commit 9d00a84fc1a8743b1da4d33a00b05f8fd7896045 Author: Leclowndu93150 <73310949+Leclowndu93150@users.noreply.github.com> Date: Sun Mar 15 18:19:13 2026 +0100 Initial mdBook porting primers site diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..a8a9514 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,50 @@ +name: Deploy Pages + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install mdBook + uses: peaceiris/actions-mdbook@v2 + with: + mdbook-version: latest + + - name: Build book + run: mdbook build + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./book + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3b2dc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +book/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..0196dbc --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Porting Primers + +This repository publishes an `mdBook` site for NeoForge porting primers covering the path from `1.21.1` to `26.1`. + +The content includes: + +- a topic-indexed landing page for jumping to the relevant primer sections +- the split upstream primer pages +- a compiled direct-port overview + +The site is deployed automatically to GitHub Pages from the `main` branch through the workflow in `.github/workflows/deploy-pages.yml`. diff --git a/book.toml b/book.toml new file mode 100644 index 0000000..9f8b361 --- /dev/null +++ b/book.toml @@ -0,0 +1,18 @@ +[book] +authors = ["Leclowndu93150", "OpenAI Codex"] +language = "en" +src = "src" +title = "1.21.1 to 26.1 Porting Primers" +description = "A topic-indexed NeoForge porting guide and upstream primer archive for migrating from 1.21.1 to 26.1." + +[output.html] +default-theme = "navy" +preferred-dark-theme = "navy" +git-repository-url = "https://github.com/Leclowndu93150/Porting-Primers" +site-url = "/Porting-Primers/" +edit-url-template = "https://github.com/Leclowndu93150/Porting-Primers/edit/main/{path}" +no-section-label = true +additional-css = [] + +[output.html.search] +enable = false diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..cde5b71 --- /dev/null +++ b/src/README.md @@ -0,0 +1,285 @@ +# 1.21.1 to 26.1 NeoForge Porting GitBook + +This GitBook is organized around two goals: + +1. Keep every upstream primer page available on its own. +2. Make the main page a topic map so you can jump straight to the primers that matter for a subsystem, workflow, or type of breakage. + +The upstream chain covered here is: + +`1.21.1 -> 1.21.2/3 -> 1.21.4 -> 1.21.5 -> 1.21.6 -> 1.21.7 -> 1.21.8 -> 1.21.9 -> 1.21.10 -> 1.21.11 -> 26.1` + +There is no separate `1.21.3` primer upstream. The `1.21.2` primer is the upstream `1.21.1 -> 1.21.2/3` step and is treated that way here. + +## How to use this GitBook + +If you already know the kind of change you are looking for, use the topic map below. + +If you want a short compiled overview first, use: + +- [Compiled Direct Port Guide](direct-port-guide.md) + +If you want the raw primers as separate pages, use: + +- [Detailed Primers](detailed-primers/README.md) + +If you want a quick view of which subsystems changed repeatedly across multiple versions, use: + +- [Repeatedly Changing Systems](repeatedly-changing-systems.md) + +## Topic Map + +### Build, mappings, names, imports, and package moves + +For Java version bumps, deobfuscation, `ResourceLocation` to `Identifier`, utility-package moves, `critereon` to `criterion`, and large import/package shuffles, go to: + +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Rename Shuffle` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Java 25 and Deobfuscation` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Minor Migrations` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Minor Migrations` + +### Datagen, packs, registries, tags, codecs, loot, validation, and recipe serialization + +For holder sets, ingredients, recipe registry changes, datapack-facing systems, tag/provider rewrites, generic encoding, loot codec registration, validation, and serializer structure changes, go to: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Pack Changes` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `The Holder Set Transition` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Instruments, the Datapack Edition` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Trial Spawner Configurations, now in Datapack Form` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Recipe Providers, the 'not actually' of Data Providers` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `The Ingredient Shift` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Recipes, now in Registry format` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Tags and Parsing` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Model Rework` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Tag Providers: Appender Rewrite` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Generic Encoding and Decoding: Replacing Direct NBT Access` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Rename Shuffle` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Loot Type Unrolling` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Validation Overhaul` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Datapack Villager Trades` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Serializer Records and Recipe Info` + +### Items, components, equipment, armor, tools, combat, dyes, and consumables + +For modern item setup, item/equipment data, armor/equippable changes, consumables, cooldowns, data components, dye behavior, and stack-template changes, go to: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Equipments and Items, Models and All` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Armor Materials, Equipment, and Model (Textures)` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Interaction Results` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `BlockEntityTypes Privatized!` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Consumables` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Registry Objcet Id, in the Properties?` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Properties Changes` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Mob Replacing Current Items` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Weapons, Tools, and Armor: Removing the Redundancies` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Data Component Getters` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `New Data Components` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Data Component Initializers` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Item Instances and Stack Templates` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Dye Component` + +### Rendering, models, shaders, particles, block models, item models, materials, atlases, and visual pipelines + +For shaders, render types, render states, client items, particles, model baking, render pipeline rewrites, block/item model systems, atlas/material changes, GUI rendering internals, and the large `26.1` rendering pass, go to: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Gui Render Types` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Shader Rewrites` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Entity Render States` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Equipments and Items, Models and All` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Armor Materials, Equipment, and Model (Textures)` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Client Items` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Particles, rendered through Render Types` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Render Pipeline Rework` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Model Rework` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `GUI Changes` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Blaze3d Changes` +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md): `Minor Migrations` +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md): `Minor Migrations` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Feature Submissions: The Movie` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The Font Glyph Pipeline` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Oh Hey, Another Rendering Rewrite` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Gizmos` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Even More Rendering Changes` + +### GUI, input, keybinds, debug screens, debug tooling, RPC tooling, and test infrastructure + +For GUI framework changes, input events, key categories, debug renderers, debug screens, tooling servers, and game tests, go to: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Gui Render Types` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `The Game Test Overhaul` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `GUI Changes` +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md): `Minor Migrations` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The Debugging Overhaul` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Debug Screens` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The JSON-RPC Management Servers` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Input Handling Consolidation` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Gizmos` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Permission Overhaul` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Java 25 and Deobfuscation` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Minor Migrations` + +### World state, saved data, game rules, timelines, clocks, players, permissions, waypoints, and other server-side systems + +For block removal flow, voxel shapes, weighted lists, tickets, saved data, server player changes, waypoints, permissions, game rules, timelines, clocks, and level/server data ownership, go to: + +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Handling the Removal of Block Entities Properly` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Voxel Shape Helpers` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Weighted List Rework` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Tickets` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Saved Data, now with Types` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Waypoints` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Server Player Changes` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): ``Level#isClientSide` now private` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Permission Overhaul` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Timeline of Environment Attributes` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Game Rule Shuffle` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): ``Level#random` field now protected` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `World Clocks and Time Markers` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Splitting the Primary Level Data into Saved Data` + +### Short releases and catch-all API churn + +If the thing you are chasing is not obviously a major subsystem rewrite, check these first: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Minor Migrations` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Minor Migrations` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Minor Migrations` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Minor Migrations` +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md): `Minor Migrations` +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md): `Minor Migrations` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Minor Migrations` +- [1.21.9 -> 1.21.10](detailed-primers/1.21.10-from-1.21.9.md): `Minor Migrations` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Minor Migrations` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Minor Migrations` + +The smallest releases in this chain are still indexed here and should not be skipped: + +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md) +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md) +- [1.21.9 -> 1.21.10](detailed-primers/1.21.10-from-1.21.9.md) + +## Complete Section Inventory By Version + +This inventory exists so the main page indexes every upstream `##` section used in this GitBook. + +### 1.21.1 -> 1.21.2/3 + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Pack Changes` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `The Holder Set Transition` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Gui Render Types` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Shader Rewrites` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Entity Render States` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Equipments and Items, Models and All` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Armor Materials, Equipment, and Model (Textures)` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Interaction Results` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Instruments, the Datapack Edition` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Trial Spawner Configurations, now in Datapack Form` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Recipe Providers, the 'not actually' of Data Providers` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `The Ingredient Shift` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `BlockEntityTypes Privatized!` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Consumables` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Registry Objcet Id, in the Properties?` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Properties Changes` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Recipes, now in Registry format` +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md): `Minor Migrations` + +### 1.21.2/3 -> 1.21.4 + +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Pack Changes` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Client Items` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Mob Replacing Current Items` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Particles, rendered through Render Types` +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md): `Minor Migrations` + +### 1.21.4 -> 1.21.5 + +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Pack Changes` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Handling the Removal of Block Entities Properly` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Voxel Shape Helpers` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Weapons, Tools, and Armor: Removing the Redundancies` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Weighted List Rework` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Tickets` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `The Game Test Overhaul` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Data Component Getters` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Tags and Parsing` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Saved Data, now with Types` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Render Pipeline Rework` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Model Rework` +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md): `Minor Migrations` + +### 1.21.5 -> 1.21.6 + +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Pack Changes` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `GUI Changes` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Waypoints` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Blaze3d Changes` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Tag Providers: Appender Rewrite` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Generic Encoding and Decoding: Replacing Direct NBT Access` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Server Player Changes` +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md): `Minor Migrations` + +### 1.21.6 -> 1.21.7 + +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md): `Pack Changes` +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md): `Minor Migrations` + +### 1.21.7 -> 1.21.8 + +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md): `Pack Changes` +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md): `Minor Migrations` + +### 1.21.8 -> 1.21.9 + +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Pack Changes` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The Debugging Overhaul` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Debug Screens` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Feature Submissions: The Movie` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The Font Glyph Pipeline` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `The JSON-RPC Management Servers` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Input Handling Consolidation` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): ``Level#isClientSide` now private` +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md): `Minor Migrations` + +### 1.21.9 -> 1.21.10 + +- [1.21.9 -> 1.21.10](detailed-primers/1.21.10-from-1.21.9.md): `Pack Changes` +- [1.21.9 -> 1.21.10](detailed-primers/1.21.10-from-1.21.9.md): `Minor Migrations` + +### 1.21.10 -> 1.21.11 + +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Pack Changes` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Rename Shuffle` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Oh Hey, Another Rendering Rewrite` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Gizmos` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Permission Overhaul` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `New Data Components` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Timeline of Environment Attributes` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `The Game Rule Shuffle` +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md): `Minor Migrations` + +### 1.21.11 -> 26.1 + +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Pack Changes` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Java 25 and Deobfuscation` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Loot Type Unrolling` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Validation Overhaul` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Datapack Villager Trades` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): ``Level#random` field now protected` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Data Component Initializers` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Item Instances and Stack Templates` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Serializer Records and Recipe Info` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Dye Component` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `World Clocks and Time Markers` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Splitting the Primary Level Data into Saved Data` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Even More Rendering Changes` +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md): `Minor Migrations` + +## Source and attribution + +The split primer pages in this GitBook are copied from the upstream primers in: + +- `ChampionAsh5357/neoforged-github`, branch `update/26.1` + +For attribution and license notes, see: + +- [Source And Attribution](source-and-attribution.md) diff --git a/src/SUMMARY.md b/src/SUMMARY.md new file mode 100644 index 0000000..dc307d0 --- /dev/null +++ b/src/SUMMARY.md @@ -0,0 +1,17 @@ +# Summary + +- [1.21.1 to 26.1 NeoForge Porting Guide](README.md) +- [Direct Port Guide](direct-port-guide.md) +- [Repeatedly Changing Systems](repeatedly-changing-systems.md) +- [Source And Attribution](source-and-attribution.md) +- [Detailed Primers](detailed-primers/README.md) +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md) +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md) +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md) +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md) +- [1.21.7 -> 1.21.8](detailed-primers/1.21.8-from-1.21.7.md) +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md) +- [1.21.9 -> 1.21.10](detailed-primers/1.21.10-from-1.21.9.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) diff --git a/src/detailed-primers/1.21.10-from-1.21.9.md b/src/detailed-primers/1.21.10-from-1.21.9.md new file mode 100644 index 0000000..fff87e8 --- /dev/null +++ b/src/detailed-primers/1.21.10-from-1.21.9.md @@ -0,0 +1,27 @@ +# Minecraft 1.21.9 -> 1.21.10 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.9 to 1.21.10. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @melanx for a typo + +## 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](https://misode.github.io/versions/?id=1.21.10&tab=changelog). + +## 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. + +### List of Additions + +- `net.minecraft.world.entity.decoration.HangingEntity#getPopBox` - Returns the bounding box indicating where the entity will pop off if colliding. + +### List of Changes + +`net.minecraft.world.level.block.state.BlockBehaviour#entityInside` now takes in a `boolean` indicating whether the entity is intersecting or inside the block diff --git a/src/detailed-primers/1.21.11-from-1.21.10.md b/src/detailed-primers/1.21.11-from-1.21.10.md new file mode 100644 index 0000000..848d233 --- /dev/null +++ b/src/detailed-primers/1.21.11-from-1.21.10.md @@ -0,0 +1,3173 @@ +# Minecraft 1.21.10 -> 1.21.11 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.10 to 1.21.11. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @xfacthd for some educated guesses regarding the usage annotations +- @dinnerbone for pointing out gizmos can also be submitted on the server in singleplayer worlds +- @thatgravyboat for pointing out the change in parameter orders for `Mth#clampedLerp` + +## 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](https://misode.github.io/versions/?id=1.22&tab=changelog). + +## The Rename Shuffle + +Many core classes, method, and parameters have been shuffled around and renamed while still retaining their individual function. The following is a list of the most important changes + +### `ResourceLocation` to `Identifier` + +All references to `ResourceLocation`, whether in method names, parameters, or other classes, have been replaced with `Identifier`. + +### The `util` Package + +Most utility classes have been moved to `net.minecraft.util`. These will need to be reimported. + +### `critereon` to `criterion` + +`net.minecraft.advancements.critereon` has been renamed to `net.minecraft.advancements.criterion`. These will need to be reimported. + +### Entity and Object Subpackages + +Both `net.minecraft.client.model` and `net.minecraft.world.entity` have been reorganized into additional subpackages based on the type of backing object. These will need to be reimported. + +- `net.minecraft` + - `BlockUtil` -> `.util.BlockUtil` + - `FileUtil` -> `.util.FileUtil` + - `ResourceLocationException` -> `IdentifierException` + - `Util` -> `.util.Util` +- `net.minecraft.advancements.critereon` -> `.advancements.criterion` +- `net.minecraft.client.gui.screens.inventory.JigsawBlockEditScreen#isValidResourceLocation` -> `isValidIdentifier` +- `net.minecraft.client.model` + - `AbstractBoatModel` -> `.object.boat.AbstractBoatModel` + - `AbstractEquineModel` -> `.animal.equine.AbstractEquineModel` + - `AbstractPiglinModel` -> `.monster.piglin.AbstractPiglinModel` + - `AbstractZombieModel` -> `.monster.zombie.AbstractZombieModel` + - `AllayModel` -> `.animal.allay.AllayModel` + - `ArmadilloModel` -> `.animal.armadillo.ArmadilloModel` + - `ArmorStandArmorModel` -> `.object.armorstand.ArmorStandArmorModel` + - `ArmorStandModel` -> `.object.armorstand.ArmorStandModel` + - `ArrowModel` -> `.object.projectile.ArrowModel` + - `AxolotlModel` -> `.animal.axolotl.AxolotlModel` + - `BannerFlagModel` -> `.object.banner.BannerFlagModel` + - `BannerModel` -> `.object.banner.BannerModel` + - `BatModel` -> `.ambient.BatModel` + - `BeeModel` -> `.animal.bee.BeeModel` + - `BeeStingerModel` -> `.animal.bee.BeeStingerModel` + - `BellModel` -> `.object.bell.BellModel` + - `BlazeModel` -> `.monster.blaze.BlazeModel` + - `BoatModel` -> `.object.boat.BoatModel` + - `BoggedModel` -> `.monster.skeleton.BoggedModel` + - `BookModel` -> `.object.book.BookModel` + - `BreezeModel` -> `.monster.breeze.BreezeModel` + - `CamelModel` -> `.animal.camel.CamelModel` + - `CamelSaddleModel` -> `.animal.camel.CamelSaddleModel` + - `CatModel` -> `.animal.feline.CatModel` + - `ChestModel` -> `.object.chest.ChestModel` + - `ChickenModel` -> `.animal.chicken.ChickenModel` + - `CodModel` -> `.animal.fish.CodModel` + - `ColdChickenModel` -> `.animal.chicken.ColdChickenModel` + - `ColdCowModel` -> `.animal.cow.ColdCowModel` + - `ColdPigModel` -> `.animal.pig.ColdPigModel` + - `CopperGolemModel` -> `.animal.golem.CopperGolemModel` + - `CopperGolemStatueModel` -> `.object.statue.CopperGolemStatueModel` + - `CowModel` -> `.animal.cow.CowModel` + - `CreakingModel` -> `.monster.creaking.CreakingModel` + - `CreeperModel` -> `.monster.creeper.CreeperModel` + - `DolphinModel` -> `.animal.dolphin.DolphinModel` + - `DonkeyModel` -> `.animal.equine.DonkeyModel` + - `DrownedModel` -> `.monster.zombie.DrownedModel` + - `ElytraModel` -> `.object.equipment.ElytraModel` + - `EndCrystalModel` -> `.object.crystal.EndCrystalModel` + - `EndermanModel` -> `.monster.enderman.EndermanModel` + - `EndermiteModel` -> `.monster.endermite.EndermiteModel` + - `EquineSaddleModel` -> `.animal.equine.EquineSaddleModel` + - `EvokerFangsModel` -> `.effects.EvokerFangsModel` + - `FelineModel` -> `.animal.feline.FelineModel` + - `FoxModel` -> `.animal.fox.FoxModel` + - `FrogModel` -> `.animal.frog.FrogModel` + - `GhastModel` -> `.monster.ghast.GhastModel` + - `GiantZombieModel` -> `.monster.zombie.GiantZombieModel` + - `GoatModel` -> `.animal.goat.GoatModel` + - `GuardianModel` -> `.monster.guardian.GuardianModel` + - `GuardianParticleModel` -> `.monster.guardian.GuardianParticleModel` + - `HappyGhastHarnessModel` -> `.animal.ghast.HappyGhastHarnessModel` + - `HappyGhastModel` -> `.animal.ghast.HappyGhastModel` + - `HoglinModel` -> `.monster.hoglin.HoglinModel` + - `HorseModel` -> `.animal.equine.HorseModel` + - `IllagerModel` -> `.monster.illager.IllagerModel` + - `IronGolemModel` -> `.animal.golem.IronGolemModel` + - `LavaSlimeModel` -> `.monster.slime.MagmaCubeModel` + - `LeashKnotModel` -> `.object.leash.LeashKnotModel` + - `LlamaModel` -> `.animal.llama.LlamaModel` + - `LlamaSpitModel` -> `.animal.llama.LlamaSpitModel` + - `MinecartModel` -> `.object.cart.MinecartModel` + - `OcelotModel` -> `.animal.feline.OcelotModel` + - `PandaModel` -> `.animal.panda.PandaModel` + - `ParrotModel` -> `.animal.parrot.ParrotModel` + - `PhantomModel` -> `.monster.phantom.PhantomModel` + - `PiglinHeadModel` -> `.object.skull.PiglinHeadModel` + - `PiglinModel` -> `.monster.piglin.PiglinModel` + - `PigModel` -> `.animal.pig.PigModel` + - `PlayerCapeModel` -> `.player.PlayerCapeModel` + - `PlayerEarsModel` -> `.player.PlayerEarsModel` + - `PlayerModel` -> `.player.PlayerModel` + - `PolarBearModel` -> `.animal.polarbear.PolarBearModel` + - `PufferfishBigModel` -> `.animal.fish.PufferfishBigModel` + - `PufferfishMidModel` -> `.animal.fish.PufferfishMidModel` + - `PufferfishSmallModel` -> `.animal.fish.PufferfishSmallModel` + - `RabbitModel` -> `.animal.rabbit.RabbitModel` + - `RaftModel` -> `.object.boat.RaftModel` + - `RavagerModel` -> `.monster.ravager.RavagerModel` + - `SalmonModel` -> `.animal.fish.SalmonModel` + - `SheepFurModel` -> `.animal.sheep.SheepFurModel` + - `SheepModel` -> `.animal.sheep.SheepModel` + - `ShieldModel` -> `.object.equipment.ShieldModel` + - `ShulkerBulletModel` -> `.object.projectile.ShulkerBulletModel` + - `ShulkerModel` -> `.monster.shulker.ShulkerModel` + - `SilverfishModel` -> `.monster.silverfish.SilverfishModel` + - `SkeletonModel` -> `.monster.skeleton.SkeletonModel` + - `SkullModel` -> `.object.skull.SkullModel` + - `SkullModelBase` -> `.object.skull.SkullModelBase` + - `SlimeModel` -> `.monster.slime.SlimeModel` + - `SnifferModel` -> `.animal.sniffer.SnifferModel` + - `SnowGolemModel` -> `.animal.golem.SnowGolemModel` + - `SpiderModel` -> `.monster.spider.SpiderModel` + - `SpinAttackEffectModel` -> `.effects.SpinAttackEffectModel` + - `SquidModel` -> `.animal.squid.SquidModel` + - `StriderModel` -> `.monster.strider.StriderModel` + - `TadpoleModel` -> `.animal.frog.TadpoleModel` + - `TridentModel` -> `.object.projectile.TridentModel` + - `TropicalFishModelA` -> `.animal.fish.TropicalFishSmallModel` + - `TropicalFishModelB` -> `.animal.fish.TropicalFishLargeModel` + - `TurtleModel` -> `.animal.turtle.TurtleModel` + - `VexModel` -> `.monster.vex.VexModel` + - `VillagerModel` -> `.npc.VillagerModel` + - `WardenModel` -> `.monster.warden.WardenModel` + - `WarmCowModel` -> `.animal.cow.WarmCowModel` + - `WindChargeModel` -> `.object.projectile.WindChargeModel` + - `WitchModel` -> `.monster.witch.WitchModel` + - `WitherBossModel` -> `.monster.wither.WitherBossModel` + - `WolfModel` -> `.animal.wolf.WolfModel` + - `ZombieModel` -> `.monster.zombie.ZombieModel` + - `ZombieVillagerModel` -> `.monster.zombie.ZombieVillagerModel` + - `ZombifiedPiglinModel` -> `.monster.piglin.ZombifiedPiglinModel` +- `net.minecraft.client.model.dragon` + - `DragonHeadModel` -> `.model.object.skull.DragonHeadModel` + - `EnderDragonModel` -> `.model.monster.dragon.EnderDragonModel` +- `net.minecraft.client.resources.sounds` + - `AbstractSoundInstance#location` -> `identifier` + - `SoundInstance#getLocation` -> `getIdentifier` +- `net.minecraft.client.searchtree` + - `IdSearchTree` + - `resourceLocationSearchTree` -> `identifierSearchTree` + - `searchResourceLocation` -> `searchIdentifier` + - `ResourceLocationSearchTree` -> `IdentifierSearchTree` +- `net.minecraft.commands.arguments.ResourceLocationArgument` -> `IdentifierArgument` +- `net.minecraft.network.FriendlyByteBuf#readResourceLocation`, `writeResourceLocation` -> `readIdentifier`, `writeIdentifier` +- `net.minecraft.resources` + - `ResourceKey#location` -> `identifier` + - `ResourceLocation` -> `Identifier` +- `net.minecraft.util.ResourceLocationPattern` -> `IdentifierPattern` +- `net.minecraft.util.parsing.packrat.commands.ResourceLocationParseRule` -> `IdentifierParseRule` +- `net.minecraft.world.entity.GlowSquid` -> `.animal.squid.GlowSquid` +- `net.minecraft.world.entity.animal` + - `AbstractCow` -> `.cow.AbstractCow` + - `AbstractFish` -> `.fish.AbstractFish` + - `AbstractGolem` -> `.golem.AbstractGolem` + - `AbstractSchoolingFish` -> `.fish.AbstractSchoolingFish` + - `Bee` -> `.bee.Bee` + - `Cat` -> `.feline.Cat` + - `CatVariant` -> `.feline.CatVariant` + - `CatVariants` -> `.feline.CatVariants` + - `Chicken` -> `.chicken.Chicken` + - `ChickenVariant` -> `.chicken.ChickenVariant` + - `ChickenVariants` -> `.chicken.ChickenVariants` + - `Cod` -> `.fish.Cod` + - `Cow` -> `.cow.Cow` + - `CowVariant` -> `.cow.CowVariant` + - `CowVariants` -> `.cow.CowVariants` + - `Dolphin` -> `.dolphin.Dolphin` + - `Fox` -> `.fox.Fox` + - `HappyGhast` -> `.happyghast.HappyGhast` + - `HappyGhastAi` -> `.happyghast.HappyGhastAi` + - `IronGolem` -> `.golem.IronGolem` + - `MushroomCow` -> `.cow.MushroomCow` + - `Ocelot` -> `.feline.Ocelot` + - `Panda` -> `.panda.Panda` + - `Parrot` -> `.parrot.Parrot` + - `Pig` -> `.pig.Pig` + - `PigVariant` -> `.pig.PigVariant` + - `PigVariants` -> `.pig.PigVariants` + - `PolarBear` -> `.polarbear.PolarBear` + - `Pufferfish` -> `.fish.Pufferfish` + - `Rabbit` -> `.rabbit.Rabbit` + - `Salmon` -> `.fish.Salmon` + - `ShoulderRidingEntity` -> `.parrot.ShoulderRidingEntity` + - `SnowGolem` -> `.golem.SnowGolem` + - `Squid` -> `.squid.Squid` + - `TropicalFish` -> `.fish.TropicalFish` + - `Turtle` -> `.turtle.Turtle` + - `WaterAnimal` -> `.fish.WaterAnimal` +- `net.minecraft.world.entity.animal.coppergolem.*` -> `.animal.golem.*` +- `net.minecraft.world.entity.animal.horse.*` -> `.animal.equine.*` +- `net.minecraft.world.entity.boss.EnderDragonPart` -> `.enderdragon.EnderDragonPart` +- `net.minecraft.world.entity.decoration` + - `Painting` -> `.painting.Painting` + - `PaintingVariant` -> `.painting.PaintingVariant` + - `PaintingVariants` -> `.painting.PaintingVariants` +- `net.minecraft.world.entity.monster` + - `AbstractIllager` -> `.illager.AbstractIllager` + - `AbstractSkeleton` -> `.skeleton.AbstractSkeleton` + - `Bogged` -> `.skeleton.Bogged` + - `CaveSpider` -> `.spider.CaveSpider` + - `Drowned` -> `.zombie.Drowned` + - `Evoker` -> `.illager.Evoker` + - `Husk` -> `.zombie.Husk` + - `Illusioner` -> `.illager.Illusioner` + - `Parched` -> `.skeleton.Parched` + - `Pillager` -> `.illager.Pillager` + - `Skeleton` -> `.skeleton.Skeleton` + - `SpellcasterIllager` -> `.illager.SpellcasterIllager` + - `Spider` -> `.spider.Spider` + - `Stray` -> `.skeleton.Stray` + - `Vindicator` -> `.illager.Vindicator` + - `WitherSkeleton` -> `.skeleton.WitherSkeleton` + - `Zombie` -> `.zombie.Zombie` + - `ZombieVillager` -> `.zombie.ZombieVillager` + - `ZombifiedPiglin` -> `.zombie.ZombifiedPiglin` +- `net.minecraft.world.entity.npc` + - `AbstractVillager` -> `.villager.AbstractVillager` + - `Villager` -> `.villager.Villager` + - `VillagerData` -> `.villager.VillagerData` + - `VillagerDataHolder` -> `.villager.VillagerDataHolder` + - `VillagerProfession` -> `.villager.VillagerProfession` + - `VillagerTrades` -> `.villager.VillagerTrades` + - `VillagerType` -> `.villager.VillagerType` + - `WanderingTrader` -> `.wanderingtrader.WanderingTrader` + - `WanderingTraderSpawner` -> `.wanderingtrader.WanderingTraderSpawner` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow` -> `.arrow.AbstractArrow` + - `AbstractHurtingProjectile` -> `.hurtingprojectile.AbstractHurtingProjectile` + - `AbstractThrownPotion` -> `.throwableitemprojectile.AbstractThrownPotion` + - `Arrow` -> `.arrow.Arrow` + - `DragonFireball` -> `.hurtingprojectile.DragonFireball` + - `Fireball` -> `.hurtingprojectile.Fireball` + - `LargeFireball` -> `.hurtingprojectile.LargeFireball` + - `SmallFireball` -> `.hurtingprojectile.SmallFireball` + - `Snowball` -> `.throwableitemprojectile.Snowball` + - `SpectralArrow` -> `.arrow.SpectralArrow` + - `ThrowableItemProjectile` -> `.throwableitemprojectile.ThrowableItemProjectile` + - `ThrownEgg` -> `.throwableitemprojectile.ThrownEgg` + - `ThrownEnderpearl` -> `.throwableitemprojectile.ThrownEnderpearl` + - `ThrownExperienceBottle` -> `.throwableitemprojectile.ThrownExperienceBottle` + - `ThrownLingeringPotion` -> `.throwableitemprojectile.ThrownLingeringPotion` + - `ThrownSplashPotion` -> `.throwableitemprojectile.ThrownSplashPotion` + - `ThrownTrident` -> `.arrow.ThrownTrident` + - `WitherSkull` -> `.hurtingprojectile.WitherSkull` +- `net.minecraft.world.entity.projectile.windcharge.*` -> `.projectile.hurtingprojectile.windcharge.*` +- `net.minecraft.world.entity.vehicle` + - `AbstractBoat` -> `.boat.AbstractBoat` + - `AbstractChestBoat` -> `.boat.AbstractChestBoat` + - `AbstractMinecart` -> `.minecart.AbstractMinecart` + - `AbstractMinecartContainer` -> `.minecart.AbstractMinecartContainer` + - `Boat` -> `.boat.Boat` + - `ChestBoat` -> `.boat.ChestBoat` + - `ChestRaft` -> `.boat.ChestRaft` + - `Minecart` -> `.minecart.Minecart` + - `MinecartBehavior` -> `.minecart.MinecartBehavior` + - `MinecartChest` -> `.minecart.MinecartChest` + - `MinecartCommandBlock` -> `.minecart.MinecartCommandBlock` + - `MinecartFurnace` -> `.minecart.MinecartFurnace` + - `MinecartHopper` -> `.minecart.MinecartHopper` + - `MinecartSpawner` -> `.minecart.MinecartSpawner` + - `MinecartTNT` -> `.minecart.MinecartTNT` + - `NewMinecartBehavior` -> `.minecart.NewMinecartBehavior` + - `OldMinecartBehavior` -> `.minecart.OldMinecartBehavior` + - `Raft` -> `.boat.Raft` +- `net.minecraft.world.level.gamerules.GameRule#getResourceLocation` -> `getIdentifier` + +## Oh Hey, Another Rendering Rewrite + +More of the rendering pipeline has been rewritten, with the majority focused on samplers, `RenderType` creation, and mipmaps. + +### The Separation of Samplers + +Blaze3d has separated setting the `AddressMode`s and `FilterMode`s when reading texture data into `GpuSampler`. As the name implies, a `GpuSampler` defines how to sample data from a buffer, such as a texture. `GpuSampler` contains four methods: `getAddressModeU` / `getAddressModeV` for determining how the sampler should behave when reading the UV positions (either repeat or clamp), `getMinFilter` / `getMagFilter` for determining how to minify or magnify the texture respectively (either nearest neighbor or linear), `getMaxAnisotropy` for the largest anisotropic filtering level that can be used, and `getMaxLod` for the maximum level-of-detail on a texture. + +Samplers can be created via `GpuDevice#createSampler`, but that is not necessary unless you want to specify a different anisotropic filtering level greater than `1`, or a maximum level-of-detail that is not `0` or `1000`. If the default, as there are only 32 possible combinations, vanilla creates all `GpuSampler`s and stores them in a cache, accessible via `RenderSystem#getSamplerCache`, followed by `SamplerCache#getSampler`: + +```java +// Raw call +GpuSampler sampler = RenderSystem.getDevice().createSampler( + // U address mode + AddressMode.CLAMP_TO_EDGE, + // V address mode + AddressMode.CLAMP_TO_EDGE, + // Minification filter + FilterMode.LINEAR, + // Magnification filter + FilterMode.NEAREST, + // The maximum anisotropic filtering level + // Vanilla uses either 1, 2, 4, or 8 for level rendering + 4f, + // The maximum level of detail for a texture + // Vanilla either uses an 0 for the default, + // or an empty optional for moving objects and + // uploading to an atlas. + OptionalDouble.of(0.0) +); + +// Sampler cache method +GpuSampler sampler = RenderSystem.getSamplerCache().getSampler( + // U address mode + AddressMode.CLAMP_TO_EDGE, + // V address mode + AddressMode.CLAMP_TO_EDGE, + // Minification filter + FilterMode.LINEAR, + // Magnification filter + FilterMode.NEAREST, + // Whether to use 1000 or 0 for the maximum level-of-detail + true +); +``` + +To make user of the sampler for a texture, when binding the texture in a render pass (via `RenderPass#bindTexture`), you must now specify the sampler to use in addition to the texture view: + +```java +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(...)) { + // Set other parameters + pass.bindTexture( + // The name of the sampler2D uniform, usually in the fragment shader + "Sampler0", + // The texture to sample + ..., + // The sampler to use + sampler + ); + + // Draw buffer +} +``` + +Setting up the post processor has not changed from the user perspective as only clamp to edge address modes may be selected. + +### The `RenderType` Shuffle + +Creating a `RenderType` has been reworked to some degree. While most of the features from the previous implementation still exist, they have been changed to match the new rendering system where direct OpenGL is abstracted away and only accessed through their defined pipelines and `RenderSystem`. + +#### Existing Types + +Existing types have been moved from `RenderType` to `RenderTypes` (e.g., `RenderType#solid` -> `RenderTypes#solid`). + +#### Custom Types + +Originally, to create a `RenderType`, you would construct a `$CompositeState` using `RenderStateShard`s. Each `RenderStateShard` would define how the pass should be setup and teardown when building some mesh, whether that was setting textures, the render target, model transforms, etc. Then, the `$CompositeState` would be built for use in whatever rendering application was needed. + +The new system splits the render definition in two: the `RenderSetup`, and our `RenderType`. The `RenderSetup`, as the name implies, sets up the renderer to be used when drawing to a texture. Teardown is completely removed as it is either handled directly when drawing the `RenderType` or uses newly constructed states that can just be thrown away. `RenderType`, on the other hand, is simply a named `RenderSetup`. It only handles drawing the mesh data and making some fields of the setup public for use in other buffer implementations. Multiple types can have the same `RenderSetup` as a number of existing types dynamically populate the texture used by the sampler and/or the outline of the object. + +A `RenderSetup` can be created through its builder via `RenderSetup#Builder`, supply the `RenderPipeline` to use. Once the builder properties are set, the actual setup can be created via `RenderSetup$RenderSetupBuilder#createRenderSetup`: + +```java +public static final RenderSetup EXAMPLE_SETUP = RenderSetup.builder( + // The pipeline to use. + // This can affect what settings are allowed from the setup. + RenderPipelines.ITEM_ENTITY_TRANSLUCENT_CULL +) + // Specifies the texture to bind to the provided sampler. + // The sampler must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + // The texture is represented as an absolute location. + .withTexture( + // 'Sampler0' is defined by the pipeline. + "Sampler0", + // Points to 'assets/minecraft/entity/wolf/wolf_armor_crackiness_low.png'. + Identifier.withDefaultNamespace("textures/entity/wolf/wolf_armor_crackiness_low.png"), + // An optional supplied `GpuSampler` to sample the texture with. + // The returned value with be cached after first resolution. + () -> RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST) + ) + // When set, allows the pipeline to use the light texture. + // 'Sampler2' must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + .useLightmap() + // When set, allows the pipeline to use the overlay texture. + // 'Sampler1' must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + .useOverlay() + // When set, uses `RenderTypes#crumbling` to overlay the block destroy stages + // based on the crumbling progress for an entity model. + // This is only implemented in `ModelFeatureRenderer`. + .affectsCrumbling() + // When set, sorts the quads based on the set `ProjectionType` in + // `RenderSystem#getProjectionType`. + // This is only implemented when getting the buffers from `MultiBufferSource$BufferSource`. + .sortOnUpload() + // Sets the initial capacity of the used buffer. + // This is only used when constructing the initial buffers in `RenderBuffers` + // All custom applications of sources already have some defined buffer with the determined size. + .bufferSize(786432) + // An object-wrapped consumer that transforms the model view matrix. + // Vanilla implementations exist in `LayeringTransform`, applying + // the transformation through the projection type: + // - `NO_LAYERING`: Do nothing. + // - `VIEW_OFFSET_Z_LAYERING`: Offsets the Z by 1 based on its `ProjectionType` + // - `VIEW_OFFSET_Z_LAYERING_FORWARD`: Offsets the Z by -11 based on its `ProjectionType` + .setLayeringTransform( + // We can also construct a new transform + new LayeringTransform( + // The name of the transform + "examplemod:example_layer", + // The transform should not push or pop to the stack + // Only translate, scale, or rotate + stack -> stack.translate(0f, 0.1f, 0f) + ) + ) + // Sets the output target that this setup should write to, + // unless overridden by the `RenderSystem#output*Override` textures. + // This is typically the main target, though it can be other vanilla + // targets or a custom one if you plan to handle it. + .setOutputTarget(OutputTarget.MAIN_TARGET) + // An object-wrapped supplier that provides the texture matrix. + // This is typically used to modify the texture UV coordinates + // in the vertex shader before sampling in the fragment shader. + // Vanilla only uses this for the glint effect and breeze/energy: + // - `DEFAULT_TEXTURING`: Do nothing. + // - `GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 8. + // - `ENTITY_GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 0.5. + // - `ARMOR_ENTITY_GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 0.16. + // - `$OffsetTextureTransform`: Translates the texture by the provided XY coordinates. + .setTextureTransform( + // We can also construct a new transform + new TextureTransform( + // The name of the transform + "examplemod:example_texture", + // The transform to apply to the texture + () -> new Matrix4f().translation(0f, 1f, 0f).scale(1.5f) + ) + ) + // Sets how an outline of the mesh should be handled: + // - `NONE`: Do nothing. + // - `IS_OUTLINE`: This is an outline and should write to the outline buffer source. + // - `AFFECTS_OUTLINE`: This defines the shape of the outline and should use `RenderTypes#OUTLINE` to draw it. + // Checked when writing to the outline buffer source or, + // if the outline color for a feature is not 0 + .setOutline(RenderSetup.OutlineProperty.AFFECTS_OUTLINE) + // Builds the setup for use in a render type. + .createRenderSetup(); +``` + +Then, the `RenderType` can be created via `create`. + +```java +public static final RenderType EXAMPLE_TYPE = RenderType.create( + // The name of the type for debugging + "examplemod:example_type", + // The render setup to use + EXAMPLE_SETUP +); +``` + +`MeshData` can be written to the output target using `RenderType#draw`. + +### Mipmap Strategy Metadata + +A texture's `mcmeta` can now specify the `mipmap_strategy` to use in the `textures` section. There are four available strategies, with `auto` defaulting to `mean` if there is no transparency, an `cutout` when there is transparency. + +| Strategy | Description | +|:---------------:|:-------------------------------------------------------------------------------------------------------------------------------| +| `mean` | The default that averages the color between four pixels for the current mipmap level. | +| `cutout` | `mean`, except that all levels are generated from the original texture, with alpha snapped to 0 or 1 using a threshold of 0.2. | +| `strict_cutout` | `cutout`, except that it sets the alpha snaps using a threshold of `0.6`. | +| `dark_cutout` | `mean`, except that the surrounding pixels are only included in the average if their alpha is not `0`. | + +```json5 +// In `assets/examplemod/textures/block/example/example_block.png.mcmeta +{ + "texture": { + // Uses the chosen strategy + "mipmap_strategy": "cutout", + // Determines how much the cutoff should be biased + // when determining whether a pixel is either fully + // opaque or transparent. + // Larger numbers means higher alpha cutoff while + // lower values use a lower alpha cutoff. + "alpha_cutoff_bias": 0.2 + } +} +``` + +### Block and Terrain Split + +`RenderPipeline`s that were used by both a standalone block and the terrain has been split into separate pipelines: one with prefix `_BLOCK` and `_TERRAIN`, respectively. This includes the solid, cutout, translucent, and tripwire pipelines. No block variant exists for the translucent pipeline. + +### Item Atlases + +The block atlas no longer contains textures specifically for items. Those have been moved to their own atlas named `minecraft:items`, with the id stored at `AtlasIds#ITEMS`. + +If a given `Material` can use both block and item textures, then it should be supplied with the `ModelManager#BLOCK_OR_ITEM` special case. + +- `com.mojang.blaze3d.buffers` + - `GpuBuffer`, `size` now uses a `long` for the size + - `slice` now uses `long`s for the length and offset + - `GpuBufferSlice` now uses `long`s for the length and offset +- `com.mojang.blaze3d.opengl` + - `BufferStorage` + - `createBuffer` now uses in a `long` for the size + - `mapBuffer` now uses `long`s for the length and offset + - `DirectStateAccess` + - `bufferSubData` now uses in a `long` for the offset + - `mapBufferRange`, `flushMappedBufferRange`, `copyBufferSubData` now use `long`s for the length and offset + - `GlBuffer` now uses a `long` for the size + - `GlDevice` now takes in a `ShaderSource` instead of a `BiFunction` + - `getOrCompileShader` now takes in a `ShaderSource` instead of a `BiFunction` + - `GlRenderPass` + - `samplers` now is a hash map of strings to `GlRenderPass$TextureViewAndSampler`s + - `$TextureViewAndSampler` - A record that defines a sampler with its sampled texture. + - `GlSampler` - The OpenGL implementation of a gpu sampler. + - `GlStateManager` + - `_glBufferSubData` now uses in a `long` for the offset + - `_glMapBufferRange` now uses `long`s for the length and offset + - `GlTexture#modesDirty`, `flushModeChanges` are removed + - `GlTextureView#getFbo` - Gets the framebuffer object of a texture, using the cache if present. +- `com.mojang.blaze3d.pipeline.RenderTarget#filterMode`, `setFilterMode` are removed +- `com.mojang.blaze3d.platform.TextureUtil` + - `solidify` - Modifies the texture by packing and unpacking the pixels to better help with non-darkened interiors within mipmaps. + - `fillEmptyAreasWithDarkColor` - Sets empty pixels to an empty pixel whose RGB value is the darkest color in the image. +- `com.mojang.blaze3d.shaders.ShaderSource` - A functional interface that gets the shader source from its id and type as a string. +- `com.mojang.blaze3d.systems` + - `CommandEncoder#copyTextureToBuffer` now uses a `long` for the offset + - `GpuDevice` + - `createSampler` - Creates a sampler for some source to destination with the desired address and filter modes. + - `precompilePipeline` now takes in a `ShaderSource` instead of a `BiFunction` + - `getMaxSupportedAnisotropy` - The maximum anisotropic filtering level supported by the hardware. + - `createBuffer` now uses in a `long` for the size + - `RenderPass#bindTexture` now takes in a `GpuSampler` + - `RenderSystem`now uses in a `long` for the size + - `samplerCache` - Returns a cache of samples containing all possible combinations. + - `TEXTURE_COUNT` is removed + - `setupOverlayColor`, `teardownOverlayColor` are removed + - `setShaderTexture`, `getShaderTexture` are removed + - `setTextureMatrix`, `resetTextureMatrix`, `getTextureMatrix` are removed + - `lineWidth` -> `VertexConsumer#setLineWidth` + - `getShaderLineWidth` -> `Window#getAppropriateLineWidth` + - `initRenderer` now takes in a `ShaderSource` instead of a `BiFunction` + - `SamplerCache` - A cache of all possible samplers that may be used by the renderer. +- `com.mojang.blaze3d.textures` + - `GpuSampler` - A buffer sampler with the specified UV address modes and minification and magnification filters. + - `GpuTexture` + - `addressModeU` -> `GpuSampler#getAddressModeU` + - `addressModeV` -> `GpuSampler#getAddressModeV` + - `minFilter` -> `GpuSampler#getMinFilter` + - `magFilter` -> `GpuSampler#getMagFilter` + - `setAddressMode`, `setTextureFilter` have been replaced by `SamplerCache#getSampler`, not one-to-one + - `useMipmaps`, `setUseMipmaps` are removed +- `net.minecraft.client` + - `Options#textureFiltering` - The chosen texture sampling method when viewed at an angle or from a distance. + - `TextureFilteringMethod` - The sampling method when viewing a texture at an angle or from a distance. +- `net.minecraft.client.gui.render.TextureSetup` now takes in the `GpuSampler`s for each of the textures + - This also includes the static constructors +- `net.minecraft.client.particle.SingleQuadParticle$Layer#ITEMS` - A layer for particles with item textures. +- `net.minecraft.client.renderer` + - `FaceInfo` + - `$Constants` -> `$Extent` + - `$VertexInfo` is now a record + - `ItemBlockRenderTypes#getRenderType(ItemStack)` + - `LightTexture#turnOffLightLayer`, `turnOnLightLayer` are removed + - `LevelRenderer#resetSampler` - Resets the chunk layer sampler. + - `PostPass` + - `$Input#bilinear` - Whether to use a bilinear filter. + - `$TextureInput` now takes in a `boolean` representing whether to use a bilinear filter + - `RenderPipelines` + - `SOLID` -> `SOLID_BLOCK`, `SOLID_TERRAIN` + - `CUTOUT` -> `CUTOUT_BLOCK`, `CUTOUT_TERRAIN` + - `CUTOUT_MIPPED` is removed + - `TRANSLUCENT` -> `TRANSLUCENT_TERRAIN` + - `TRIPWIRE` -> `TRIPWIRE_BLOCK`, `TRIPWIRE_TERRAIN` + - `ANIMATE_SPRITE_SNIPPET`, `ANIMATE_SPRITE_BLIT`, `ANIMATE_SPRITE_INTERPOLATION` - Pipelines for animated sprites. + - `RenderStateShard` has been replaced with `RenderSetup`, not one-to-one + - `$LightmapStateShard` -> `RenderSetup#useLightmap` + - `$OverlayStateShard` -> `RenderSetup#useOverlay` + - `$MultiTextureStateShard`, `$TextureStateShard` -> `RenderSetup#textures` + - `$LayeringStateShard` -> `RenderSetup#layeringTransform`, `LayeringTransform` + - `$LineStateShard` -> `VertexConsumer#setLineWidth` + - `$OutputStateShard` -> `RenderSetup#outputTarget`, `OutputTarget` + - `$TexturingStateShard`, `$OffsetTexturingStateShard` -> `RenderSetup#textureTransform`, `TextureTransform` + - `RenderType` has been split into two separate concepts, not one-to-one + - All of the stored `RenderType`s have been moved to `RenderTypes` + - The actual class usage has moved to `.rendertype.RenderType`, where it does the work of `$CompositeRenderType` + - `Sheets#translucentBlockItemSheet` - A render type for translucent block items. +- `net.minecraft.client.renderer.block` + - `BlockRenderDispatcher` no longer takes in the supplied `SpecialBlockModelRenderer` + - `LiquidBlockRenderer` now takes in a `MaterialSet` + - `setupSprites` has been moved into the `LiquidBlockRenderer` constructor +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` + - `vertices` -> `position*`, `packedUV*`, not one-to-one + - `position` - Gets the position vector given the index. + - `packedUV` - Gets the packed UV given the index. + - `BlockElementRotation` now takes in a `Vector3fc` for the origin and a `Matrix4fc` transform + - The constructor also takes in a `$RotationValue` instead of a `Direction$Axis` and angle `float` + - `$EulerXYZRotation` - A XYZ rotation in degrees. + - `$RotationValue` - An interface that defines the rotation transformation. + - `$SingleAxisRotation` - A rotation in degrees around a single axis. + - `FaceBakery` + - `VERTEX_COUNT` -> `BakedQuad#VERTEX_COUNT` + - `VERTEX_INT_SIZE`, `COLOR_INDEX`, `UV_INDEX` are removed + - `bakeQuad` now takes in a `ModelBaker$PartCache` + - `extractPositions` is removed + - `SimpleModelWrapper#bake` now returns a `BlockModelPart` + - `SimpleUnbakedGeometry#bake` now takes in a `ModelBaker` instead of a `SpriteGetter` + - `TextureSlots$parseTextureMap` no longer takes in an `Identifier` + - `Variant` + - `withZRot` - Rotates the model state around the Z axis. + - `$SimpleModelState` now takes in a Z `Quadrant` + - `withZ` - Sets the Z quadrant of the model state. + - `VariantMutator#Z_ROT` - Rotates a model around the Z axis. +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` no longer takes in whether to use mipmaps + - `CUTOUT_MIPPED` is removed + - `texture` is removed + - `ChunkSectionsToRender` now takes in the `GpuTextureView` + - `dynamicTransforms` -> `chunkSectionInfos` + - `renderGroup` now takes in the `GpuSampler` +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` constructor is now package-private + - `computeExtents` now returns an array of `Vector3fc`s + - `ItemStackRenderState$LayerRenderState` + - `NO_EXTENTS_SUPPLIER` is now a supplied array of `Vector3fc`s + - `setExtents` now takes in a supplied array of `Vector3fc`s +- `net.minecraft.client.renderer.rendertype.RenderTypes` + - `MOVING_BLOCK_SAMPLER` - A sampler for blocks that are in motion. + - `solid` -> `solidMovingBlock` + - `cutout` -> `cutoutMovingBlock` + - `tripwire` -> `tripwireMovingBlock` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture#setUseMipmaps` is removed + - `MipmapGenerator#generateMipLevels` now takes in the name of the texture, a `MipmapStrategy` to determine how a specific texture should be mip mapped, and a `float` for the alpha cutoff bias + - `MipmapStrategy` - A enum defines the strategies used when constructing a mipmap for a texture. + - `OverlayTexture#setupOverlayColor`, `teardownOverlayColor` replaced by `getTextureView`, not one-to-one + - `SpriteContents` now takes in an optional `TextureMetadataSection` to determine the sprite's metadata + - `UBO_SIZE` - The uniform buffer object size of the sprite contents. + - `createTicker` -> `createAnimationState`, not one-to-one + - `uploadFirstFrame` no longer takes in the texture `int`s, instead a mip level `int` + - `$AnimatedTexture#createTicker`, `uploadFirstFrame` -> `createAnimationState`, not one-to-one + - `$Ticker` -> `$AnimationState`, not one-to-one + - `tickAndUpload` -> `tick`, `getDrawUbo`, `needsToDraw`, `drawToAtlas`; not one-to-one + - `SpriteTicker` interface is removed + - `Stitcher` now takes in the anisotropic filtering level + - `$Holder(T, int)` is removed + - `$Region#walk` now takes in a padding `int` + - `$SpriteLoader` no longer takes in the minimum width/height + - `load` now takes in a padding `int` + - `TextureAtlas` now implements `TickableTexture` instead of `Tickable` + - `TextureAtlasSprite` now implements `AutoCloseable` + - The constructor takes in a padding `int` + - `createTicker` -> `createAnimationState`, not one-to-one + - `getUOffset`, `getVOffset`, `uvShrinkRatio` are removed + - `uploadFirstFrame` now takes in the mip level `int` + - `uploadSpriteUbo` - Uploads the atlas sprite to the to the buffer. + - `$Ticker` interface is removed + - `TextureManager` no longer implements `Tickable` + - `Tickable` -> `TickableTexture` +- `net.minecraft.client.renderer.texture.atlas` + - `SpriteSource$SpriteSupplier` -> `$DiscardableLoader` + - `Function` superinterface is now represented as `$Loader` + - `apply` -> `get` + - `SpriteSourceList#list` now returns a list of `SpriteSource$Loader`s +- `net.minecraft.client.resources.metadata.texture.TextureMetadataSection` now takes in a `MipmapStrategy` to determine how a specific texture should be mip mapped, and a `float` for the alpha cutoff bias +- `net.minecraft.client.resources.model` + - `ModelBaker` + - `missingBlockModelPart` - The missing block model. + - `parts` - A cache of previously constructed vectors. + - `$PartCache` - A cache that interns previously constructed vertices in a quad. + - `ModelBakery` + - `*_STILL` - Fluid still texture locations. + - `$MissingModels` now takes in a `BlockModelPart` missing model + - `ModelManager` + - `BLOCK_OR_ITEM` - A special case that causes the model manager to check both the item and block atlas. + - `specialBlockModelRenderer` now returns the raw renderer instead of a supplied value. +- `net.minecraft.data.AtlasIds#ITEMS` - The item atlas identifier. +- `net.minecraft.world.level.block.LeavesBlock#setCutoutLeaves` - Sets whether the leaves is using cutout rendering. + +## Gizmos + +Gizmos are the newest iteration in the submission and rendering decoupling, this time for debug renderers. However, the underlying structure to submit gizmos for rendering is much more complex since debug renderers can submit objects at nearly any point during the client's process. + +### What is a Gizmo? + +A `Gizmo` is basically an object that submits some object primitives -- specifically points, lines, triangle fans, quads, and text -- for rendering. Each gizmo essentially strings together these primitives via `emit` into its desired shape. During the render process, these make use of the `RenderPipelines#DEBUG_*` pipelines to render their primitives to the screen. Creating a new gizmo is as simple as extending the interface: + +```java +// Store some parameters like a render state to submit the element primitives +public record ExampleGizmo(Vec3 start, Vec3 end) implements Gizmo { + + @Override + public void emit(GizmoPrimitives gizmos, float alphaMultiplier) { + // Submit any elements here + gizmos.addLine(this.start, this.end, ARGB.multiplyAlpha(0, alphaMultiplier), 3f); + } +} +``` + +Actually submitting the elements happens through `Gizmos#addGizmo`. This stores the gizmo to be emitted and drawn to the screen, as long as it is called during `Minecraft#tick` or any rendering on the client -- which is how the debug renderers emit theirs, `IntegratedServer#tickServer` in a singleplayer world, or packet processing on either side. All of the methods in `Gizmos` call `addGizmo` internally, which is why the method is typically absent outside its class: + +```java +// Somewhere in GameRenderer#render + +Gizmos.addGizmo(new ExampleGizmo(Vec3.ZERO, Vec3.X_AXIS)); + +// Calls addGizmo internally +Gizmos.point(Vec3.ZERO, 0, 5f); +``` + +Calling `addGizmo` returns a `GizmoProperties`, which sets some properties for when the element is drawn, assuming that `GizmoCollector` is not a `NOOP`. `GizmoProperties` provides three methods: + +| Method | Description | +|:------------------:|:--------------------------------------------------------------------------------| +| `setAlwaysOnTop` | Clears the depth texture before rendering. | +| `persistForMillis` | Keeps the gizmo on screen for the specified amount of time before disappearing. | +| `fadeOut` | Fades the disappearing when persisted for a certain amount of time. | + +### Putting it Together + +With that, how can you submit gizmos for rendering pretty much anywhere in the client pipeline? Well, this all starts from `Gizmos#withCollector` and `SimpleGizmoCollector`. + +`SimpleGizmoCollector` is basically just a list that holds the collected gizmos to render. During the rendering process, `SimpleGizmoCollector#drainGizmos` is called, copying the gizmos over to a separate list for the renderer to `Gizmo#emit`, before drawing to the screen through the familiar frame pass and buffer source. `drainGizmos` then clears the internal list based on `GizmoProperties#persistForMillis`, or immediately if not specified, for the next frame. + +To actually collect these elements, there is a rather convoluted process. `Minecraft`, `LevelRenderer`, and `IntegratedServer` have their own `SimpleGizmoCollector`. This is done by setting the collector using `Gizmo#withCollector`, which returns a `Gizmos$TemporaryCollection`. The collection is `AutoCloseable` that, when closed, releases the held collector on the local thread. So, the collectors are wrapped in a try-with-resources to facilitate the submission during these periods. Then, during the debug pass, the per tick gizmos are merged with the per frame gizmos and drawn to the screen via `addTemporaryGizmos`, quite literally at the last moment in `LevelRenderer#renderLevel`. The `IntegratedServer` gizmos in a singleplayer world are stored in a volatile field, allowing it to be accessed from the client thread. + +- `net.minecraft.client.Minecraft` + - `collectPerTickGizmos` - Returns a collection of all gizmos to emit. + - `getPerTickGizmos` - Gets the gizmos to draw to the screen. +- `net.minecraft.client.renderer` + - `LevelRenderer#collectPerFrameGizmos` - Returns a collection of all gizmos to emit. + - `OrderedSubmitNodeCollector#submitHitbox` is removed + - `ShapeRenderer` + - `renderShape` now takes in a line width `float` + - `renderLineBox` -> `Gizmos#cuboid`, not one-to-one + - `addChainedFilledBoxVertices` -> `Gizmos#cuboid`, not one-to-one + - `renderFace` -> `Gizmos#rect`, not one-to-one + - `renderVector` -> `Gizmos#line`, not one-to-one + - `SubmitNodeCollection#getHitboxSubmits` is removed + - `SubmitNodeStorage$HitboxSubmit` record is removed +- `net.minecraft.client.renderer.debug` + - `DebugRenderer` + - `render` -> `emitGizmos`, no longer takes in the `PoseStack`, `BufferSource` or `boolean`, now taking in the partial tick `float` + - `renderFilledUnitCube` -> `Gizmos#cuboid`, not one-to-one + - `renderFilledBox` -> `Gizmos#cuboid`, not one-to-one + - `renderTextOverBlock` -> `Gizmos#billboardTextOverBlock`, not one-to-one + - `renderTextOverMob` -> `Gizmos#billboardTextOverMob`, not one-to-one + - `renderFloatingText` -> `Gizmos#billboardText`, not one-to-one + - `renderVoxelShape` -> `LevelRenderer#renderHitOutline`, now private, not one-to-one + - `SimpleDebugRenderer$render` -> `emitGizmos`, no longer takes in the `PoseStack`, `BufferSource` or `boolean`, now taking in the partial tick `float` + - `GameTestBlockHighlightRenderer` + - `render` -> `emitGizmos`, taking in no parameters + - `renderMarker` no longer takes in the `PoseStack` or buffer source + - `$Marker#get*` are removed + - `LightDebugRenderer` now takes in two flags determining whether to show the block or sky light + - `PathfindingRenderer#renderPath`, `renderPathLine` no longer take in the `PoseStack` or buffer source +- `net.minecraft.client.renderer.entity.EntityRenderer#extractAdditionalHitboxes` is removed +- `net.minecraft.client.renderer.entity.state` + - `EntityRenderState#hitboxesRenderState`, `serverHitboxesRenderState` are removed + - `HitboxesRenderState` class is removed + - `ServerHitboxesRenderState` class is removed +- `net.minecraft.client.renderer.feature.HitboxFeatureRenderer` -> `EntityHitboxDebugRenderer`, not one-to-one +- `net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives` - A storage and renderer for primitive shapes. or gizmos. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `sampler`, `getSampler` - Returns the `GpuSampler` used by the texture. + - `setClamp` -> `GpuSampler#getAddressMode*`, not one-to-one + - `setFilter` -> `GpuSampler#get*Filter`, not one-to-one + - `ReloadableTexture` no longer takes in the address mode and filter `boolean`s +- `net.minecraft.client.server.IntegratedServer#getPerTickGizmos` - Gets the gizmos to draw to the screen for the current tick. +- `net.minecraft.gizmos` + - `ArrowGizmo` - A gizmo that draws an arrow. + - `CircleGizmo` - A gizmo that draws an approximate circle with twenty vertices. + - `CuboidGizmo` - A gizmo that draws a rectangular prism. + - `Gizmo` - An object that can emit simple shape primitives to draw. + - `GizmoCollector` - An add-only collector. + - `GizmoPrimitives` - Shape primitives that can be drawn. + - `GizmoProperties` - Properties that apply to how the gizmo should be drawn. + - `Gizmos` - A collection of static methods for creating gizmos and collecting them. + - `GizmoStyle` - A property holder to define how a gizmo should be drawn. These are used by the gizmos themselves and not the actual primitives. + - `LineGizmo` - A gizmo that draws a line. + - `PointGizmo` - A gizmo that draws a point. + - `RectGizmo` - A gizmo that draws a rectangle. + - `SimpleGizmoCollector` - A collector implementation for adding gizmos before sending them off for rendering. + - `TextGizmo` - A gizmo that draws text. +- `net.minecraft.server.MinecraftServer#processPacketsAndTick` - Handles server ticking and packet processing. + +## Permission Overhaul + +The permission level integer has been expanded into an entirely new system that is both simple yet complicated. There are three main parts: `Permission`s, `PermissionSet`s, and `PermissionCheck`s. + +### Permissions + +`Permission`s are functionally data objects that define some sort of state. Vanilla provides two types of permissions: `Permission$Atom`, which just is a unique unit object; and `Permission$HasCommandLevel`, which holds the desired `PermissionLevel` for a command. Both of the data objects are registered as map codecs for dumping the command report. + +```java +// Attempts to query moderator level permissions. +public static final Permission COMMANDS_MODERATOR = new Permission.HasCommandLevel(PermissionLevel.MODERATORS); +``` + +A custom permission can be created through some class or record that extends `Permission` with an associated `MapCodec` registered to its static registry: + +```java +// This does not check whether the user has the given permission +// It is literally just holding data representing the permission state +public record HasExamplePermission(int state) implements Permission { + public static final MapCodec MAP_CODEC = Codec.INT.fieldOf("state") + .xmap(HasExamplePermission::new, HasExamplePermission::state); + + @Override + public MapCodec codec() { + return HasExamplePermission.MAP_CODEC; + } +} + +// In some registration handler +Registry.register( + BuiltInRegistries.PERMISSION_TYPE + Identifier.withNamespaceAndPath("examplemod", "has_example_permission"), + HasExamplePermission.MAP_CODEC +); + +// Storing the permission for use +public static final Permission HAS_STATE_ONE = new HasExamplePermission(1); +``` + +### Permission Sets + +If `Permission`s define the queryable state, then `PermissionSet`s are the permissions the user actually has. `PermissionSet` is a functional interface that checks whether the user has the desired permission state (via `hasPermission`). Vanilla uses a `LevelBasedPermissionSet` for checking whether the permission queried matches the current `PermissionLevel`. As a permission set is usually checked against some swathe of permissions, multiple permission sets can be combined into one via `PermissionSet#union`. It functionally performs an OR operation, meaning that if a set does not check a permission, it should default to `false`. + +```java +public interface ExamplePermissionSet extends PermissionSet { + + // Keep track of the user's state for our permissions + int state(); + + @Override + default boolean hasPermission(Permission permission) { + // Check our permission + if (permission instanceof HasExamplePermission example) { + return this.state() >= example.state(); + } + + // Otherwise ignore + return false; + } +} + +// Storing a permission set +// Could also be implemented or stored on the desired target +public static ExamplePermissionSet STATE_ONE = () -> 1; + +// Check whether the permission set has the desired permission +STATE_ONE.hasPermission(HAS_STATE_ONE); +``` + +Currently, there is no simple method to store custom permission sets on the desired user. `CommandSourceStack` does have a method to union other permission sets via `withMaximumPermission`, but that would need to be handled within the associated `createCommandSourceStack` method. The normal `LevelBasedPermissionSet` can typically be queried through a `permissions` method, though there is no common interface across objects, even though `PermissionSetSupplier` seems to exist for that purpose. + +### Permission Checks + +Now, a `PermissionSet` never directly checks a `Permission` within the codebase. That would require having the object accessible at all times. Instead, a `PermissionCheck` object is created, which takes in the `PermissionSet` and `check`s whether the user has the desired data to continue execution. Vanilla provides two types of checks: `$AlwaysPass`, which means it will always return true; and `$Require`, which requires the set to have the desired `Permission`. The checks also have a map codec for dumping the command report. + +```java +// Requires the permission set has acccess to moderator commands +public static final PermissionCheck LEVEL_MODERATORS = new PermissionCheck.Require(COMMANDS_MODERATOR); +``` + +Custom permission checks can be created through some class or record that implements `check` and registers the map codec to its static registry: + +```java +public static record AnyOf(List permissions) implements PermissionCheck { + public static final MapCodec MAP_CODEC = Permission.CODEC.listOf().fieldOf("permissions") + .xmap(AnyOf::new, AnyOf::permissions); + + @Override + public boolean check(PermissionSet permissionSet) { + return this.permissions.stream().filter(perm -> permissionSet.hasPermission(perm)).findAny().isPresent(); + } + + @Override + public MapCodec codec() { + return MAP_CODEC; + } +} + +// In some registration handler +Registry.register( + BuiltInRegistries.PERMISSION_CHECK_TYPE + Identifier.withNamespaceAndPath("examplemod", "any_of"), + AnyOf.MAP_CODEC +); + +// Storing the check for use in a command +public static final PermissionCheck CHECK_STATE_ONE = new AnyOf(List.of( + HAS_STATE_ONE, + Permissions.COMMANDS_GAMEMASTER +)); + +// For some command +Commands.literal("example").requires(Commands.hasPermission(CHECK_STATE_ONE)); +``` + +- `net.minecraft.client.multiplayer.ClientSuggestionProvider` no longer implements `PermissionSource` + - The constructor now takes in a `PermissionSet` instead of a `boolean` + - `allowsRestrictedCommands` -> `ClientPacketListener#ALLOW_RESTRICTED_COMMANDS`, now private, not one-to-one +- `net.minecraft.client.player.LocalPlayer#setPermissionLevel` -> `setPermissions`, not one-to-one +- `net.minecraft.commands` + - `Commands` + - `LEVEL_*` are now `PermissionCheck`s instead of `int`s + - `hasPermission` now takes in a `PermissionCheck` instead of an `int`, and returns a `PermissionProviderCheck` instead of a `PermissionCheck` + - `createCompilationContext` - Creates a source stack with the given permissions. + - `CommandSourceStack` no longer implements `PermissionSource` + - The constructor now takes in a `PermissionSet` instead of an `int` + - The `protected` constructor is now `private` + - `withPermission` now takes in a `PermissionSet` instead of an `int` + - `withMaximumPermission` now takes in a `PermissionSet` instead of an `int` + - `ExecutionCommandSource` now extends `PermissionSetSupplier` instead of `PermissionSource` + - `PermissionSource` interface is removed + - `SharedSuggestionProvider` now extends `PermissionSetSupplier` +- `net.minecraft.commands.arguments.selector.EntitySelectorParser#allowSelectors` now has an overload that takes in a `PermissionSetSupplier` +- `net.minecraft.core.registries` + - `BuiltInRegistries#PERMISSION_TYPE`, `Registries#PERMISSION_TYPE` - An object that defines some data requirement. + - `BuiltInRegistries#PERMISSION_CHECK_TYPE`, `Registries#PERMISSION_CHECK_TYPE` - A predicate that checks whether the set has the required data. +- `net.minecraft.server` + - `MinecraftServer` + - `operatorUserPermissionLevel` -> `operatorUserPermissions`, not one-to-one + - `getFunctionCompilationLevel` -> `getFunctionCompilationPermissions`, not one-to-one + - `getProfilePermissions` now returns a `LevelBasedPermissionSet` + - `ReloadableServerResources#loadResources` now takes in a `PermissionSet` instead of an `int` + - `ServerFunctionLibrary` now takes in a `PermissionSet` instead of an `int` + - `WorldLoader$InitConfig` now takes in a `PermissionSet` instead of an `int` +- `net.minecraft.server.commands.PermissionCheck` -> `.server.permissions.PermissionCheck`, not one-to-one +- `net.minecraft.server.dedicated.DedicatedServerProperties` + - `opPermissionLevel` -> `opPermissions`, not one-to-one + - `functionPermissionLevel` -> `functionPermissions`, not one-to-one + - `deserializePermissions`, `serializePermission` - Reads and writes the chosen level permission set. +- `net.minecraft.server.jsonrpc.internalapi` + - `MinecraftOperatorListService#op` now takes in an optional `PermissionLevel` instead of an `int` + - `MinecraftServerSettingsService` + - `getOperatorUserPermissionLevel` -> `getOperatorUserPermissions`, not one-to-one + - `setOperatorUserPermissionLevel` -> `setOperatorUserPermissions`, not one-to-one +- `net.minecraft.server.jsonrpc.methods` + - `OperatorService$OperatorDto#permissionLevel` now takes in an optional `PermissionLevel` instead of an `int` + - `ServerSettingsService` + - `operatorUserPermissionLevel` now returns a `PermissionLevel` instead of an `int` + - `setOperatorUserPermissionLevel` now takes in and returns a `PermissionLevel` instead of an `int` +- `net.minecraft.server.permissions` + - `LevelBasedPermissionSet` - A set of permissions that checks whether the user has an equal or higher command permission level. + - `Permission` - Data related to the user's permissions, such as command level. + - `PermissionCheckTypes` - The types of permission checks vanilla provides. + - `PermissionLevel` - Defines a level sequence for a permission. + - `PermissionProviderCheck` - A predicate that checks that tests the supplier's permission set against a check. + - `Permissions` - The permissions vanilla provides. + - `PermissionSet` - A set of a permissions to user has, but mostly defines a method to determine whether a user has the desired permission. + - `PermissionSetSupplier` - An object that supplies a `PermissionSet`. + - `PermissionSetUnion` - A union of multiple permission sets. + - `PermissionTypes` - The types of permissions vanilla provides. +- `net.minecraft.server.players` + - `PlayersList#op` now takes in an optional `LevelBasedPermissionSet` instead of an `int` + - `ServerOpListEntry` now takes in a `LevelBasedPermissionSet` instead of an `int` + - `getLevel` -> `permissions`, not one-to-one +- `net.minecraft.world.entity.player.Player#getPermissionLevel`, `hasPermissions` -> `permissions`, not one-to-one +- `net.minecraft.world.entity.projectile.ProjectileUtils` + - `getHitEntitiesAlong` - Gets the entities hit along the provided path. + - `getManyEntityHitResult` - Gets all entities hit along the path of the two points within the bounding box. +- `net.minecraft.world.entity.projectile.arrow.AbstractArrow#findHitEntities` - Gets all entities hit by the vector. + +## New Data Components + +With the addition of the spear, a number of data components have been added to provide the associated functionality. The following is an brief overview of these components. + +### Use Effects + +`DataComponents#USE_EFFECTS` defines some effects to apply to the player that is using (e.g., right-clicking) an item. Currently, there are only three types of effects: whether the player can sprint when using the item, whether the use interaction causes vibrations, and the scalar that is applied to the player's horizontal movement. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.USE_EFFECTS, + new UseEffects( + // Whether the player can sprint while using the item + true, + // Whether on item use that a vibration is sent from the player + false + // The scalar applied to the player's horizontal movement + 0.5f + ) +)); +``` + +### Damage Type + +`DataComponents#DAMAGE_TYPE` defines the damage type applied to an entity when hit with this item. It takes in either the `ResourceKey` of the damage type or the `DamageType` object itself. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.DAMAGE_TYPE, + new EitherHolder<>( + // The damage type this item applies to the attacked entity + DamageTypes.FALLING_ANVIL + ) +)); +``` + +### Swing Animation + +`DataComponents#SWING_ANIMATION` defines the animation to play when swinging or attacking (e.g., left-clicking) with the item. There are three types of animation to play: `SwingAnimationType#NONE`, which does nothing; `WHACK`, which plays the standard swing animation; and `STAB`, which plays the spear thrust animation. The length of the animation can also be specified. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.SWING_ANIMATION, + new SwingAnimation( + // The animation to play + SwingAnimationType.NONE, + // The amount of time to play the animation for, in ticks + 20 + ) +)); +``` + +### Minimum Attack Charge + +`DataComponents#MINIMUM_ATTACK_CHARGE` determines how long the player must wait before making another attack with the item. The charge is a value between 0 and 1, which determines percentage of the delay to wait before making another attack. The delay is determined by the player's attack speed. This is checked twice if the player's action is a stab. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.MINIMUM_ATTACK_CHARGE, + // The percentage of time the player must wait before making another attack with this item + 0.5f +)); +``` + +### Attack Range + +`DataComponents#ATTACK_RANGE` determines the range that an entity can attack another entity from when attacking with this item. If not set, it defaults to the entity's interaction range attribute. The range specified is for the player, with mob reach determined by the range times the mob factor. A range can also be specified for the player when in creative mode, overriding the default range. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.ATTACK_RANGE, + new AttackRange( + // The minimum range in blocks for this item to hit the entity. + // Must be between [0, 64]; defaults to 0. + 0.4f, + // The maximum range in blocks for this item to hit the entity. + // Must be between [0,64]; defaults to 3. + 4.5f, + // The minimum range in blocks for this item to hit the entity, + // provided the holding entity is a player in creative mode. + // This supercedes the minimum range. + // Must be between [0, 64]; defaults to 0. + 0f, + // The maximum range in blocks for this item to hit the entity, + // provided the holding entity is a player in creative mode. + // This supercedes the maximum range. + // Must be between [0,64]; defaults to 3. + 5f, + // The margin to inflate the hitbox by in blocks, compensating + // for potential precision issues. + // Must be between [0,1]; defaults to 0.3. + 0.25f, + // A scalar to multiply the minimum and maximum range by to determine + // a non-player entity's reach. + // Must be between [0,2]; defaults to 1. + 1.1f + ) +)); +``` + +### Piercing Weapon + +`DataComponents#PIERCING_WEAPON` sets the player's attack as not an attack, but as a stab or piercing attack. This is a separate action than swinging, which either attacks the entity or breaks a block. A piercing weapon can attack an entity, but is unable to break blocks. It also applies any enchantment effects for lunging. Piercing weapons are only applied to the player. + +The logic pipeline flows like so: + +- If `Player#cannotAttackWithItem` returns true, then the pipeline is terminated +- Piercing attack is handled via: + - Client - `MultiPlayerGameMode#piercingAttack` + - Server - `PiercingWeapon#attack` +- Server-only: + - Get all entities that: + - Are within the entity's attack range `DataComponents#ATTACK_RANGE` + - Are within the hitbox constructed from the reach starting at the player's eye position + - If `PiercingWeapon#canHitEntity` returns true: + - Player is not invulnerable or dead, and + - Either: + - Entity is an `Interaction` entity + - Or: + - Entity can be hit by a projectile + - If both players, that this player can harm the other player + - Is not a passenger of the same vehicle + - Call `LivingEntity#stabAttack` on each entity +- `LivingEntity#onAttack` is fired +- `LivingEntity#lungeForwardMaybe` is fired +- Server-only: + - `PiercingWeapon#makeHitSound` is played if at least one entity was hit + - `PiercingWeapon#makeSound` is played +- `LivingEntity#swing` is fired + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.PIERCING_WEAPON, + new PiercingWeapon( + // Whether being hit by this item deals knockback to the entity. + true, + // Whether being hit by this item dismounts the entity from its vehicle. + true, + // The sound to play when attacking with this item. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.LLAMA_SWAG), + // The sound to play when this item hits an entity. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.ITEM_BREAK) + ) +)); +``` + +### Kinetic Weapon + +`DataComponents#KINETIC_WEAPON` affects an entity's use (e.g., right-click) behavior. On right-click, if an item has the component, then `KineticWeapon#damageEntities` is called every tick instead of `Item#onUseTick`, only on the server. The kinetic weapon also calls `LivingEntity#stabAttack` to damage its entities similar to piercing attack. In fact, the component itself is similar to `PiercingWeapon`, except with a few additional fields to handle the kinetic damage applied and to make it accessible to all living entities instead of only the player. + +For the stab attack to occur, one of the conditions (dismount, knockback, damage) must be present and return true. The attack range is obtained from the `DataComponents#ATTACK_RANGE` component. If a stab attack occurs, then the `SPEAR_MOBS_TRIGGER` criteria will be fired on the server. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.KINETIC_WEAPON, + new KineticWeapon( + // The number of ticks to wait before this entity can attempt to contact + // (e.g., damage) another entity. + 10, + // The number of ticks to wait before attempting to stab any entities in range. + 20, + // The condition to check whether an attack from this item will dismount + // an entity in a vehicle. + // If the optional is not present, then it will default to false. + Optional.of(new KineticWeapon.Condition( + // The maximum number of ticks from first use plus delay that this + // condition may return true. + 100, + // The minimum speed the entity must be traveling for this condition + // to succeed. + // The speed is calculated as the dot product of the delta movement + // and the view vector multiplied by 20. + // Vanilla spears use values from 7-14 for dismount and 5.1 for knockback. + 9f, + // The minimum speed relative to the attacking entity that this entity + // must be traveling for this condition to succeed. + // Vanilla spears use 4.6 for damage. + 5f + )), + // The condition to check whether an attack from this item will cause knockback + // to an entity. + // If the optional is not present, then it will default to false. + Optional.of(KineticWeapon.Condition.ofAttackerSpeed( + // Maximum ticks + 100, + // Entity traveling speed + 5.1f + )), + // The condition to check whether an attack from this item will damage an + // entity. + // If the optional is not present, then it will default to false. + Optional.of(KineticWeapon.Condition.ofRelativeSpeed( + // Maximum ticks + 100, + // Relative traveling speed + 4.6f + )), + // The movement of the item during the third person attack animation + // Vanilla spears use 0.38. + 0.38f, + // A multiplier to apply to the damage of an entity + // The damage is calculated as the relative traveling speed of this entity + // to its target. + 4f, + // The sound to play when first using this item. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.LLAMA_SWAG), + // The sound to play when this item hits an entity. + // If the optional is empty, no sound is played. + Optiona.of(SoundEvents.ITEM_BREAK) + ) +)); +``` + +- `net.minecraft.core.components` + - `DataComponents` + - `USE_EFFECTS` - The effects to apply to the entity when using the item. + - `MINIMUM_ATTACK_CHARGE` - The minimum amount of time to attack with the item. + - `DAMAGE_TYPE` - The `DamageType` the item deals + - `PIERCING_WEAPON` - A weapon with some hitbox range that lunges towards the entity. + - `KINETIC_WEAPON` - A weapon with some hitbox range that requires some amount of forward momentum. + - `SWING_ANIMATION` - The animation applied when swinging an item. + - `ATTACK_RANGE` - Sets a custom attack range when using the item, overriding the normal entity interaction range. +- `net.minecraft.core.component.DataComponentType#ignoreSwapAnimation`, `$Builder#ignoreSwapAnimation` - When true, the swap animation does not affect the data component 'usage'. +- `net.minecraft.core.component.predicates` + - `AnyValue` - A predicate that checks if the component exists on the getter. + - `DataComponentPredicate` + - `$Type` is now an interface + - Its original implementation has been replaced by `$TypeBase` + - `$AnyValueType` - A type that uses the `AnyValue` predicate. + - `$ConcreteType` - A type that defines a specific predicate. +- `net.minecraft.network.protocol.game.ServerboundInteractPacket#isWithinRange` - Whether the interaction from the player is within the valid range to execute. +- `net.minecraft.world.entity` + - `LivingEntity` + - `SWING_DURATION` -> `SwingAnimation#duration`, not one-to-one + - `stabbedEntities` - The number of recent entities attacked by a kinetic weapon. + - `entityAttackRange` - The range that this entity can attack. + - `getActiveItem` - The currently used item, or the mainhand item. + - `Mob` + - `chargeSpeedModifier` - The modifier applied to the movement speed when charging. + - `canFireProjectileWeapon` -> `canUseNonMeleeWeapon`, now taking in an `ItemStack` instead of a `ProjectileWeaponItem` + - `getAttackBoundingBox` now takes in a horizontal inflation offset +- `net.minecraft.world.entity.ai.behavior` + - `ChargeAttack` - Handles a charge attack performed by a mob. + - `SpearApproach` - Approaches the enemy when holding a kinetic weapon. + - `SpearAttack` - Attacks the enemy with a kinetic weapon. + - `SpearRetreat` - Flees from the attacked target after using a kinetic weapon. +- `net.minecraft.world.entity.ai.goal.SpearUseGoal` - Handles a mob using a spear. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `SPEAR_FLEEING_TIME` - The number of ticks the entity has been fleeing for after using a kinetic weapon. + - `SPEAR_FLEEING_POSITION` - The position the entity flees to after using a kinetic weapon. + - `SPEAR_CHARGE_POSITION` - The position the entity charges to when using a kinetic weapon. + - `SPEAR_ENGAGE_TIME` - How long this entity has been engaged with its enemy when using a kinetic weapon. + - `SPEAR_STATUS` - The status of the entity when using a kinetic weapon. +- `net.minecraft.world.entity.player.Player` + - `hasEnoughFoodToDoExhaustiveManoeuvres` - Returns whether the player can perform an exhaustive manuever. + - `canInteractWithEntity` -> `isWithinEntityInteractionRange` + - `isWithinAttackRange` - If the bounding box being targeted is within the player's range. + - `canInteractWithBlock` -> `isWithinBlockInteractionRange` + - `CREATIVE_ENTITY_INTERACTION_RANGE_MODIFIER_VALUE` - A modifiers that increases the maximum range of an interaction by the given amount. +- `net.minecraft.world.item` + - `Item#getDamageSource` -> `getItemDamageSource`, now deprecated + - `ItemStack` + - `getSwingAnimation` - Returns the swing animation of the item. + - `getDamageSource` - Returns the damage source the item provides when hit. + - `causeUseVibration` - Sends the game event if the item on use can cause vibrations. + - `SwingAnimationType` - The type of animation played when swinging the item. +- `net.minecraft.world.item.component` + - `AttackRange` - The hitbox range of this item. + - `KineticWeapon` - A weapon that requires some amount of forward momentum. + - `PiercingWeapon` - A weapon that lunges towards the entity. + - `SwingAnimation` - The animation applied when swinging an item. + - `UseEffects` - The effects to apply to the entity when using the item. + +## The Timeline of Environment Attributes + +Environment attributes, as the name implies, defines a set of properties or modifications ('attributes') for a given dimension and/or biome ('environment'). They are stored directly within the biome or dimension type under the `attributes` field, or as part of a mutable timeline under the `tracks` field. Each attribute can represent anything from the visual settings to gameplay behavior, interpolating between different values as defined. Vanilla provides their available attributes within `EnvironmentAttributes` while the stored attributes are obtained from `Level#environmentAttributes`. + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + // Defines the attributes to apply within the dimension + "attributes": { + // Sets the cloud height + // More technically, modifies the value by overriding it + "minecraft:visual/cloud_height": 90 + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + // Defines the attributes to apply within the biome + // Defaults or modifies those in the dimension + // These attributes must be positional + "attributes": { + "minecraft:visual/cloud_height": { + // Instead of setting the value, apply a modifier + "modifier": "add", + // Adds 60 to 90, making this biome have a cloud height of 150 + "argument": 60 + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + // The number of ticks this track takes before repeating + "period_ticks": 24000, + // Defines the attributes to interpolate between + // based on the defined keyframes. + // Defaults or modifies those in the biome, or dimension + "tracks": { + "minecraft:visual/cloud_height": { + // The keyframes that define certain values of the attribute + "keyframes": [ + { + // The tick representing the keyframe + "tick": 12000, + // The argument that modifies the value + // In this case, adds 1 to 60 + 90, making this have a cloud height of 151 + "value": 1 + }, + { + // The tick representing the keyframe + "tick": 23999, + // The argument that modifies the value + // In this case, adds 0 to 60 + 90, making this have a cloud height of 150 + "value": 0 + } + ], + // Instead of setting the value, applies a modifier to the argument + "modifier": "add", + // The sampler function to apply when interpolating between ticks + "ease": "linear" + } + } +} +``` + +When calling `EnvironmentAttributeSystem#getValue`, the attribute value is obtained through the layers defined by the `Level`: + +1. Read the default value from the registered attribute (via `EnvironmentAttribute#defaultValue`). +2. Apply the modifier from the dimension, or do nothing if one does not exist for this attribute. +3. Apply the modifier from the biome, or do nothing if one does not exist. +4. Apply the modifiers from all active timelines defined in the `DimensionType`, or do nothing if none exist. Timeline order is not guaranteed. +5. If the dimension can have weather (skylight, no ceiling, and not the end), apply the modifiers from the `WeatherAttributes`. +6. If on the client (i.e. `ClientLevel`), apply the sky flashes modifier. +7. Sanitize the final value to be in the range defined by the `EnvironmentAttribute`. + +This is highly oversimplified and introduces many new concepts, so let's break it down further by creating our own environment attribute and timeline. + +### Custom Environment Attributes + +Environment attributes are created through the `$Builder`, via `EnvironmentAttribute#builder`, taking the type value it represents (e.g., float, integer, object). The builder only requires one value to be set: the `defaultValue`. This is used if the attribute is not overridden by a dimension or biome. If the attribute value should have a valid set of states, then an `AttributeRange` can be set via `valueRange`. The `AttributeRange` is basically a unary operator that transforms the input into its 'valid' state via `sanitize`. It also verifies that the value passed in through the JSON is in a 'valid' state via `validate`. + +From there, there are three more methods responsible for determining the logic used to compute the value. `$Builder#syncable` syncs the attribute to the client, which is required for any attribute that causes some sort of change that is not specific to the server (e.g., visuals, audio, or common code). `notPositional` means that the attribute cannot be applied on a biome (still settable in a dimension or timeline), else an exception is thrown. Finally `spatiallyInterpolated` will attempt to interpolate using the attribute type between different biomes to apply a more seamless transition. Vanilla only handles client side attributes for spatial interpolation. Anything on the server must handle their own `SpatialAttributeInterpolator`. + +Finally the actual attribute can be obtained via `$Builder#build`. This value must be registered to `BuiltInRegistries#ENVIRONMENT_ATTRIBUTE`: + +```java +public static final EnvironmentAttribute EXAMPLE_ATTRIBUTE = Registry.register( + BuiltInRegistries.ENVIRONMENT_ATTRIBUTE, + Identifier.withNamespaceAndPath("examplemod", "example_attribute"), + EnvironmentAttribute.builder( + // The attribute type + // Must match the generic for the attribute value + AttributeTypes.BOOLEAN + ) + // The value this attribute should have by default + .defaultValue(false) + // Syncs this value to the client + .syncable() + .build() +); +``` + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + "attributes": { + "examplemod:example_attribute": true + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + "attributes": { + "examplemod:example_attribute": { + "modifier": "xor", + "argument": true + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + "period_ticks": 24000, + "tracks": { + "examplemod:example_attribute": { + "keyframes": [ + { + "tick": 12000, + "value": false + }, + { + "tick": 23999, + "value": true + } + ], + "modifier": "and", + "ease": "linear" + } + } +} +``` + +### Custom Attribute Types + +Every environment attribute has an associated attribute type that is statically registered to `BuiltInRegistries#ATTRIBUTE_TYPE`. Not only does this define how to serialize the object value, but it also contains the modifications that can be applied to the value along with how to interpolate between spaces and frames. In fact, all of the builder settings, including `syncable` and `spatiallyInterpolated`, rely on the attribute type to determine what does it mean to perform that action. Without it, the attribute couldn't even be read from the dimension or biome JSON, much less the actual logic behind getting the value of the attribute. + +As such, the attribute type can be broken into three parts: the serialization codec, the modifier library, and the interpolation functions. + +```java +// We will use this example object for explaining the attribute type +public record ExampleObject(int value1, boolean value2) { + // The default value + public static final ExampleObject DEFAULT = new ExampleObject(0, false); +} +``` + +#### Type Serialization + +Serialization of the attribute type is handled through a codec of that type, both to disk (biome and dimension JSON) and network (`$Builder#syncable`): + +```java +// The codec to serialize the attribute type value +public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(ExampleObject::value1), + Codec.BOOL.fieldOf("value2").forGetter(ExampleObject::value2) + ).apply(instance, ExampleObject::new) +); +``` + +#### Modifier Library + +The modifier library is a map of `AttributeModifier$OperationId` to `AttributeModifier`s that determine what operations can be performed on the default value. If the map contains no operations, the the default value cannot be mutated. All of the static constructors for `AttributeType` add the `OVERRIDE` modifier, allowing for the dimension and/or biome to set the value. This map should be thought of as a pseudo-registry (basically keys to unique values), as the default codec used to serialize is for a `BiMap` via an id resolver. + +An `AttributeModifier` defines two generics: the first being the environment attribute value type, and the second being an arbitrary object to apply the operation with. The modifier has two methods: `apply`, which takes in the value and the argument to return a new value; and `argumentCodec` to properly serialize the argument. For any operation, all possible mutations must be implemented within a single `AttributeModifier`: + +```java +// Modifiers only handling a part of the object +public static final AttributeModifier ADD = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Integer argument) { + // Apply the operation to the subject + return new ExampleObject(subject.value1() + argument, subject.value2()); + } + + @Override + public Codec argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + return Codec.INT; + } +}; + +public static final AttributeModifier OR = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Boolean argument) { + // Apply the operation to the subject + return new ExampleObject(subject.value1(), subject.value2() || argument); + } + + @Override + public Codec argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + return Codec.BOOL; + } +}; + +// A modifier handling all possible object combinations +public static final AttributeModifier>> AND = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Either> argument) { + return argument.map( + arg -> new ExampleObject(subject.value1() & arg.value1(), subject.value2() && arg.value2()), + either -> either.map( + arg -> new ExampleObject(subject.value1() & arg, subject.value2()), + arg -> new ExampleObject(subject.value1(), subject.value2() && arg) + ) + ); + } + + @Override + public Codec>> argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + // We can use the attribute codec for the value type + return Codec.either(attribute.valueCodec(), Codec.either(Codec.INT, Codec.BOOL)); + } +}; + +// Constructing the library +// The argument can be any value as long as it can be serialized and handled +// If using one of the static constructors for the attribute type, the override +// handler is added automatically along with the associated modifier codec for +// the map +public static final Map> EXAMPLE_LIBRARY = Map.of( + AttributeModifier.OperationId.ADD, ADD, + AttributeModifier.OperationId.OR, OR, + AttributeModifier.OperationId.AND, AND +); +``` + +#### Type Interpolation + +To support interpolation, whether for client frames (because of `$Builder#syncable`), spatial (`$Builder#spatiallyInterpolated`), states (weather), or keyframes (timelines), there needs to be some function that, given some step between 0 and 1 (either time or position), how are the two values merged. This is handled through a `LerpFunction`, of which the generic is the environment attribute value type. For non-interpolated values, this normally uses `LerpFunction#ofStep`, which acts like a simple threshold between the two values. More specifically, spatial will set the threshold as 0.5 while the partial tick, keyframe, and state change will only consider full steps (meaning always the next value). However, this function can be however you choose to define it: + +```java +// Step represents the value between 0 and 1 to interpolation +// Original represents the step at 0 +// Next represents the step at 1 +public static final LerpFunction EXAMPLE_SPATIAL_LERP = (step, original, next) -> { + return new ExampleObject( + Mth.lerp(step, original.value1(), next.value1()), + step >= 0.5f ? next.value2() : original.value2() + ); +} + +public static final LerpFunction EXAMPLE_PARTIAL_LERP = (step, original, next) -> { + return new ExampleObject( + Mth.lerp(step, original.value1(), next.value1()), + next.value2() + ); +} + +// Will always return the first value +public static final LerpFunction EXAMPLE_KEYFRAME_LERP = LerpFunction.ofConstant(); + +// Will change to the next state after 0.1 of the step has past +public static final LerpFunction EXAMPLE_STATE_CHANGE_LERP = LerpFunction.ofStep(0.1f); +``` + +#### Putting it all Together + +With each of these parts, an `AttributeType` can now be constructed. This is typically done using one of the static constructors: `ofInterpolated` for values that define their interpolation function, or `ofNotInterpolated`, for values that are okay just snapping between two values. For common use cases, unless your value transitions between something that is inherently obvious to the player (e.g., visuals like fog or sky color), then interpolation is generally unnecessary. + +If you decide to use the `AttributeType` instance constructor instead, you will also have to create a codec to serialize the modifier map. See `AttributeType#createModifierCodec` on how to do so. + +```java +// The attribute type must be statically registered to be handled correctly +public static final AttributeType EXAMPLE_ATTRIBUTE_TYPE = Registry.register( + BuiltInRegistries.ATTRIBUTE_TYPE, + Identifier.withNamespaceAndPath("examplemod", "example_attribute_type"), + new AttributeType<>( + // The codec for the value + ExampleObject.CODEC, + // The map of operations that can be modified + // `OVERRIDE` is automatically added for serialization + EXAMPLE_LIBRARY, + // The codec used to serialize the modifier library + Util.make(() -> { + ImmutableBiMap> map = ImmutableBiMap.builder() + .put(AttributeModifier.OperationId.OVERRIDE, AttributeModifier.override()) + .putAll(EXAMPLE_LIBRARY) + .buildOrThrow(); + return ExtraCodecs.idResolverCodec(AttributeModifier.OperationId.CODEC, map::get, map.inverse()::get); + }), + // The function interpolating between two keyframes in a timeline + EXAMPLE_KEYFRAME_LERP, + // The function interpolating between two states (only used for attributes in the weather maps) + EXAMPLE_STATE_CHANGE_LERP, + // The function interpolating between two spatial coordinates + EXAMPLE_SPATIAL_LERP, + // The function interpolating between client frames + EXAMPLE_PARTIAL_LERP + ) +); +``` + +From there, we can create an `EnvironmentAttribute` that uses said type: + +```java +public static final EnvironmentAttribute EXAMPLE_OBJECT_ATTRIBUTE = Registry.register( + BuiltInRegistries.ENVIRONMENT_ATTRIBUTE, + Identifier.withNamespaceAndPath("examplemod", "example_object_attribute"), + EnvironmentAttribute.builder( + EXAMPLE_ATTRIBUTE_TYPE + ) + .defaultValue(ExampleObject.DEFAULT) + // Possible because of the codec and partial tick lerp + .syncable() + // Possible because of the spatial lerp + .spatiallyInterpolated() + .build() +); +``` + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + "attributes": { + "examplemod:example_object_attribute": { + "value1": 10, + "value2": true + } + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + "attributes": { + "examplemod:example_object_attribute": { + // Must use one of the arguments defined in the library + // In this case either 'add', 'or', or 'and' + "modifier": "and", + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "argument": false + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + "period_ticks": 24000, + "tracks": { + "examplemod:example_object_attribute": { + "keyframes": [ + { + "tick": 12000, + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "value": 1 + }, + { + "tick": 23999, + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "value": { + "value1": 0, + "value2": false + } + } + ], + // Must use one of the arguments defined in the library + // In this case either 'add', 'or', or 'and' + "modifier": "and", + "ease": "linear" + } + } +} +``` + +### Timelines + +`Timeline`s are method of modifying attributes based on the current game time. More specifically, they define some keyframes that the values are interpolated between, first determining the step using the `EasingType` function, and second using `AttributeType#keyframeLerp` to get the value. This is not only a replacement of `Schedule`s in brains, but also attributes relating to the day/night cycle (e.g., sky color, slime spawn chance, etc.). These function as a layer after the biome modifiers are applied for both positional and non-positional attributes. + +Timelines are activated based on the `DimensionType#timelines` tag, which are prefixed with `in_` (e.g. `minecraft:in_overworld` is the timeline tag for the overworld). All dimension tags include the `minecraft:universal` tag, meaning all timelines tagged within will run within all dimensions (provided they add the universal tag). + +The vanilla timelines are like so: + +- `minecraft:day`: The day/night cycle +- `minecraft:moon`: The moon phase and spawn chance +- `minecraft:villager_schedule`: What `Activity` a villager performs +- `minecraft:early_game`: Stops pillager patrol spawns for the first few days + +The associated tags are the following; + +- `minecraft:universal` + - `minecraft:villager_schedule` +- `minecraft:in_overworld` - Overworld dimension + - `#minecraft:universal` + - `minecraft:day` + - `minecraft:moon` + - `minecraft:early_game` +- `minecraft:in_nether` - Nether dimension + - `#minecraft:universal` +- `minecraft:in_end` - End dimension + - `#minecraft:universal` + +#### Keyframes + +Each `Timeline` is made up of keyframes responsible for determining what the argument to the modifier should be at a given tick. These keyframes are then compiled into a list called a `KeyframeTrack`, baked into a `KeyframeTrackSampler` when constructing the attribute layers. Every two adjacent keyframes (including the first and last) is considered a `KeyframeTrackSampler$Segment`. This is what's used to sample an attribute at a given tick. + +Let's say we have the following (keyframe, value) segment (100, 0) -> (200, 1) and we are currently at tick 150. How do we choose what argument to use? Well, this is performed in two operations. First, we calculate the step: a value between `0` and `1` that determines how much to interpolate the value with. The step is calculated first linearly: (current_tick - start_segment_tick) / (end_segment_tick - start_segment_tick). Then, the step is passed into the desired `EasingType`, which is a function that takes in a 0-1 value and returns a 0-1 value, such as `in_out_bounce` or `out_back`. You can also create your own `EasingType` like so: + +```java +// `EasingType#registerSimple` must be made public +EasyingType.registerSimple( + // The name of the function + "examplemod:ease", + // The function to apply to the value + // For smooth transitions, the function should map 0 -> 0 and 1 -> 1 + original -> 0.5f * (float) Mth.sin(Math.PI * (3 * original - 0.5)) + 0.5f +); +``` + +Then, it passes the step to the `AttributeType#keyframeLerp` function along with the two arguments to get the lerped argument to apply. + +#### Attribute Tracks + +With the keyframes determining the arguments, we apply the arguments to the attribute through an `AttributeTrack`, baked into an `AttributeTrackSampler` when constructing the attribute layers. An `AttributeTrack` contains the `KeyframeTrack` to get the arguments, and an `ArgumentModifier` to apply the argument to the value. Note that there can only be one modifier for a given track. + +These `AttributeTrack`s are then stored in a map of attributes to tracks, which define our `Timeline`. The timeline also contains an optional integer indicating the period of the tracks. The 'period', in this case, acts as one full run of all tracks in the timeline. Values outside of the period are modulo'd. Most timelines use `24000` for the period as that represents one Minecraft day in ticks. + +#### Custom Timelines + +Custom `Timeline`s are added to the `timeline` datapack registry: + +```json5 +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + // Runs for every 3000 ticks (1/8 of a day) + "period_ticks": 3000, + "tracks": { + // The attribute(s) to modify + "examplemod:example_object_attribute": { + // The easing function to determine the step between arguments + "ease": "examplemod:ease", + // The list of keyframes defining the arguments at set ticks + // The arguments are then interpolated using the easing function + // and keyframe lerp + "keyframes": [ + { + // The tick for which this argument is the given value + "tick": 1500, + // Adds 10 to the attribute + "value": 10 + }, + // In-between, uses the easing function to step down between + // 10 and 0 + { + "tick": 2999, + // Adds 0 to the attribute + "value": 0 + } + // In-between, uses the easing function to step up between + // 0 and 10 + ], + // The modifier to use when applying the argument + // to the value + "modifier": "add" + } + } +} +``` + +- `net.minecraft.client` + - `Camera#attributeProbe` - Gets the client environment attribute probe for values and interpolation. + - `Minecraft` + - `getSituationalMusic` now returns `Music` instead of `MusicInfo` + - `getMusicVolume` - Gets the volume of the background music, or normal volume if the open screen has background music. +- `net.minecraft.client.multiplayer.ClientLevel` + - `effects` is removed + - `getSkyDarken` -> `EnvironmentAttributes#SKY_LIGHT_COLOR`, `SKY_LIGHT_FACTOR`; not one-to-one + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR`, not one-to-one + - `getCloudColor` -> `EnvironmentAttributes#CLOUD_COLOR`, not one-to-one + - `getStarBrightness` -> `EnvironmentAttributes#STAR_BRIGHTNESS`, not one-to-one + - `getSkyFlashTime` is now private +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects` class is removed, replaced entirely by `EnvironmentAttribute`s + - `SkyRenderer` + - `renderSkyDisc` now takes in a single ARGB `int` instead of three RGB `float`s + - `renderSunMoonAndStars` now take in two additional `float`s for the moon and star rotation +- `net.minecraft.client.renderer.state.SkyRenderState` + - `skyType` -> `skybox`, not one-to-one + - `isSunriseOrSunset`, `timeOfDay` are removed + - `moonAngle`, `starAngle` - The angle of the moon and stars. +- `net.minecraft.client.resources.sounds.BiomeAmbientSoundsHandler` no longer takes in the `BiomeManager` +- `net.minecraft.client.sounds` + - `MusicInfo` -> `Minecraft#getSituationalMusic`, `getMusicVolume`; not one-to-one + - `MusicManager#startPlaying` now takes in the `Music` instead of the `MusicInfo` +- `net.minecraft.core.registries` + - `BuiltInRegistries`, `Registries#ENVIRONMENT_ATTRIBUTE` - The registry for the environment attributes. + - `BuiltInRegistries`, `Registries#ATTRIBUTE_TYPE` - The registry for the attribute types. + - `BuiltInRegistires`, `Registries#SCHEDULE` are removed + - `Registries#TIMELINE` - The registry key for the timeline. +- `net.minecraft.data.tags.TimelineTagsProvider` - The tags provider for the timeline. +- `net.minecraft.server.level.ServerLevel#getMoonBrightness` - Returns the brightness of the moon. +- `net.minecraft.sounds.Music#event` -> `sound` +- `net.minecraft.tags.TimelineTags` - The tags for the timeline. +- `net.minecraft.util` + - `BinaryAnimator$EasingFunction` -> `EasingType` + - `CubicSampler` -> `GaussianSampler`, `SpatialAttributeInterpolator`; not one-to-one + - `KeyframeTrack` - A track of keyframes and the easing performed between them. + - `KeyframeTrackSampler` - A keyframe track that replays based on the period, lerping between values using the provided function. +- `net.minecraft.world.attribute` + - `AmbientSounds` - The sounds that ambiently play within an environment. + - `AttributeRange` - An interface meant to validate inputs and sanitize the corresponding value into an appropriate bound. + - `AttributeType` - A type definition of the operations and modifications that can be performed by an attribute. + - `AttributeTypes` - A registry of all vanilla attribute types. + - `BackgroundMusic` - The background music that plays within an environment. + - `BedRule` - The rules of how beds function within an environment. + - `EnvironmentAttribute` - A definition of some attribute within an environment. + - `EnvironmentAttributeLayer` - A layer that modifies a value. + - `EnvironmentAttributeMap` - A map of attribute definitions to their argument and modifier. + - `EnvironmentAttributeProbe` - The attribute handler for getting and interpolating between values. Used only by the camera. + - `EnvironmentAttributeReader` - A reader that can lookup the environment attributes either by dimension or position. + - `EnvironmentAttributes` - A registry of all vanilla environment attributes. + - `EnvironmentAttributeSystem` - A reader implementation that gets and spatially interpolates environment attributes. + - `LerpFunction` - A functional interface that takes in some value between 0-1 along with the start and end values to interpolate between. + - `WeatherAttributes` - Attributes maps for applying weather layers. +- `net.minecraft.world.attribute.holder` + - `AttributeModifier` - A modifier that takes in the attribute value along with some argument (typically a value of the same type) to produce a modified value. + - `BooleanModifier` - Modifier for a boolean with a boolean argument. + - `ColorModifier` - Modifier for an ARGB integer with some argument, typically integers. + - `FloatModifier` - Modifier for a float with some argument, typical floats or a float with an alpha interpolator. + - `FloatWithAlpha` - A record containing some value and an alpha typically used for blending. +- `net.minecraft.world.entity.ai.Brain` + - `getSchedule` is removed + - `setSchedule` now takes in an `EnvrionmentAttribute` instead of a `Schedule` + - `updateActivityFromSchedule` now takes in the `EnvironmentAttributeSystem` and position instead of the day time +- `net.minecraft.world.entity.animal.bee.Bee#isNightOrRaining` replaced with `EnvironmentAttributes#BEES_STAY_IN_HIVE` +- `net.minecraft.world.entity.player.Player$BedSleepingProblem` is now a record + - `NOT_POSSIBLE_HERE` -> `BedRule#EXPLODES` + - `NOT_POSSIBLE_NOW` -> `BedRule#CAN_SLEEP_WHEN_DARK` +- `net.minecraft.world.entity.schedule` + - `Keyframe` -> `.minecraft.util.Keyframe`, not one-to-one + - `Schedule` is removed, its logic replaced by `Timeline`, `Timelines` + - `ScheduleBuilder` is remvoed, its logic replaced by `Timeline$Builder` + - `Timeline` -> `.world.timeline.Timeline`, not one-to-one +- `net.minecraft.world.entity.variant.SpawnContext` now takes in the `EnvironmentAttributeReader` +- `net.minecraft.world.level` + - `Level` + - `isMoonVisible` replaced by `EnvironmentAttributes#MOON_ANGLE` + - `getSunAngle` replaced by `EnvironmentAttributes#SUN_ANGLE` + - `canHaveWeather` is now `public` + - `LevelAccessor` now implements `LevelReader` instead of `LevelTimeAccess` + - `LevelReader#environmentAttributes` - Returns the manager for get the environment attribute within a dimension and its associated biomes. + - `LevelTimeAccess` interface is removed + - `MoonPhase` + - `CODEC` - The codec for the moon phase. + - `PHASE_LENGTH` - The number of ticks that a moon phase is present for. + - `startTick` - The start tick for a particular phase. +- `net.minecraft.world.level.biome` + - `AmbientAdditionsSettings` -> `.world.attribute.AmbientAdditionsSettings` + - `AmbientMoodSettings` -> `.world.attribute.AmbientMoodSettings` + - `AmbientParticleSettings` -> `.world.attribute.AmbientParticle` + - `Biome` now takes in the `EnvironmentAttributeMap` + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR` + - `getFogColor` -> `EnvironmentAttributes#FOG_COLOR` + - `getAttributes` - Gets the attributes for this biome. + - `getWaterFogColor` -> `EnvironmentAttributes#WATER_FOG_COLOR` + - `getAmbientParticle` -> `EnvironmentAttributes#AMBIENT_PARTICLES` + - `getAmbientLoop` -> `AmbientSounds#loop` environment attribute + - `getAmbientMood` -> `AmbientSounds#mood` environment attribute + - `getAmbientAdditions` -> `AmbientSounds#additions` environment attribute + - `getBackgroundMusic` -> `EnvironmentAttributes#BACKGROUND_MUSIC` + - `getBackgroundMusicVolume` -> `EnvironmentAttributes#MUSIC_VOLUME` + - `$Builder` + - `putAttributes` - Puts all attributes from another map. + - `setAttribute` - Sets an environment attribute. + - `modifyAttribute` - Modifies an attribute source for the biome. + - `BiomeSpecialEffects` is now a record + - `getFogColor` -> `EnvironmentAttributes#FOG_COLOR` + - `getWaterFogColor` -> `EnvironmentAttributes#WATER_FOG_COLOR` + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR` + - `getAmbientParticleSettings` -> `EnvironmentAttributes#AMBIENT_PARTICLES` + - `getAmbientLoopSoundEvent` -> `AmbientSounds#loop` environment attribute + - `getAmbientMoodSettings` -> `AmbientSounds#mood` environment attribute + - `getAmbientAdditionsSettings` -> `AmbientSounds#additions` environment attribute + - `getBackgroundMusic` -> `EnvironmentAttributes#BACKGROUND_MUSIC` + - `getBackgroundMusicVolume` -> `EnvironmentAttributes#MUSIC_VOLUME` +- `net.minecraft.world.level.block` + - `BedBlock#canSetSpawn` -> `BedRule#canSetSpawn` environment attribute + - `CreakingHeartBlock#isNaturalNight` replaced by `EnvironmentAttributes#CREAKING_ACTIVE` + - `RespawnAnchorBlock#canSetSpawn` now takes in the `ServerLevel` and `BlockPos` +- `net.minecraft.world.level.dimension` + - `BuiltinDimensionTypes#*_EFFECTS` are removed + - `DimensionDefaults#OVERWORLD_CLOUD_HEIGHT` is now a `float` + - `DimensionType` + - `fixedTime` -> `hasFixedTime`, now a `boolean` instead of a `OptionalLong` + - `natural`, `effectsLocation` are removed + - `skybox` - The skybox to display within the dimension. + - `cardinalLightType` - The type of light permeating through a dimension. + - `timelines` - A set of timelines that modify the environment attributes of this dimension. + - `ultraWarm` -> `EnvironmentAttributes#WATER_EVAPORATES`, `FAST_LAVA`, `DEFAULT_DRIPSTONE_PARTICLE` + - `bedWorks` -> `EnvironmentAttributes#BED_RULE` + - `respawnAnchorWorks` -> `EnvironmentAttributes#RESPAWN_ANCHOR_WORKS` + - `cloudHeight` -> `EnvironmentAttributes#CLOUD_HEIGHT` + - `attribute` - Gets the attributes for this dimension. + - `piglinSafe`, `$MonsterSettings#piglinSafe` -> `EnvironmentAttributes#PIGLINS_ZOMBIFY` + - `hasRaids`, `$MonsterSettings#hasRaids` -> `EnvironmentAttributes#CAN_START_RAID` + - `timeOfDay` is removed + - `moonPhase` replaced by `EnvironmentAttributes#MOON_PHASE` + - `hasEndFlashes` - Returns whether the skybox is the end. + - `$CardinalLightType` - The light permeating through a dimension. + - `$Skybox` - The skybox of a dimension. +- `net.minecraft.world.level.material.FogType#DIMENSION_OR_BOSS` is removed +- `net.minecraft.world.timeline` + - `AttributeTrack` - A track that applies the attribute modifier with the argument sampled from the given keyframe track. + - `AttributeTrackSampler` - A baked attribute track. + - `Timeline` - A map of attributes to tracks that are applied based on the given time in ticks modulo the period. + - `Timelines` - All vanilla timelines. + +## The Game Rule Shuffle + +The gamerule system has been overhauled to a degree, allowing its keys to be stored as proper registry objects while still having its values limited to either integers or booleans. Most of the classes are basically just combinations of others. + +### Existing Game Rules + +Existing game rules are still in a `GameRules` class, just moved to a different location. Their fields have been renamed and seem to follow some basic rules: + +1. Rules no longer have the `RULE_` prefix +1. Rules now have underscores separating words +1. The `DO` prefix is removed from rule names (e.g. `RULE_DOENTITYDROPS` -> `ENTITY_DROPS`) +1. The `SPAWNING` suffix has been replaced with the `SPAWN_` prefix (e.g. `RULE_DOMOBSPAWNING` -> `SPAWN_MOBS`) +1. The `DISABLE` prefix is removed, meaning that their values are inverted (e.g., `RULE_DISABLERAIDS` -> `RAIDS`) + +While there are some edge cases, searching for a specific word in the previous game rule name will most likely lead you to the new name (e.g., searching for `ADVANCEMENT` in `RULE_ANNOUNCEADVANCEMENTS` leads to `SHOW_ADVANCEMENT_MESSAGES`). + +To actually get a value from the game rules, you would use `GameRules#get` instead of the previous `getBoolean` and `getInteger`. The type is obtained from the generic on the registered `GameRule`. + +```java +// With ServerLevel level +boolean fallDamage = level.getGameRules().get(GameRules.FALL_DAMAGE); +``` + +Additionally, setting the game rule is now simplified to calling `GameRules#set` -- taking in the `GameRule`, value, and the current server if the changes are propogated through `MinecraftServer#onGameRuleChanged`, which it should generally be. + +```java +// With ServerLevel level +level.getGameRules().set(GameRules.FALL_DAMAGE, false, level.getServer()); +``` + +### Creating a Game Rule + +Game rules are created through the `GameRule` class, which is basically a type definition of how the game rule functions depending on its caller. Its generic represents the type of the value being held. The only hardcoded concepts that separate this from being a general type is that the actual arguments can be limited to a specific range, and that they store the default value. Otherwise, the fields are mostly the same from its previous counterparts in `GameRules$Type` and `GameRules$Key`. + +Then, once created, the `GameRule` must be statically registered to `BuiltInRegistries#GAME_RULE` + +```java +public static final GameRule EXAMPLE_RULE = Registry.register( + BuiltInRegistries.GAME_RULE + Identifier.withNamespaceAndPath("examplemod", "example_rule"), + new GameRule( + // The category that best represents the game rule. + // This is only used by the edit game rule screen + // when first constructing the world. + // A custom category can be created by calling + // `GameRuleCategory#register` or just its constructor + // as the sort order goes unused + GameRuleCategory.register( + Identifier.withNamespaceAndPath("examplemod", "example_category") + ), + // The type of the game rule, represenative of the + // JSON schema version of the generic. + // This is only used by the management system for + // checking an untyped rule. + GameRuleType.INT, + // The argument type used for serializing the value + // in commands. + // This can be range-limited based on the constructor. + IntegerArgumentType.integer(0, 5), + // A caller that runs typically during the visiting process + // for each game rule. + // This caller is only used by the edit game rules screen + // for adding the correct component that modifies the value. + // `GameRuleTypeVisitor#visit` should not be used here + // as the visitor already calls that function. + GameRuleTypeVisitor::visitInteger, + // The codec used to serialize the game rules to disk + // or for the managment service. + // This can be range-limited based on the constructor. + Codec.intRange(0, 5), + // A function that maps the set value to an integer + // result used when setting or querying the game rule + // via a command. + // This is the only case when a result of `0` does not + // mean the command has failed. + gameRuleValue -> gameRuleValue, + // The default value to set for this rule. + 3, + // A feature flag set that are required for this game rule + // to be enabled in game. + // An empty flag set means it should be enabled at all times. + FeatureFlagSet.of() + ) +); +``` + +`net.minecraft.client.gui.screens.worldselection` + - `EditGameRulesScreen` + - `$BooleanRuleEntry` now takes in a `GameRule` instead of a `GameRules$BooleanValue` + - `$EntryFactory` no longer bounds its generic + - `$IntegerRuleEntry` now takes in a `GameRule` instead of a `GameRules$IntegerValue` + - `InitialWorldCreationOptions#disabledGameRules` is now a `GameRuleMap` +- `net.minecraft.core.registries.BuiltInRegistries#GAME_RULE`, `Registries#GAME_RULE` - Game rule registry. +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` + - `$SetGameRules` now takes in a `GameRulesMap` instead of `$Entry`s + - `entry`, `$Entry` are removed +- `net.minecraft.server.MinecraftServer#onGameRuleChanged` now takes in the `GameRule` and value instead of the string key and `$Value` wrapper +- `net.minecraft.server.jsonrpc.api.Schema` + - `RULE_TYPE_SCHEMA` is now a `GameRuleType` instead of a `GameRulesService$RuleType` + - `TYPED_GAME_RULE_SCHEMA` is now a `GameRulesService$GameRuleUpdate` instead of a `GameRulesService$TypedRule` + - `UNTYPED_GAME_RULE_SCHEMA` is now a `GameRulesService$GameRuleUpdate` instead of a `GameRulesService$UntypedRule` +- `net.minecraft.server.jsonrpc.internalapi` + - `GameRules` interface is removed + - `MinecraftGameRuleService#getRule` -> `getRuleValue` +- `net.minecraft.server.jsonrpc.methods.GameRulesService` + - `$RuleType` is removed + - `$TypedRule`, `$UntypedRule` -> `$GameRuleUpdate`, not one-to-one +- `net.minecraft.server.notifications.NotificationService#onGameRuleChanged` now takes in the `GameRule` and value instead of the string key and `$Value` wrapper +- `net.minecraft.world.level.GameRules` + - The static rule keys are now located in `.gamerules.GameRules` without the `RULE_` prefix and underscores in-between words + - `DO` is removed from the name (e.g. `RULE_DOENTITYDROPS` -> `ENTITY_DROPS`) + - `SPAWNING` names now start with `SPAWN_` (e.g. `RULE_DOMOBSPAWNING` -> `SPAWN_MOBS`) + - The map behavior linking the key to its associated value is now handled by `GameRuleMap` + - `getBoolean`, `getInteger` -> `get` + - `$Key`, `$Type` -> `GameRule`, not one-to-one + - `GameRule` implements `FeatureElement` + - `$Category` -> `GameRuleCategory`, not one-to-one + - `$Value`, `$BooleanValue`, `$IntegerValue` are removed, replaced with the direct object being wrapped + - `$GameRuleTypeVisitor` -> `GameRuleTypeVisitor` + +## 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. + +### Usage Annotations + +Mojang has recently given some integer values and flags an annotation, marking its intended usage. This does not affect modders in any way, as it likely seems to be a way to perform static analysis on the values passed around, probably for some kind of validation. + +- `com.mojang.blaze3d.buffers.GpuBuffer$Usage` - An annotation that marks whether a given integer defines the usage flags of the particular buffer. +- `com.mojang.blaze3d.platform.InputConstants$Value` - An annotation that marks whether a given integer defines the input of a device. +- `com.mojang.blaze3d.buffers.GpuTexture$Usage` - An annotation that marks whether a given integer defines the usage flags of the particular texture. +- `net.minecraft.client.input` + - `InputWithModifiers$Modifiers` - An annotation that marks whether a given integer defines the modifiers of an input. + - `KeyEvent$Action` - An annotation that marks whether a given integer defines the action being performed by the input (i.e., press, release, repeat). + - `MouseButtonInfo` + - `$Action` - An annotation that marks whether a given integer defines the action being performed by the mouse (i.e., press, release, repeat). + - `$MouseButton` - An annotation that marks whether a given integer defines the input of a mouse. +- `net.minecraft.server.level.TicketType$Flags` - An annotation that marks whether a given integer defines the flags of a ticket type. +- `net.minecraft.world.level.block.Block$UpdateFlags` - An annotation that marks whether a given integer defines the flags for a block update. + +### Text Collectors + +`ActiveTextCollector` is a method of submitting strings and components to render, meant to provide common utilities for alignment, especially with text that goes off the screen. While this does not necessarily replace `GuiGraphics#drawString`, a few widgets require the use of the `ActiveTextCollector`, such as `AbstractStringWidget#renderLines`. + +An `ActiveTextCollector` can be created by calling one of the `GuiRenderer#textRenderer*` methods. They take in a `$HoveredTextEffects`, which handles how to render the component hover and click event, and a `Style` consumer callback for any additional handling. It also stores a set of default parameters, which basically represent the current pose opacity and screen rectangle. + +There are two methods two submit a piece of text for rendering: `accept` for standard strings, and `acceptScrolling*` for screens that go out of the rectangle, scrolling back and forth on the screen at a rate of roughly one unit per second (see the accessibility settings for an example). `accept` takes in, at most, five parameters: the alignment of the X position (`TextAlignment#LEFT` is like normal, `CENTER` the center of the text, `RIGHT` the end of the text), the X position for the alignment, Y position, parameters to override, and the text. `acceptScrolling` takes in, at most, seven parameters: the text, the starting X position center aligned, the leftmost X position, the rightmost X position, the topmost Y position, the bottommost Y position, and the parameters to override. + +```java +// In some method with GuiGraphics graphics +ActiveTextCollector collector = graphics.textRenderer( + // Render hover and click events + HoveredTextEffects.TOOLTIP_AND_CURSOR; +); + +collector.accept( + // Align the text to the center + TextAlignment.CENTER, + // Start X (in this case the center position) + 20, + // Start Y + 0, + // The parameters to use + collector.defaultParameters(), + // The text to display + Component.literal("Hello world!") +); +``` + +- `net.minecraft.client.gui` + - `ActiveTextCollector` - A helper for rendering text with certain parameters and alignments. + - `GuiGraphics` now takes in the mouse XY + - `textRenderer*` - Methods for constructing the helper for submit text in their appropriate location. + - `$HoveredTextEffects` - An enum that defines the text effects to apply when using the text collector. +- `net.minecraft.client.gui.components` + - `AbstractButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `renderWidget` is now final + - Use `renderContents` instead to submit elements + - `renderDefaultSprite` should be called in `renderContents` to blit the default sprite + - `renderString` -> `renderDefaultLabel`, not one-to-one + - `AbstractSliderButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `AbstractStringWidget` + - `visitLines` - Handles submitting text elements to the screen. + - `setColor`, `getColor` are removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `setComponentClickHandler` - Set the handler for when a component with the provided style is clicked. + - `AbstractWidget` + - `renderScrollingString` -> `renderScrollingStringOverContents`, not one-to-one + - `getAlpha` - Gets the alpha of the widget. + - `$WithInactiveMessage` - A widget that can change the message to display when inactive. + - `Button` is now abstract + - `$Plain` replicates the previous behavior + - `ChatComponent` + - `MESSAGE_BOTTOM_TO_MESSAGE_TOP` - The height of a chat component. + - `render` now takes in a `Font` and a `boolean` for whether to change the curse on insertions + - `captureClickableText` - Captures the clickable text to submit. + - `handleChatQueueClicked` replaced by `QUEUE_EXPAND_ID`, not one-to-one + - `getClickedComponentStyleAt` -> `$ChatGraphicsAccess#handleMessage`, not one-to-one + - `getMessageTagAt` -> `$ChatGraphicsAccess#handleTag`, `handleTagIcon`; not one-to-one + - `getWidth`, `getHeight`, `getScale` are now private + - `$AlphaCalculator` - Calculates the alpha for a given chat line. + - `$ChatGraphicsAccess` - An interface for handling the submission of the chat input. + - `$LineConsumer` no longer takes in the first three `int`s + - `FittingMultilineTextWidget#setColor` is removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `MultiLineLabel` + - `render`, `getStyle` -> `visitLines`, not one-to-one + - `$Align` -> `TextAlignment` + - `MultiLineTextWidget#setColor`, `configureStyleHandling` are removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `SplashRenderer` now takes in a `Component` instead of a `String` + - `SpriteIconButton#renderSprite` - Submits the sprite icon. + - `StringWidget#setColor` is removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `TabButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `renderString` -> `renderLabel`, now private, not one-to-one +- `net.minecraft.client.gui.screens.inventory.BookViewScreen#getClickedComponentStyleAt` -> `visitText`, now private, not one-to-one + +### Shared Text Areas Debugger + +A new debug has been added that draws the bounding box each glyph, including the empty glyph. The color shifts slightly between each glyph for ease of differentiation, and changes entirely depending on if there is some combination of a click or hover event. + +- `net.minecraft.SharedConstants#DEBUG_ACTIVE_TEXT_AREAS` - A flag for the debugger drawing the bounds and effects of each glyph. +- `net.minecraft.client.gui.Font` + - `prepareText` now has an overload of whether to render something in the empty areas + - `$GlyphVisitor` + - `acceptGlyph` now takes in a `TextRenderable$Styled` instead of a `TextRenderable` + - `acceptEmptyArea` - Accepts an empty area to draw to the screen. + - `$PreparedTextBuilder` now takes in whether to include the empty areas for rendering +- `net.minecraft.client.gui.font` + - `ActiveArea` - Defines the bounds and style of the area to draw. + - `EmptyArea` - An area with nothing within it. + - `PlainTextRenderable` now implements `TextRenderable$Styled` instead of `TextRenderable` + - `width`, `height`, `ascent` - The bounds of the object. + - `TextRenderable$Styled` - A text renderable that defines some active area for its bounds. +- `net.minecraft.client.gui.font.glyphs.BakedGlyph#createGlyph` now returns a `TextRenderable$Styled` + +### JSpecify Annotations + +Mojang has moved from using a mix of their own annotations to those available in JSpecify when required. As such, instead of all fields, methods, and parameters being marked as nonnull by default, it is replaced by `NullMarked`, which considers a type usage non-null unless explictly annotated as `Nullable`, barring some special cases. + +- `com.mojang.blaze3d.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed +- `com.mojang.math.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed +- `net.minecraft.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed + +### Slot Sources + +Slot sources are an expansion upon the previous contents drop system in shulker boxes allowing any loot table to pulls its entries from some container slots. This can be used in any location where a `LootContext` is enabled, though it is currently only implemented as a loot pool entry. + +In vanilla, a slot source works by having some `LootContextArg`, which points to some loot context param value, return an object that implements `SlotProvider`. Currently, this refers to any `Container` or `Entity` implementation. The `SlotProvider` is then used by `SlotSource#provide` to construct a `SlotCollection`: a stream of deep copied `ItemStack`s. The stacks stored in the collection are then passed to the output of the pool. As this is all done in one of the `SlotSource#provide` implementations, it can reference anything (not just `SlotProvider`) as long as it can transform that data into the `SlotCollection`. + +```java +// A slot source whose 'slots' are the elements +// within an item tag. +public record TagSlotSource(TagKey tag) implements SlotSource { + + public static final MapCodec MAP_CODEC = TagKey.codec(Registries.ITEM) + .fieldOf("tag").xmap(TagSlotSource::new, TagSlotSource::tag); + + @Override + public SlotCollection provide(LootContext ctx) { + // Get the holder set for the tag + Optional> holderSetOpt = ctx.getResolver() + .lookup(Registries.ITEM).flatMap(getter -> getter.get(this.tag)); + + // Stream the elements and map to a SlotCollection + return holderSetOpt.map(holderSet -> + // `Item#getDefaultInstance` returns a new copy, so it can be used. + // If the ItemStack already exists, then `ItemStack#copy` should be + // called on each. + (SlotCollection) () -> holderSet.stream().map(holder -> holder.value().getDefaultInstance()) + ).orElse(SlotCollection.EMPTY); + } + + @Override + public MapCodec codec() { + // The codec used to serialize the slot source + return MAP_CODEC; + } +} + +// The map codec needs to be registered to the slot source type registry +Registry.register( + BuiltInRegistries.SLOT_SOURCE_TYPE + Identifier.withNamespaceAndPath("examplemod", "tag"), + TagSlotSource.MAP_CODEC +); +``` + +```json5 +// An example loot table +{ + // ... + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + // Use the slot source loot pool + "type": "minecraft:slots", + "slot_source": { + // Our slot source + "type": "examplemod:tag", + "tag": "minecraft:planks" + } + } + ] + } + // ... + ] +} +``` + +- `net.minecraft.advancements.criterion.SlotsPredicate#matches` now takes in a `SlotProvider` instead of an `Entity` +- `net.minecraft.core.registries.BuiltInRegistries#SLOT_SOURCE_TYPE`, `Registries#SLOT_SOURCE_TYPE` - Slot source type registry. +- `net.minecraft.world.Container` now extends `SlotProvider` + - `getSlot` - Gets an access for a single item. +- `net.minecraft.world.entity` + - `Entity` now implements `SlotProvider` + - `SlotAccess` + - `NULL` is removed + - `forContainer` -> `forListElement`, not one-to-one + - `SlotProvider` - An object that provides some access to its internal storage via slots. +- `net.minecraft.world.item.slot` + - `CompositeSlotSource` - A composite of multiple slot sources. + - `ContentsSlotSource` - Gets the slot contents. + - `EmptySlotSource` - An empty slot source. + - `FilteredSlotSource` - Filters the provided slot source pased on the item predicate. + - `GroupSlotSource` - Groups multiple slot sources together into one concatenated collection. + - `LimitSlotSource` - Limits the provided slot source to a maximum size. + - `RangeSlotSource` - Gets the desired range of slots. + - `SlotCollection` - A collection of slots to grab the item copies from. + - `SlotSource` - Given a loot context, returns a collection of slots to provide. + - `SlotSources` - The slot sources provided by vanilla. + - `TransformedSlotSource` - Transforms the provided slot source. +- `net.minecraft.world.level.storage.loot.ContainerComponentManipulator#getSlots` - Gets the slots of a data component on the stack. +- `net.minecraft.world.level.storage.loot.entries` + - `LootPoolEntries#SLOTS` - A pool that uses slots from a source. + - `SlotLoot` - A pool that gets its items from some slot source. + +### Zombie Nautilus Variant + +Zombie nautilus are the newest addition to the variant datapack registry objects, taking in the familiar model and texture override along with the spawn conditions: + +```json5 +// A file located at: +// - `data/examplemod/zombie_nautilus_variant/example_zombie_nautilus.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/nautilus/example_zombie_nautilus.png` + "asset_id": "examplemod:entity/nautilus/example_zombie_nautilus", + // Defines the `ZombieNautilusVariant$ModelType` that's used to select what entity model to render the zombie nautilus variant with + "model": "warm", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +- `net.minecraft.core.component.DataComponents#ZOMBIE_NAUTILUS_VARIANT` - The variant of the zombie nautilus. +- `net.minecraft.core.registries.Registries#ZOMBIE_NAUTILUS_VARIANT` - The registry key for the zombie nautilus variant. +- `net.minecraft.network.syncher.EntityDataSerializers#ZOMBIE_NAUTILUS_VARIANT` - The variant of the zombie nautilus. +- `net.minecraft.world.entity.animal.nautilus` + - `ZombieNautilusVariant` - A variant of a zombie nautilus. + - `ZombieNautilusVariants` - All vanilla zombie nautilus variants. + +### `OptionEnum` Removal + +`OptionEnum` has been removed in favor of simply calling the `OptionInstance$Enum` constructor with the desired values and codec. As such, most `byId` methods have been replaced with some codec and the translatable entry is now stored as a `Component` than the translation key string. + +- `net.minecraft.client` + - `AttackIndicatorStatus` no longer implements `OptionEnum` + - `byId` -> `LEGACY_CODEC`, not one-to-one + - `getKey` -> `caption`, not one-to-one + - `CloudStatus` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `InactivityFpsLimit` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `OptionInstance#forOptionEnum` is removed + - `PrioritizeChunkUpdate` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `byId` -> `LEGACY_CODEC`, not one-to-one +- `net.minecraft.client.sounds.MusicManager$MusicFrequency` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one +- `net.minecraft.server.level.ParticleStatus` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `byId` -> `LEGACY_CODEC`, not one-to-one +- `net.minecraft.util.OptionEnum` is removed +- `net.minecraft.world.entity.HumanoidArm` no longer implements `OptionEnum` + - `BY_ID` is now private + - `getKey` -> `caption`, not one-to-one +- `net.minecraft.world.entity.player.ChatVisbility` no longer implements `OptionEnum` + - `byId` -> `LEGACY_CODEC`, not one-to-one + - `getKey` -> `caption`, not one-to-one + +### Specific Logic Changes + +- `net.minecraft.client.renderer.entity.EntityRenderState#lightCoords` now defaults to 0xF000F0. +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen#keyPressed` no longer returns `true` if the key is not handled by the screen, instead returning `false`. +- `net.minecraft.util.Mth#clampedLerp` parameters have been reordered for both overloads. The methods now take in the step, the original value, and the next value; instead of the original value, next value, and the step value. + +### Tag Changes + +- `minecraft:biome` + - `plays_underwater_music` is removed + - Replaced by `BackgroundMusic#underwaterMusic` environment attribute + - `has_closer_water_fog` is removed + - Replaced by `EnvironmentAttributes#WATER_FOG_END_DISTANCE` + - `increased_fire_burnout` is removed + - Replaced by `EnvironmentAttributes#INCREASED_FIRE_BURNOUT` + - `snow_golem_melts` is removed + - Replaced by `EnvironmentAttributes#SNOW_GOLEM_MELTS` + - `without_patrol_spawns` is removed + - Replaced by `EnvironmentAttributes#CAN_PILLAGER_PATROL_SPAWN` + - `spawns_coral_variant_zombie_nautilus` +- `minecraft:block` + - `can_glide_through` +- `minecraft:entity_type` + - `burn_in_daylight` + - `can_float_while_ridden` + - `can_wear_nautilus_armor` + - `nautilus_hostiles` +- `minecraft:item` + - `camel_husk_food` + - `zombie_horse_food` + - `nautilus_bucket_food` + - `nautilus_food` + - `nautilus_taming_items` + - `spears` + - `enchantable/lunge` + - `enchantable/sword` -> `enchantable/melee_weapon`, `enchantable/sweeping` +- `minecraft:timeline` + - `universal` + - `in_overworld` + - `in_nether` + - `in_end` + +### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds#isAmd` - Whether the GPU's vendor is AMD. +- `com.mojang.blaze3d.opengl` + - `GlConst#GL_POINTS` - Defines the points primitive as the type to render. + - `GlTimerQuery` - The OpenGL implementation of querying an object, typically the time elapsed. +- `com.mojang.blaze3d.platform.InputConstants#MOUSE_BUTTON_*` - The inputs of a mouse click, represented by numbers as they may have different intended purposes. +- `com.mojang.blaze3d.systems` + - `CommandEncoder#timerQueryBegin`, `timerQueryEnd` - Handlers for keeping track of the time elapsed. + - `GpuQuery` - A query for an arbitrary object, such as the time elapsed. +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat` + - `POSITION_COLOR_LINE_WIDTH` - A vertex format that specifies the position, color, and line width. + - `POSITION_COLOR_NORMAL_LINE_WIDTH` - A vertex format that specifies the position, color, normal, and line width. + - `VertexFormat$Mode#POINTS` - A vertex mode that draws points. + - `VertexFormatElement#LINE_WIDTH` - A vertex element that takes in one float representing the width. +- `com.mojang.math` + - `OctahedralGroup` + - `BLOCK_ROT_*` - Constants representing the block rotations. + - `permutation` - Returns the symmetric group. + - `Quadrant#fromXYZAngles` - Gets the octahedral group that represents the three quadrant rotations. + - `SymmetricGroup3#inverse` - Returns the inverse group. +- `net.minecraft` + - `SharedConstants` + - `MAX_CLOUD_DISTANCE` - The maximum cloud range to be rendered by the player. + - `DEFAULT_RANDOM_TICK_SPEED` - The default random tick speed. + - `Util#localizedDateFormatter` - Returns the localized `DateTimeFormatter` for the given style. +- `net.minecraft.advancements.criterion` + - `DataComponentMatchers$Builder#any` - Matches whether there exists some data for the component. + - `SpearMobsTrigger` - A trigger that checks the number of entities the player has speared with a kinetic weapon. +- `net.minecraft.client` + - `GuiMessage` + - `splitLines` - Splits the component into lines with the desired width. + - `getTagIconLeft` - Gets the width of the content with an additional four pixel padding. + - `KeyMapping$Category#DEBUG` - The debug keyboard category. + - `MusicToastDisplayState` - An enum representing how the toast for music should be displayed. + - `NarratorStatus#LEGACY_CODEC` - A codec to deserialize the enum narrator status. + - `OptionInstance` + - `$IntRangeBase` + - `next` - Gets the next value. + - `previous` - Gets the previous value. + - `$SliderableEnum` - A slider that selects between enum options. + - `$SliderableValueSet` + - `next` - Gets the next value. + - `previous` - Gets the previous value. + - `Options` + - `keyToggleGui` - A key mapping that toggles the in-game gui. + - `keyToggleSpectatorShaderEffects` - A key mapping that toggles the shader effects tied to a camera entity. + - `keyDebug*`, `debugKeys` - Key mappings for the debug renderers. + - `weatherRadius` - Returns the radius of the weather particles to render in an area. + - `cutoutLeaves` - Whether leaves should render in cutout or solid. + - `vignette` - Whether a vignette should be applied to the screen. + - `improvedTransparency` - Whether to use the transparency post processor. + - `chunkSectionFadeInTime` - The amount of second that should be taken for a chunk to fade in when first rendered. + - `maxAnisotropyBit` - The bit value of the anisotrophic filtering level. + - `maxAnisotropyValue` - The ansiotrophic filtering level. +- `net.minecraft.client.animation.definitions.NautilusAnimation` - The animation definitions for the nautilus. +- `net.minecraft.client.data.models.ItemModelGenerators` + - `generateSpear` - Generates the spear item model. + - `generateItemWithTintedBaseLayer` - Generates a two layered item model whose base layer is tinted. +- `net.minecraft.client.data.models.model.ModelTemplates#SPEAR_IN_HAND` - A template for the spear in hand model. +- `net.minecraft.client.gui.components` + - `AbstractButton#setOverrideRenderHighlightedSprite` - Overrides whether to use the focused enabled/disabled sprite. + - `Checkbox#adjustWidth` - Sets the width of the widget using the message, font, and its initial X position. + - `CycleButton` + - `$Builder#withSprite` - Sets the supplier used to get the sprite based on the current button state. + - `$DisplayState` - How the button shoud be displayed. + - `$SpriteSupplier` - Gets the sprite location given the current button state. + - `EditBox#setInvertHighlightedTextColor` - Sets whether to invert the highlighted text color. + - `FocusableTextWidget` + - `getPadding` - Returns the text padding. + - `updateWidth` - Updates the width the text can take up. + - `updateHeight` - Update the height the text can take up. + - `$Builder` - Builds the component. + - `MultiLineTextWidget#getTextX`, `getTextY` - Gets the text position. + - `OptionsList` + - `addHeader` - Adds a header entry. + - `resetOption` - Resets the option value. + - `$AbstractEntry` - Defines the element within the selection list. + - `$HeaderEntry` - An entry that represents the header of a section. + - `$OptionInstanceWidget` - A record containing the widget and optionally the option instance. + - `ResettableOptionWidget` - A widget that can reset its value to a default. + - `SelectableEntry` - A utility for checking whether the mouse is in a specific region. +- `net.minecraft.client.gui.layouts.HeaderAndFooterLayout#MAGIC_PADDING` - A common padding between the elements. +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementTab#canScrollHorizontally`, `canScrollVertically` - Checks whether the tab data can be scrolled in a given direction. + - `AdvancementTabType#getWidth`, `getHeight` - Gets the width / height of the tab. +- `net.minecraft.client.gui.screens.debug.DebugOptionsScreen#getOptionList` - Returns the list of options for the debug screen. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractMountInventoryScreen` - A screen representing a mount's inventory. + - `EffectsInInventory` + - `SPACING` - The spacing between effects. + - `SPRITE_SQUARE_SIZE` - The size of the effect icon. + - `NautilusInventoryScreen` - The screen for the nautilus inventory. +- `net.minecraft.client.gui.screens.options` + - `OptionsSubScreen#resetOption` - Resets the option value to its default. + - `VideoSettingsScreen#updateTransparencyButton` - Sets the transparency button to the current option value. +- `net.minecraft.client.gui.screens.packs.TransferableSelectionList$PackEntry#ICON_SIZE` - The size of the pack icon. +- `net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton#select`, `unselect` - Handles tab display selection. +- `net.minecraft.client.input.InputQuirks#EDIT_SHORTCUT_KEY_LEFT`, `EDIT_SHORTCUT_KEY_RIGHT` -> `InputWithModifiers#hasControlDownWithQuirk`, not one-to-one +- `net.minecraft.client.model.HumanoidModel$ArmPose` + - `SPEAR` - The spear third person arm pose. + - `animateUseItem` - Modifies the `PoseStack` given the entity state, use time, arm, and stack. + - `affectsOffhandPose` - Whether the arm animation will affect the offhand pose. +- `net.minecraft.client.model.animal.nautilus` + - `NautilusArmorModel` - The armor model for a nautilus. + - `NautilusModel` - The model for a nautilus. + - `NautilusSaddleModel` - The saddle model for a nautilus. +- `net.minecraft.client.model.effects.SpearAnimations` - The animations performed when using a spear. +- `net.minecraft.client.model.geom` + - `ModelLayers` + - `*NAUTILUS*` - The model layers for the nautilus. + - `UNDEAD_HORSE*_ARMOR` - The armor model layers for the undead horse. + - `PartName` + - `INNER_MOUTH`, `LOWER_MOUTH` - Part names for a mouth. + - `SHELL` - Part name for a shell. + - `*_CORAL*` - Part names for the corals on a zombie nautilus. +- `net.minecraft.client.model.geom.builders.UVPair#pack`, `unpack*` - Handles packing/unpacking of a UV into a `long`. +- `net.minecraft.client.model.monster.nautilus.ZombieNautilusCoralModel` - The model for the warm variant of a zombie nautilus. +- `net.minecraft.client.model.monster.skeleton.SkeletonModel#createSingleModelDualBodyLayer` - Creates a parched layer definition. +- `net.minecraft.client.multiplayer` + - `ClientPacketListener#hasClientLoaded` - Whether the client is loaded. + - `MultiPlayerGameMode#piercingAttack` - Initiates a lunging attack. +- `net.minecraft.client.player.LocalPlayer#raycastHitResult` - Gets the hit result for the camera entity for the given partial tick. +- `net.minecraft.client.renderer` + - `DynamicUniforms` + - `CHUNK_SECTION_UBO_SIZE` - The uniform buffer object size for the chunk section. + - `writeChunkSections` - Writes a varargs of chunk sections to the uniform storage. + - `$ChunkSectionInfo` - The dynamic uniform for the chunk section. + - `GameRenderer` + - `updateCamera` - Calls the setup function for the camera. + - `getPanoramicScreenshotParameters` - Get the screenshot parameters for panoramic mode. + - `PanoramicScreenshotParameters` - The screenshot parameters for panoramic mode. + - `Sheets#CELESTIAL_SHEET` - The atlas for the celestial textures. +- `net.minecraft.client.renderer.blockentity.BlockEntityWithBoundingBoxRenderer#STRUCTURE_VOIDS_COLOR` - The void color for a structure. +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher$RenderSection` + - `getVisibility` - Returns the current alpha of the chunk. + - `setFadeDuration` - Sets the amount of time it should take for a chunk to fade in. + - `setWasPreviouslyEmpty`, `wasPreviouslyEmpty` - Handles whether the section did not previously exist. +- `net.minecraft.client.renderer.entity` + - `CamelHuskRenderer` - The entity renderer for a camel husk. + - `CamelRenderer#createCamelSaddleLayer` - Creates the saddle layer for the camel. + - `NautilusRenderer` - The entity renderer for a nautilus. + - `ParchedRenderer` - The entity renderer for a parched. + - `ZombieNautilusRenderer` - The entity renderer for a zombie nautilus. +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` + - `swingAnimationType` - The animation to play when swinging their hand. + - `ticksUsingItem` - How many ticks the item has been used for. + - `getUseItemStackForArm` - Returns the held item stack based on the arm. + - `LivingEntityRenderState#ticksSinceKineticHitFeedback` - The amount of ticks since this entity was hit with a kinetic weapon. + - `NautilusRenderState` - The entity render state of a nautilus. + - `UndeadRenderState` - The entity render state for an undead humanoid. +- `net.minecraft.client.renderer.item.ItemModelResolver#swapAnimationScale` - Gets the scale of the swap animation for the stack. +- `net.minecraft.client.renderer.state.LevelRenderState#gameTime` - The current game time. +- `net.minecraft.client.resources.SplashManager` component fields - The components for the special messages. +- `net.minecraft.client.resources.model` + - `BlockModelRotation#IDENTITY` - The identity rotation. + - `EquipmentClientInfo#NAUTILUS_*` - The layers for the nautilus. +- `net.minecraft.core.Vec3i` + - `multiply` - Multiplies each component with a provided scalar. + - `toMutable` - Returns a mutable `Vector3i`. +- `net.minecraft.data.AtlasIds#CELESTIAL_SHEET` - The atlas for the celestial textures. +- `net.minecraft.data.recipes.RecipeProvider#waxedChiseled` - The recipe for a waxed chiseled block. +- `net.minecraft.gametest.framework.GameTestHelper#getAbsoluteDirection` - Returns the absolute direction from the test relative direction. +- `net.minecraft.nbt.NbtAccounter` + - `defaultQuota` - An accounter with a maximum of 2 MiB allocated. + - `uncompressedQuota` - An accounter with a maximum of 100 MiB allocated. +- `net.minecraft.network.chat.MutableComponent#withoutShadow`, `Style#withoutShadow` - Removes the drop shadow from the text. +- `net.minecraft.network.protocol.game.ServerboundPlayerActionPacket$Action#STAB` - The player performed the stab action. +- `net.minecraft.network.syncher.EntityDataSerializers#HUMANOID_ARM` - The main hand of the humanoid. +- `net.minecraft.resources.Identifier#toShortString` - Returns the string of the location. Namespace is omitted if `minecraft`. +- `net.minecraft.server` + - `MinecraftServer` + - `getServerActivityMonitor` - Returns the monitor that sends the server activity notification. + - `getStopwatches` - Returns a map of ids to timers. + - `ServerScoreboard#storeToSaveDataIfDirty` - Writes the data if dirty. +- `net.minecraft.server.commands.StopwatchCommand` - A command that starts or stops a stopwatch. +- `net.minecraft.server.dedicated.DedicatedServerProperties#managementServerAllowedOrigins` - The origins a request from the management server can come from. +- `net.minecraft.server.jsonrpc.OutgoingRpcMethods#SERVER_ACTIVITY_OCCURRED` - A request made from the minecraft server about server activity occurring. +- `net.minecraft.server.jsonrpc.api.Schema` + - `BOOL_OR_INT_SCHEMA` - A schema for a field that can be either a boolean or integer. + - `typedCodec` - Returns the codec for the schema. + - `info` - Returns a copy of the schema. +- `net.minecraft.server.level` + - `ChunkMap#getChunkDataFixContextTag` - Returns the datafix tag for the chunk data. + - `ServerLevel` + - `getDayCount` - Gets the number of days that has passed. + - `canSpreadFireAround` - Whether fire can spread at the given block position. +- `net.minecraft.server.network` + - `EventLoopGroupHolder` - A holder for managing the event loop and channels for communicating with some end, whether local or socket-based. + - `ServerGamePacketListenerImpl#resetFlyingTicks` - Resets how long the player has been flying. +- `net.minecraft.server.notifications` + - `NotificationService#serverActivityOccurred` - Notifies the management server that activity has occurred. + - `ServerActivityMonitor` - The monitor that sends the server activity notification +- `net.minecraft.util` + - `ARGB` + - `srgbToLinearChannel` - Converts the sRGB value into a linear color space. + - `linearToSrgbChannel` - Converts the linear value into a sRGB color space. + - `meanLinear` - Computes the mean using the linear color space for four values, then converting it back into sRGB. + - `addRgb` - Adds the RGB channels, using the alpha from the first value. + - `subtractRgb` - Subtracts the RGB channels, using the alpha from the first value. + - `multiplyAlpha` - Multiplies the alpha value into the provided ARGB value. + - `linearLerp` - Linearly interpolates the color by converting into the linear color space. + - `white`, `black` - Colors with the provided alpha. + - `alphaBlend` - Blends two colors along with their alpha value. + - `vector4fFromARGB32` - Converts an ARGB value to four floats. + - `Ease` - A utility full of easing functions. + - `ExtraCodecs` + - `NON_NEGATIVE_LONG`, `POSITIVE_LONG` - Longs with the listed constraints. + - `longRange` - A long codec that validates whether it is between the provided range. + - `STRING_RGB_COLOR`, `STRING_ARGB_COLOR` - A codec allowing for an (A)RGB value expressed in hex form as a string. + - `MAX_PROPERTY_NAME_LENGTH`, `MAX_PROPERTY_VALUE_LENGTH`, `MAX_PROPERTY_SIGNATURE_LENGTH`, `MAX_PROPERTIES` - Constants related to serializing the property map. + - `Mth` + - `cube` - Cubes a number. + - `chessboardDistance` - Computes the absolute maximum difference between two pairs of coordinates; the larger axis difference is returned. + - `SpecialDates` - A utility containing the dates that Mojang changes some behavior or rendering for. + - `TriState` + - `CODEC` - The codec for the tristate. + - `from` - Turns a boolean into a tristate. +- `net.minecraft.util.profiling.jfr.JvmProfiler#onClientTick` - Runs on client tick, taking in the current FPS. +- `net.minecraft.util.profiling.jfr.event.ClientFpsEvent` - An event that keeps track of the client FPS. +- `net.minecraft.util.profiling.jfr.stats.FpsStat` - A record containing the client FPS. +- `net.minecraft.world` + - `LockCode#canUnlock` - Whether the given player can unlock this code. + - `Stopwatch` - A record that holds the creation time and amount of time that has elapsed. + - `Stopwatches` - A tracker for starting, managing, and stopping stopwatches. +- `net.minecraft.world.effect` + - `MobEffects#BREATH_OF_THE_NAUTILUS` - Prevents the user from losing air underwater. + - `MobEffectUtil#shouldEffectsRefillAirsupply` - Whether the entity has an effect that refills the air supply while under a liquid. +- `net.minecraft.world.entity` + - `Entity` + - `getHeadLookAngle` - Calculates the view vector of the head rotation. + - `updateDataBeforeSync` - Updates the data stored in the entity before syncing to the client. + - `computeSpeed` - Computes last known speed and position of the entity. + - `getKnownSpeed` - Gets the last known speed of the entity. + - `hasMovedHorizontallyRecently` - If the last known speed's horizontal distance is larger than 0, more specifically the margin of error. + - `EntityProcessor` - A post processor for an entity when loading. + - `EntityEvent#KINETIC_HIT` - An event fired when an entity is hit with a kinetic weapon. + - `HumanoidArm#STREAM_CODEC` - The network codec for the arm enum. + - `LivingEntity` + - `DEFAULT_KNOCKBACK` - The default knockback applied to an entity on hit. + - `itemSwapTicker` - The amount of time taken when swapping items. + - `recentKineticEnemies` - The attackers that have recently attacked with a kinetic weapon. + - `lungeForwardMaybe` - Apply the lunge effects. + - `causeExtraKnockback` - Applies an multiplicative force to the knockback. + - `wasRecentlyStabbed`, `rememberStabbedEntity` - Handles enemies that were stabbed with a kinetic weapon. + - `stabAttack` - Handles when a mob is stabbed by this entity. + - `onAttack` - Handles when this entity has attacked another entity. + - `getTicksUsingItem` - Returns the number of ticks this item has been used for. + - `getTicksSinceLastKineticHitFeedback` - The number of ticks that has passed since this entity was last hit with a kinetic weapon. + - `shouldTravelInFluid` - If this entity should travel in the given fluid. + - `travelInWater` - Moves an entity as if they were in water. + - `Mob#sunProtectionSlot` - The equipment slot that protects the entity from the sun. + - `NeutralMob#level` - Returns the level the entity is in. + - `PlayerRideableJumping#getPlayerJumpPendingScale` - Returns the scalar to apply to the entity on player jump. +- `net.minecraft.world.entity.ai.attributes.Attributes#DEFAULT_ATTACK_SPEED` - The default attack speed. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `CHARGE_COOLDOWN_TICKS` - The number of cooldown ticks after a charge attack. + - `ATTACK_TARGET_COOLDOWN` - The number of cooldown ticks before attacking a target. +- `net.minecraft.world.entity.ai.sensing.TemptingSensor#forAnimal` - A sensor that special cases animal entities for check if the desired item is food. +- `net.minecraft.world.entity.animal.camel` + - `Camel` + - `getDashingSound`, `getDashReadySound` - Camel dashing sounds. + - `getStandUpSound`, `getSitDownSound` - Camel sit/stand sounds. + - `getSaddleSound` - Camel saddle sound. + - `CamelHusk` - The camel husk entity. +- `net.minecraft.world.entity.animal.equine.AbstractHorse#isMobControlled` - Whether a mob can control this horse. +- `net.minecraft.world.entity.animal.nautilus` + - `AbstractNautilus` - The core of the nautilus entity. + - `Nautilus` - The nautilus entity. + - `NautilusAi` - The brain of a nautilus. + - `ZombieNautilus` - The zombie nautilus entity. + - `ZombieNautilusAi` - The brain of a zombie nautilus. +- `net.minecraft.world.entity.decoration.HangingEntity#hasLevelCollision` - Whether this entity is colliding with a block or the border in a given bounds. +- `net.minecraft.world.entity.monster.skeleton.Parched` - The parched entity. +- `net.minecraft.world.entity.monster.zombie.Husk$HuskGroupData` - The group data for the husk. +- `net.minecraft.world.entity.player.Player` + - `cannotAttackWithItem` - Checks whether the player cannot attack with the item. + - `getItemSwapScale` - Returns the scalar to use for the item swap animation. + - `resetOnlyAttackStrengthTicker` - Resets the attack strength ticker. + - `openNautilusInventory` - Opens the inventory of the interacted nautilus. + - `applyPostImpulseGraceTime`, `isInPostImpulseGraceTime` - Handles the grace time between impulses. +- `net.minecraft.world.food.FoodData#hasEnoughFood` - Whether the current food level is greater than 6 hunger (or three full hunger bars). +- `net.minecraft.world.inventory` + - `AbstractMountInventoryMenu` - The inventory menu for a mount. + - `NautilusInventoryMenu` - The inventory menu of a nautilus. +- `net.minecraft.world.item` + - `HoneycombItem#WAXED_RECIPES` - A map of waxed block to their recipe categories and name. + - `Item$Properties` + - `spear` - Adds the spear components. + - `nautilusArmor` - Adds the nautilus armor components. + - `ItemStack#matchesIgnoringComponents` - Whether the stack matches ignoring all components that match the predicate. + - `ItemUseAnimation` + - `TRIDENT` - The trident use animation. + - `hasCustomArmTransform` - Whether the animation provides a custom transform to the arm. +- `net.minecraft.world.item.enchantment` + - `Enchantment#doLunge` - Applies the post piercing attack effect. + - `EnchantmentEffectComponents#POST_PIERCING_ATTACK` - The effect to apply after a piercing attack. + - `EnchantmentHelper#doLungeEffects` - Applies the effect on lunge. + - `LevelBasedValue$Exponent` - Applies an exponent given the base and power. +- `net.minecraft.world.item.enchantment.effects` + - `ApplyEntityImpulse` - An entity effect that adds an impulse in the direction of the look angle. + - `ApplyExhaustion` - An entity effect that applies food exhaustion to the player if they are using the enchanted item. + - `ScaleExponentially` - A value effect that multiplies the value by a number raised to some exponent. +- `net.minecraft.world.level` + - `Chunk#isValid` - Whether the chunk pos is within the maximum allowed coordinate world (within the 30 million block radius). + - `CollisionGetter` + - `noEntityCollision` - Whether the entity is not colliding with another entity in the given bounds. + - `noBorderCollision` - Whether the entity is not colliding with the world border in the given bounds. + - `Level#isInValidBounds` - Whether the block position is not outside the maximum allowed coordinate world (build height for Y axis, 30 million block radius for XZ axis). + - `MoonPhase` - An enum representing the phases of the moon. +- `net.minecraft.world.level.border.WorldBorder$MovingBorderExtent#getPreviousSize` - Gets the previous size of the border. +- `net.minecraft.world.level.chunk.storage` + - `IOWorker#STORE_EMPTY` - A supplied `null` tag. + - `LegacyTagFixer` - An interface that handles how to upgrade a tag, like for the chunk. + - `SimpleRegionStorage` + - `isOldChunkAround` - Whether the chunk from a previous version still exists in this version. + - `injectDatafixingContext` - When the context is not `null`, adds it to the given tag. + - `markChunkDone` - Marks a chunk as finished for upgrading to the current version. + - `chunkScanner` - Gets the access used to scan chunks. +- `net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler#LAST_MONOLYTH_STRUCTURE_DATA_VERSION` - Returns the last data version containing glitched monolyths. +- `net.minecraft.world.level.storage.loot.LootContextArg` - An argument for a loot context to query. +- `net.minecraft.world.level.storage.loot.functions.DiscardItem` - A loot function that discards the loot, returning an empty stack. +- `net.minecraft.world.phys.Vec3` + - `offsetRandomXZ` - Offsets the point by a random amount in the XZ direction. + - `rotation` - Computes the rotation of the vector. + - `applyLocalCoordinatesToRotation` - Adds the components relative to the current rotation of the vector. + - `isFinite` - Returns whether all components of the vector are finite (not NaN or infinity) values. +- `net.minecraft.world.scores` + - `Scoreboard` + - `packPlayerTeams` - Packs the player teams into a serializable format. + - `packObjectives` - Packs the objectives into a serializable format. + - `packDisplaySlots` - Packs the display slots into a serializable format. + - `ScoreboardSaveData` + - `getData`, `setData` - Handles the packed scoreboard. + - `Packed$EMPTY` - Represents an empty scoreboard. +- `net.minecraft.world.waypoints.Waypoint$Icon#copyFrom` - Copies the icon color and style from another icon. + +### List of Changes + +- `com.mojang.blaze3d.platform.Lighting#updateLevel` now takes in a `DimensionType$CardinalLightType` instead of a boolean for whether the level is the nether or not +- `com.mojang.blaze3d.systems.GpuDevice#createTexture` now has an overload that takes in a supplied label instead of the raw string +- `com.mojang.blaze3d.vertex.VertexConsumer` + - `addVertex`, `addVertexWith2DPose` now take in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) + - `putBulkData` no longer takes the final `boolean` to read the buffer data to determine the initial color +- `com.mojang.math` + - `OctahedralGroup` + - `fromXYAngles` -> `Quadrant#fromXYAngles` + - `permute` -> `SymmetricGroup3#permuteAxis` + - `SymmetricGroup3` + - `permutation` -> `permute` + - `permuteVector` -> `OctahedralGroup#rotate` + - `Transformation` now takes in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) + - This also applies to the argument getter methods +- `net.minecraft` + - `FileUtil#isValidStrictPathSegment` -> `containsAllowedCharactersOnly`, now private + - Replaced by `isValidPathSegment` + - `Minecraft` + - `disconnectWithProgressScreen` now takes in a `boolean` of whether to stop the sound engine + - `disconnect` now takes in a `boolean` of whether to stop the sound engine + - `SharedConstants` + - `DEBUG_WATER` -> `DebugScreenEntries#VISUALIZE_WATER_LEVELS`, not one-to-one + - `DEBUG_HEIGHTMAP` -> `DebugScreenEntries#VISUALIZE_HEIGHTMAP`, not one-to-one + - `DEBUG_COLLISION` -> `DebugScreenEntries#VISUALIZE_COLLISION_BOXES`, not one-to-one + - `DEBUG_SUPPORT_BLOCKS` -> `DebugScreenEntries#VISUALIZE_ENTITY_SUPPORTING_BLOCKS`, not one-to-one + - `DEBUG_LIGHT` -> `DebugScreenEntries#VISUALIZE_BLOCK_LIGHT_LEVELS`, `VISUALIZE_SKY_LIGHT_LEVELS`; not one-to-one + - `DEBUG_SKY_LIGHT_SECTIONS` -> `DebugScreenEntries#VISUALIZE_SKY_LIGHT_SECTIONS`, not one-to-one + - `DEBUG_SOLID_FACE` -> `DebugScreenEntries#VISUALIZE_SOLID_FACES`, not one-to-one + - `DEBUG_CHUNKS` -> `DebugScreenEntries#VISUALIZE_CHUNKS_ON_SERVER`, not one-to-one +- `net.minecraft.advancements.criterion.EntityFlagsPredicate` now takes in optional booleans for if the entity is in water or fall flying + - The associated `$Builder` methods have also been added +- `net.minecraft.client` + - `Camera` + - `setup` now takes in a `Level` instead of a `BlockGetter` + - `get*` has been replaced by their record alternatives (e.g. `getEntity` -> `entity`) + - `Vector3f` return values are replaced with `Vector3fc` + - `GraphicsStatus` -> `GraphicsPreset`, not one-to-one + - `KeyMapping` now has an overload that takes in the sort order + - `MouseHandler#lastClickTime` -> `lastClick`, now private, not one-to-one + - `OptionInstance$OptionInstanceSliderButton` now implements `ResettableOptionWidget` + - `Options` + - `graphicsMode` -> `graphicsPreset`, `applyGraphicsPreset` + - `showNowPlayingToast` -> `musicToast`, not one-to-one +- `net.minecraft.client.data.models` + - `EquipmentAssetProvider#humanoidAndHorse` -> `humanoidAndMountArmor` + - `ItemModelGenerators` + - `getSpans` -> `getSideFaces`, not one-to-one + - `$SpanFacing` -> `$SideDirection`, not one-to-one + - `$Span` -> `$SideFace`, not one-to-one + - `ItemModelOutput#accept` now has an overload that takes in the `ClientItem$Properties` +- `net.minecraft.client.gui` + - `Font#NO_SHADOW` -> `Style#NO_SHADOW` + - `GuiGraphics` + - `textHighlight` now takes in a `boolean` of whether to render the background rectangle + - `submitOutline` -> `renderOutline` +- `net.minecraft.client.gui.components` + - `AbstractButton#handleCursor` -> `handleCursor`, now protected + - `AbstractSliderButton` + - `HANDLE_WIDTH` is now protected + - `canChangeValue`, `setValue` are now protected + - `AbstractWidget#message` is now protected + - `CycleButton` now implements `ResettableOptionWidget` + - `builder` now has an overload to take in a supplied default value + - `booleanBuilder` now takes in a boolean to choose which component to default to + - `$Builder` now takes in a supplied default value + - `displayOnlyValue(boolean)` -> `displayState`, not one-to-one + - `FocusableTextWidget` constructor is now package private, use `builder` instead + - `OptionsList` now passes in an `$AbstractEntry` to the generic rather than an `$Entry` + - `addSmall` now has an overload that takes in an `OptionInstance` + - `$Entry` now extends `$AbstractEntry` + - `$OptionEntry` class is removed + - `big` -> `$Entry#big` + - `small` -> `$Entry#small` + - `StringWidget#clipText` is now public static, taking in the `Font` +- `net.minecraft.client.gui.components.debug` + - `DebugScreenEntryList` + - `toggleF3Visible` -> `toggleDebugOverlay` + - `setF3Visible` -> `setOverlayVisible` + - `isF3Visible` -> `isOverlayVisible` + - `DebugScreenEntryStatus#IN_F3` -> `IN_OVERLAY` +- `net.minecraft.client.gui.components.debugchart.AbstractDebugChart#COLOR_GREY` -> `CommonColors#TEXT_GRAY` +- `net.minecraft.client.gui.components.toasts.ToastManager` + - `createNowPlayingToast` -> `initializeMusicToast`, now private, not one-to-one + - `removeNowPlayingToast` -> `setMusicToastDisplayState`, not one-to-one +- `net.minecraft.client.gui.navigation.ScreenRectangle#transform*` methods now take in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) +- `net.minecraft.client.gui.render.state.*` now take in the interface, 'read only' variants for its `pose` (e.g., `Vector3f` -> `Vector3fc`) + - `GuiTextRenderState` now takes in whether to draw the empty space around each glyph +- `net.minecraft.client.gui.screens` + - `DeathScreen` now takes in the `LocalPlayer` + - `Screen` now has an overload that takes in the `Minecraft` instance and `Font` to use + - `minecraft` is now final + - `font` is now final + - `init(Minecraft, int, int)` -> `init(int, int)` + - `resize(Minecraft, int, int)` -> `init(int, int)` + - `handleComponentClicked` -> `ChatScreen#handleComponentClicked`, now private + - `handleClickEvent` has been moved to their associated classes instead of one super interface (e.g., `BookViewScreen#handleClickEvent`) +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementsScreen#renderWindow` now takes in the mouse XY `int`s + - `AdvancementTab#drawTab` now takes in the mouse XY `int`s +- `net.minecraft.client.gui.screens.debug.DebugOptionsScreen$OptionList` is now public +- `net.minecraft.client.gui.screens.inventory` + - `AbstractCommandBlockEditScreen#populateAndSendPacket` no longer takes in the `BaseCommandBlock` + - `AbstractContainerScreen#renderSlots`, `renderSlot` now take in the mouse XY `int`s + - `CreativeModeInventoryScreen#renderTabButton` now takes in the mouse XY `int`s + - `EffectsInInventory#renderEffects` -> `render` + - `HorseInventoryScreen` now extends `AbstractMountInventoryScreen` + - `MinecartCommandBlockEditScreen` now takes in a `MinecartCommandBlock` instead of a `BaseCommandBlock` +- `net.minecraft.client.gui.screens.multiplayer.ServerSelectionList$OnlineServerEntry` now implements `SelectableEntry` +- `net.minecraft.client.gui.screens.packs.TransferableSelectionList$PackEntry` now implements `SelectableEntry` +- `net.minecraft.client.gui.screens.recipebook` + - `RecipeBookComponent#initFilterButtonTextures` -> `getFilterButtonTextures`, not one-to-one + - `RecipeBookTabButton` now implements `ImageButton` instead of `StateSwitchingButton` + - The constructor now takes in the XY position along with the `Button$OnPress` consumer +- `net.minecraft.client.gui.screens.worldselection.WorldSelectionList$WorldListEntry` is no longer static, now implements `SelectableEntry` +- `net.minecraft.client.model` + - `AnimationUtils` + - `animateCrossbowCharge` now takes in a `float` instead of an `int` + - `animateZombieArms` now takes in an `UndeadRenderState` instead of two `float`s + - `HumanoidModel` + - `setupAttackAnimation` no longer takes in a `float` + - `getArm` is now public from protected +- `net.minecraft.client.model.geom.ModelPart#getExtentsForGui` now takes in a `Consumer` instead of a set +- `net.minecraft.client.model.geom.builders.UVPair` is now a record +- `net.minecraft.client.multiplayer` + - `MultiPlayerGameMode#isAlwaysFlying` -> `isSpectator` + - `ServerStatusPinger#pingServer` now takes in an `EventLoopGroupHolder` +- `net.minecraft.client.renderer` + - `CloudRenderer#render` now takes in the game time `long` + - `DynamicUniforms#writeTransform`, `$Transform` no longer take in the line width `float` + - `GameRenderer#setPanoramicMode` -> `setPanoramicScreenshotParameters`, not one-to-one + - `GlobalSettingsUniform#update` now takes in the `Camera` and whether to use Rotated Grid Super Sampling (RGSS) + - `ItemBlockRenderTypes#setFancy` -> `setCutoutLeaves` + - `ItemInHandRenderer` no longer takes in the `ItemRenderer` + - `LevelRenderer#isSectionCompiled` -> `isSectionCompiledAndVisible` + - `RenderPipelines` + - `LINE_STRIP` -> `LINES` or `LINES_TRANSLUCENT`, not one-to-one + - `DEBUG_LINE_STRIP` -> `DEBUG_POINTS`, not one-to-one + - `RenderType` + - `LINE_STRIP`, `lineStrip` -> `RenderTypes#LINES`, `LINES_TRANSLUCENT`, `linesTranslucent`; not one-to-one + - `debugLineStrip` -> `debugPoint`, not one-to-one + - `SkyRenderer` now takes in the `TextureManager` and `AtlasManager` + - `extractRenderState` now takes in a `Camera` instead of the camera position + - `renderSunMoonAndStars` now takes in a `MoonPhase` instead of an `int` + - `UniformValue` + - `$IVec3Uniform` now takes in a `Vector3ic` instead of a `Vector3i` + - `$Vec2Uniform` now takes in a `Vector2fc` instead of a `Vector2f` + - `$Vec3Uniform` now takes in a `Vector3fc` instead of a `Vector3f` + - `$Vec4Uniform` now takes in a `Vector4fc` instead of a `Vector4f` + - `WeatherEffectRenderer#tickRainParticles` now takes in an `int` for the weather radius + - `WorldBorderRenderer#extract` now takes in a `float` for the partial tick +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#getExtents` now takes in a `Consumer` instead of a set + - `BedRenderer#getExtents` now takes in a `Consumer` instead of a set + - `BellRenderer#BELL_RESOURCE_LOCATION` -> `BELL_TEXTURE` + - `DecoratedPotRenderer#getExtents` now takes in a `Consumer` instead of a set + - `EnchantTableRenderer#BOOK_LOCATION` -> `BOOK_TEXTURE` + - `ShulkerBoxRenderer#getExtents` now takes in a `Consumer` instead of a set + - `TestInstanceRenderer` no longer takes in the `BlockEntityRendererProvider$Context` +- `net.minecraft.client.renderer.blockentity.state.BlockEntityWithBoundingBoxRenderState$InvisibleBlockType$STRUCUTRE_VOID` -> `STRUCTURE_VOID` +- `net.minecraft.client.renderer.chunk.ChunkSectionLayer#textureView` -> `texture`, not one-to-one +- `net.minecraft.client.renderer.entity.EntityRenderDispatcher` no longer takes in the `ItemRenderer` +- `net.minecraft.client.renderer.entity.layers` + - `CarriedBLockLayer` no longer takes in the `BlockRenderDispatcher` + - `IronGolemFlowerLayer` no longer takes in the `BlockRenderDispatcher` + - `ItemInHandLayer#submitArmWithItem` now takes in the held `ItemStack` +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` + - `*HandItem` -> `*HandItemState`, `*HandItemStack`; not one-to-one + - `extractArmedRenderState` now takes in the partial tick `float` + - `HorseRenderState#bodyArmorItem` -> `EquineRenderState#bodyArmorItem` + - `HumanoidRenderState` + - `attackTime` -> `ArmedEntityRenderState#attackTime` + - `ticksUsingItem` is now a float + - `IllagerRenderState` now extends `UndeadRenderState` + - `ticksUsingItem` is now a float + - `ZombieRenderState` now extends `UndeadRenderState` + - `ZombifiedPiglinRenderState` now extends `UndeadRenderState` +- `net.minecraft.client.renderer.fog.FogRenderer#setupFog` no longer takes in the `boolean` +- `net.minecraft.client.renderer.fog.environment` + - `AtmosphericFogEnvironment` now extends `FogEnvironment` instead of `AirBasedFogEnvironment` + - `FogEnvironment#setupFog` no longer takes in the `Entity` and `BlockPos`, instead the `Camera` +- `net.minecraft.client.renderer.item.ClientItem$Properties` now takes in a float for changing the scale of the swap animation +- `net.minecraft.client.renderer.special.SpecialModelRenderer#getExtents` now takes in a `Consumer` instead of a set +- `net.minecraft.client.renderer.state.SkyRenderState#moonPhase` is now a `MoonPhase` instead of an `int` +- `net.minecraft.client.resources.SplashManager` + - `prepare` now returns a list of `Component`s instead of strings + - `apply` now takes in a list of `Component`s instead of strings +- `net.minecraft.client.resources.model.BlockModelRotation` is now a class + - `by` -> `get`, not one-to-one +- `net.minecraft.client.resources.sounds` + - `RidingHappyGhastSoundInstance` -> `RidingEntitySoundInstance`, not one-to-one + - `RidingMinecartSoundInstance` now extends `RidingEntitySoundInstance` instead of `AbstractTickableSoundInstance` + - The constructor now takes in the `SoundEvent`, volume min and max, and amplifier + - `SimpleSoundInstance#forMusic` no longer takes in the volume +- `net.minecraft.client.sounds` + - `SoundEngine` no longer takes in the `MusicManager` + - `updateCategoryVolume` -> `refreshCategoryVolume` + - `setVolume` -> `updateCategoryVolume`, not one-to-one + - `SoundManager` no longer takes in the `MusicManager` + - `updateSourceVolume` -> `refreshCategoryVolume` + - `setVolume` -> `updateCategoryVolume`, not one-to-one +- `net.minecraft.gametest.framework.GameTestHelper` + - `spawn` now has an overload that takes in the `EntitySpawnReason` or three `int`s for the position + - `assetTrue`, `assetFalse`, `assertValueEqual` now has an overload that takes in a `String` instead of a `Component` + - `assertEntityData` now has an overload that takes in the `AABB` bounding box + - `getRelativeBounds` is now public + - `assertEntityPosition` -> `assertEntityPresent`, not one-to-one +- `net.minecraft.nbt` + - `CompoundTag#remove` now returns the removed tag + - `NbtUtils#getDataVersion` now has an overload that only takes in the `CompoundTag` +- `net.minecraft.network` + - `Connection` + - `NETWORK_WORKER_GROUP` -> `EventLoopGroupHolder#NIO`, not one-to-one + - `NETWORK_EPOLL_WORKER_GROUP` -> `EventLoopGroupHolder#EPOLL`, not one-to-one + - `LOCAL_WORKER_GROUP` -> `EventLoopGroupHolder#LOCAL`, not one-to-one + - `connectToServer`, `connect` now take in an `EventLoopGroupHolder` instead of a `boolean` + - `FriendlyByteBuf` + - `writeVector3f` now takes in a `Vector3fc` instead of a `Vector3f` + - `writeQuaternion` now takes in a `Quaternionfc` instead of a `Quaternionf` + - `DEFAULT_NBT_QUOTA` -> `NbtAccounter#DEFAULT_NBT_QUOTA` +- `net.minecraft.network.codec` + - `ByteBufCodecs` + - `VECTOR3F` now uses a `Vector3fc` instead of a `Vector3f` + - `QUATERNIONF` now uses a `Quaternionfc` instead of a `Quaternionf` + - `StreamCodec#composite` now has ten and twelve parameter variants +- `net.minecraft.network.chat` + - `ComponentUtils#mergeStyles` now has an overload that takes in and returns a `Component` + - `MutableComponent` is now final +- `net.minecraft.network.protocol.game` + - `ClientboundHorseScreenOpenPacket` -> `ClientboundMountScreenOpenPacket` + - `ClientGamePacketListener#handleHorseScreenOpen` -> `handleMountScreenOpen` + - `GamePacketTypes#CLIENTBOUND_HORSE_SCREEN_OPEN` -> `CLIENTBOUND_MOUNT_SCREEN_OPEN` +- `net.minecraft.network.numbers` + - `FixedFormat` is now a record + - `StyledFormat` is now a record +- `net.minecraft.network.syncher.EntityDataSerializers` + - `VECTOR3` now uses a `Vector3fc` instead of a `Vector3f` + - `QUATERNION` now uses a `Quaternionfc` instead of a `Quaternionf` +- `net.minecraft.server` + - `MinecraftServer` + - `isAllowedToEnterPortal` -> `ServerLevel#isAllowedToEnterPortal` + - `isSpawningMonsters` -> `ServerLevel#isSpawningMonsters` + - `isPvpAllowed` -> `ServerLevel#isPvpAllowed` + - `isCommandBlockEnabled` -> `ServerLevel#isCommandBlockEnabled` + - `isSpawnerBlockEnabled` -> `ServerLevel#isSpawnerBlockEnabled` + - `getGameRules` -> `ServerLevel#getGameRules` + - `isEpollEnabled` -> `useNativeTransport` + - `ServerScoreboard` no longer implements its own saved data type, instead using the packed `ScoreboardSaveData` + - `TYPE` -> `ScoreboardSavedData#TYPE` +- `net.minecraft.server.jsonrpc` + - `IncomingRpcMethod` now takes in two generics for the parameters to the request and the result response + - `$Builder` now has constructors for parameterless and parameter functions, replacing `$Factory` + - `response`, `param` now take in their `Schema`s + - `OutgoingRpcMethod$Factory` now takes in the generic params and result +- `net.minecraft.server.jsonrpc.api` + - `MethodInfo`, `$Named` now takes in two generics for the parameters to the request and the result response + - `PARAMS_CODEC` -> `paramsTypedCodec`, now private, not one-to-one + - `MAP_CODEC` -> `typedCodec`, now package-private, not one-to-one + - `ParamInfo` now takes in a generic for the parameter + - `CODEC` -> `typedCodec`, not one-to-one + - `ResultInfo` now takes in a generic for the result response + - `CODEC` -> `typedCodec`, not one-to-one + - `Schema` now takes in a generic for the type it represents + - The constructor now takes in a list of types instead of an optional, an non-optional property map, non-oprional enuma values, and the codec to serialize the type + - `ofTypes` now has an overload that takes in a list of types + - `SchemaComponent` now takes in a generic for the type it represents +- `net.minecraft.server.jsonrpc.security.AuthenticationHandler` now implements `ChannelDuplexHandler` instead of `ChannelInboundHandlerAdapter` + - The constructor now takes in a string set of allowed origins + - `$SecurityCheckResult#allowed` now has an overload that specifies whether the token was sent through the websocket protocol +- `net.minecraft.server.level` + - `ChunkMap` now extends `SimpleRegionStorage` instead of `ChunkStorage` + - `ServerLevel#drop` no longer returns a `boolean` +- `net.minecraft.server.network.ServerConnectionListener` + - `SERVER_EVENT_GROUP` -> `EventLoopGroupHolder#NIO`, not one-to-one + - `SERVER_EPOLL_EVENT_GROUP` -> `EventLoopGroupHolder#EPOLL`, not one-to-one +- `net.minecraft.stats.ServerStatsCounter` now takes in a `Path` instead of a `File` + - `parseLocal` -> `parse`, not one-to-one + - `toJson` now returns a `JsonElement` instead of a `String` +- `net.minecraft.util` + - `ARGB#lerp` -> `srgbLerp` + - `ExtraCodecs` now use the interface, 'read only' variants for its generic (e.g., `Vector3f` -> `Vector3fc`) + - `Mth` + - `easeInOutSine` -> `Ease#inOutSine` + - `sin`, `cos` now takes in a `double` instead of a `float` + - `absMax` now has overloads that uses `int`s or `float`s + - `TriState` now implements `StringRepresentable` +- `net.minecraft.util.profiling.jfr.Percentiles#evaluate` now has an overload that takes in an `int[]` +- `net.minecraft.util.profiling.jfr.parse.JfrStatsResult` now takes in an FPS stat + - `tickTimes` -> `serverTickTimes` +- `net.minecraft.util.profiling.jfr.stats.TimedStatSummary#summary` now returns an optional of the `TimeStatSummary` +- `net.minecraft.util.worldupdate.WorldUpgrader` + - `$AbstractUpgrader` no longer takes in a generic + - `createStorage` now returns a `SimpleRegionStorage` instead of the generic + - `tryProcessOnePosition` now takes in a `SimpleRegionStorage` instead of the generic + - `$DimensionToUpgrade` no longer takes in a generic, instead using `SimpleRegionStorage` +- `net.minecraft.world.RandomSequences` no longer takes in the world seed + - `codec` -> `CODEC` + - `get`, `reset` now takes in the world seed +- `net.minecraft.world.entity` + - `Avatar#DATA_PLAYER_MAIN_HAND` now uses a `HumanoidArm` generic instead of a byte + - `Entity#hasImpulse` -> `needsSync` + - `EntityType#loadEntityRecursive` now takes in an `EntityProcessor` instead of a `Function` + - `LivingEntity#invulnerableDuration` -> `INVULNERABLE_DURATION` + - `Mob#playAttackSound` -> `LivingEntity#playAttackSound` + - `NeutralMob` + - `TAG_ANGER_TIME` -> `TAG_ANGER_END_TIME`, not one-to-one + - `getRemainingPersistentAngerTime` -> `getPersistentAngerEndTime`, not one-to-one + - `setRemainingPersistentAngerTime` -> `setTimeToRemainAngry`, `setPersistentAngerEndTime`; second is not one-to-one + - `getPersistentAngerTarget`, `setPersistentAngerTarget` now deal with `EntityReference`s +- `net.minecraft.world.entity.ai.sensing.SensorType#*_TEMPTATIONS` -> `FOOD_TEMPTATIONS`, not one-to-one +- `net.minecraft.world.entity.ai.util` + - `GoalUtils` + - `mobRestricted` now takes in a `double` instead of an `int` + - `isRestricted` now has an overload that takes in a `Vec3` + - `LandRandomPos` + - `getPosAway` now has an overload that takes in an additional `double` for the start/end radians + - `generateRandomPosTowardDirection` now takes in a `double` instead of an `int` + - `RandomPos` + - `generateRandomDirectionWithinRadians` now takes in `double`s for the start/end radians + - `generateRandomPosTowardDirection` now takes in a `double` instead of an `int` +- `net.minecraft.world.entity.animal.equine.AbstractHorse#getInventorySize` -> `AbstractMountInventoryMenu#getInventorySize` +- `net.minecraft.world.entity.monster.Monster#checkMonsterSpawnRules` now expanded its type generic to extends `Mob` instead of `Monster` +- `net.minecraft.world.entity.monster.skeleton.Bogged#*_ATTACK_INTERVAL` -> `AbstractSkeleton#INCREASED_*_ATTACK_INTERVAL` +- `net.minecraft.world.entity.monster.zombie` + - `Husk#checkHuskSpawnRules` -> `Monster#checkSurfaceMonsterSpawnRules`, not one-to-one + - `Zombie` + - `doUnderWaterConversion` now takes in the `ServerLevel` + - `convertToZombieType` now takes in the `ServerLevel` +- `net.minecraft.world.entity.npc.villager` + - `AbstractVillager` + - `updateTrades` now takes in the `ServerLevel` + - `addOffersFromItemListings` now takes in the `ServerLevel` + - `Villager#shouldRestock` now takes in the `ServerLevel` + - `VillagerTrades$ItemListing#getOffer` now takes in the `ServerLevel` +- `net.minecraft.world.entity.player.Player` + - `openMinecartCommandBlock` now takes in a `MinecartCommandBlock` instead of a `BaseCommandBlock` + - `sweepAttack` -> `doSweepAttack`, now private, not one-to-one + - `respawn` -> `LocalPlayer#respawn` + - `CLIENT_LOADED_TIMEOUT_TIME` -> `ServerGamePacketListenerImpl#CLIENT_LOADED_TIMEOUT_TIME` + - `clientLoadedTimeoutTimer`, `tickClientLoadTimeout` -> `ServerGamePacketListenerImpl#tickClientLoadTimeout` + - `hasClientLoaded` -> `ServerGamePacketListenerImpl#hasClientLoaded` + - `setClientLoaded` -> `ServerGamePacketListenerImpl#markClientLoaded`, `markClientUnloadedAfterDeath`, `restartClientLoadTimerAfterRespawn`; not one-to-one +- `net.minecraft.world.entity.projectile.Projectile` constructor is now `protected` instead of package private +- `net.minecraft.world.entity.vehicle.VehicleEntity#shouldSourceDestroy` is now `protected` instead of package private +- `net.minecraft.world.entity.vehicle.minecart` + - `AbstractMinecart` now takes in the `ServerLevel` + - `MinecartCommandBlock$MinecartCommandBase` is now package-private +- `net.minecraft.world.inventory.HorseInventoryMenu` now extends `AbstractMountInventoryMenu` +- `net.minecraft.world.item.component.ItemAttributeModifiers#compute` now takes in the `Attribute` holder +- `net.minecraft.world.item.enchantment.effects.PlaySoundEffect` now takes in a list of sound events instead of a single +- `net.minecraft.world.level` + - `BaseCommandBlock` + - `performCommand` now takes in a `ServerLevel` instead of a `Level` + - `onUpdated` now takes in a `ServerLevel` + - `createCommandSourceStack` now takes in a `ServerLevel` + - `$CloseableCommandBlockSource` now takes in a `ServerLevel`, with its constructor protected + - `CollisionGetter#noBlockCollision` now has an overload that takes in an additional `boolean` of whether to check liquid collisions. + - `Level#getGameTime` -> `LevelAccessor#getGameTime` + - `LevelAccessor#getCurrentDifficultyAt` -> `ServerLevelAccessor#getCurrentDifficultyAt` + - `LevelTimeAccess#getMoonPhase` now returns a `MoonPhase` instead of an `int` +- `net.minecraft.world.level.biome` + - `AmbientAdditionsSettings` is now a record + - `AmbientMoodSettings` is now a record + - `AmbientParticleSettings` is now a record +- `net.minecraft.world.level.block.entity.BaseContainerBlockEntity#canUnlock` -> `sendChestLockedNotifications`, not one-to-one +- `net.minecraft.world.level.border` + - `BorderChangeListener#onLerpSize` now takes in an additional `long` for the game time + - `WorldBorder` can now take in the `WorldBorder$Settings` + - `getMin*`, `getMax*` now have an overload that takes in the partial tick `float` + - `lerpSizeBetween` now takes in an additional `long` for the game time + - `applySettings` -> `applyInitialSettings`, not one-to-one + - The original behavior can be replicated by passing the settings into the constructor + - `$BorderExtent#getMin*`, `getMax*` now takes in the partial tick `float` +- `net.minecraft.world.level.chunk.storage` + - `RecreatingSimpleRegionStorage` now takes in a supplied `LegacyTagFixer` + - `SimpleRegionStorage` now takes in a supplied `LegacyTagFixer` + - `write` now has an overload that takes in a supplied `CompoundTag` + - `upgradeChunkTag` now has an overload that takes in a a nullable tag comntext +- `net.minecraft.world.level.dimension.DimensionType` + - `MOON_PHASES` is now an array of `MoonPhase`s and private + - `moonPhase` now returns a `MoonPhase` instead of an `int` +- `net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler` now implements `LegacyTagFixer` + - The constructor now takes in the `DataFixer` + - `removeIndex` -> `LegacyTagFixer#markChunkDone` + - `updateFromLegacy` now private + - `getLegacyStructureHandler` now takes in the `DataFixer`, a supplied `DimensionDataStorage`, and returns a supplied `LegacyTagFixer` +- `net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces$StartPiece` fields are now package-private +- `net.minecraft.world.level.saveddata.SavedDataType` no longer takes in a `SavedData$Context`, removing the function argument constructor +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` no longer takes in a `SavedData$Context` + - `FileNameDateFormatter#create` -> `FORMATTER` + - `LevelStorageSource` + - `UNCOMPRESSED_NBT_QUOTA` -> `NbtAccounter#UNCOMPRESSED_NBT_QUOTA`, now `public` + - `$LevelDirectory#corruptedDataFile`, `rawDataFile` now take in a `ZonedDateTime` instead of a `LocalDateTime` +- `net.minecraft.world.level.storage.loot.LootContext` + - `$BlockEntityTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` + - `$EntityTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` + - `$ItemStackTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction` + - `$*Source` -> `$DirectSource`, not one-to-one + - `$Source` -> `LootContextArg$Getter`, not one-to-one + - `CopyNameFunction#copyName` now takes in a `LootContextArg` instead of a `$Source` + - `$Source` -> `LootContextArg`, not one-to-one + - `FilteredFunction` now takes in an `Optional` pass and fail `LootItemFunction` instead of just a modifier + - The function can now be builder through a `$Builder` via `filtered` +- `net.minecraft.world.phys.Vec3` now takes in a `Vector3fc` instead of a `Vector3f` +- `net.minecraft.world.phys.shapes.Shapes#rotateHorizontal`, `rotateAll`, `rotateAttachFace` now have overloads to take in the `OctahedralGroup` +- `net.minecraft.world.scores` + - `Score` now has a public constructor for the `$Packed` value + - `MAP_CODEC` -> `Score$Packed` ands its `$Packed#MAP_CODEC` + - `Scoreboard$PackedScore#score` now takes in a `Score$Packed` instead of a `Score` + - `ScoreboardSavedData` now takes in a `ScoreboardSaveData$Packed` instead of a `Scoreboard` + - `FILE_ID` merged into type + - `loadFrom` -> `ServerScoreboard#load` + - `pack` -> `ServerScoreboard#store`, now private, not one-to-one + +### List of Removals + +- `com.mojang.blaze3d.vertex.VertexFormat$Mode#LINE_STRIP` +- `net.minecraft.Util#lastOf` +- `net.minecraft.client` + - `Minecraft#useFancyGraphics` + - `GuiMessage#icon` + - `StringSplitter` + - `formattedIndexByWidth`, `componentStyleAtWidth` + - `splitLines(FormattedText, int, Style, FormattedText)` +- `net.minecraft.client.gui.Font#wordWrapHeight(String, int)` +- `net.minecraft.client.gui.components` + - `CycleButton` + - `onOffBuilder()` + - `$Builder#withInitialValue` + - `StateSwitchingButton` +- `net.minecraft.client.gui.screens.inventory` + - `EffectsInInventory#renderTooltip` + - `InventoryScreen#renderEntityInInventory` +- `net.minecraft.client.gui.screens.packs.PackSelectionScreen#clearSelected` +- `net.minecraft.client.player.LocalPlayer#USING_ITEM_SPEED_FACTOR` +- `net.minecraft.client.renderer` + - `ItemModelGenerator#createOrExpandSpan` + - `GpuWarnlistManager#dismissWarningAndSkipFabulous`, `isSkippingFabulous` + - `RenderPipelines` + - `DEBUG_STRUCTURE_QUADS`, `DEBUG_SECTION_QUADS` + - `SkyRenderer#initTextures` +- `net.minecraft.client.renderer.fog.environment` + - `AirBasedFogEnvironment` + - `DimensionOrBossFogEnvironment` + - `FogEnvironment#onNotApplicable` +- `net.minecraft.client.resources.model.BlockModelRotation#actualRotation` +- `net.minecraft.gametest.framework.GameTestHelper#setNight`, `setDayTime` +- `net.minecraft.network.FriendlyByteBuf#readDate`, `writeDate` +- `net.minecraft.server` + - `MinecraftServer#hasGui` + - `ServerScoreboard#createData`, `addDirtyListener` +- `net.minecraft.server.jsonrpc.IncomingRpcMethod$Factory` +- `net.minecraft.server.jsonrpc.methods.IllegalMethodDefinitionException` +- `net.minecraft.server.jsonrpc.security.AuthenticationHandler#AUTH_HEADER` +- `net.minecraft.util` + - `DebugBuffer` + - `LazyLoadedValue` +- `net.minecraft.util.thread.NamedThreadFactory` +- `net.minecraft.world.entity.Mob#isSunBurnTick` +- `net.minecraft.world.entity.animal.armadillo.ArmadilloAi#getTemptations` +- `net.minecraft.world.entity.animal.axolotl.AxolotlAi#getTemptations` +- `net.minecraft.world.entity.animal.camel.CamelAi#getTemptations` +- `net.minecraft.world.entity.animal.equine.ZombieHorse#checkZombieHorseSpawnRules` + - Use `Monster#checkMonsterSpawnRules` instead +- `net.minecraft.world.entity.animal.goat.GoatAi#getTemptations` +- `net.minecraft.world.entity.animal.sniffer.SnifferAi#getTemptations` +- `net.minecraft.world.entity.player.Player#playNotifySound` +- `net.minecraft.world.entity.raid.Raid#TICKS_PER_DAY` +- `net.minecraft.world.level` + - `BaseCommandBlock` + - `getLevel` + - `getUsedBy`, `getPosition` + - `Level#TICKS_PER_DAY` +- `net.minecraft.world.level.border.WorldBorder$Settings#toWorldBorder` + - Use the `WorldBorder` constructor instead +- `net.minecraft.world.level.chunk.storage` + - `ChunkStorage` + - `RecreatingChunkStorage` +- `net.minecraft.world.level.saveddata.SavedData$Context` +- `net.minecraft.world.phys.Vec3#fromRGB24` diff --git a/src/detailed-primers/1.21.2-from-1.21.1.md b/src/detailed-primers/1.21.2-from-1.21.1.md new file mode 100644 index 0000000..8934994 --- /dev/null +++ b/src/detailed-primers/1.21.2-from-1.21.1.md @@ -0,0 +1,3199 @@ +# Minecraft 1.21.1 -> 1.21.2 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.1 to 1.21.2. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +## 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](https://misode.github.io/versions/?id=1.21.2&tab=changelog). + +## The Holder Set Transition + +Many of the methods that used `TagKey`s or raw registry objects have been replaced with the direct `HolderSet` object. A `HolderSet` is essentially a list of registry object references that can be dynamically updated and managed as needed by the game. There are effectively two kinds of `HolderSet`s: direct and named. Named `HolderSet`s are the object representation of tags in game. It's called a named set as the `HolderSet` is referenced by the tag's name. Direct `HolderSet`s, on the other hand, are created by `HolderSet#direct`, which functions as an inlined list of values. These are useful when a separate object doesn't need to be defined to construct some value. + +For a JSON example: +```json5 +// HolderSet#direct with one element +{ + "holder_set": "minecraft:apple" +} + +// HolderSet#direct with multiple elements +{ + "holder_set": [ + "minecraft:apple", + "minecraft:stick" + ] +} + +// HolderSet reference (tags) +{ + "holder_set": "#minecraft:planks" +} +``` + +Generally, you should never be constructing holder sets incode except during provider generation. Each set type has a different method of construction. + +First, to even deal with `Holder`s or `HolderSet`s, you will need access to the static registry instance via `Registry` or the datapack registry via `HolderGetter`. The `HolderGetter` is either obtained from a `BootstrapContext#lookup` during datapack registry generation or `HolderLookup$Provider#lookupOrThrow` either as part of generation or `MinecraftServer#registryAccess` during gameplay. + +Once that is available, for direct `HolderSet`s, you will need to get the `Holder` form of a registry object. For static registries, this is done through `Registry#wrapAsHolder`. For datapack registries, this is done through `HolderGetter#getOrThrow`. + +```java +// Direct holder set for Items +HolderSet items = HolderSet.direct(BuiltInRegistries.ITEM.wrapAsHolder(Items.APPLE)); + +// Direct holder set for configured features +// Assume we have access to the HolderGetter> registry +Holderset> features = HolderSet.direct(registry.getOrThrow(OreFeatures.ORE_IRON)); +``` + +For named `HolderSet`s, the process is similar. For both static and dynamic registries, you call `HolderGetter#getOrThrow`. + +```java +// Named holder set for Items +HolderSet items = BuiltInRegistries.ITEM.getOrThrow(ItemTags.PLANKS); + +// Named holder set for biomes +// Assume we have access to the HolderGetter registry +Holderset biomes = registry.getOrThrow(BiomeTags.IS_OCEAN); +``` + +As these changes are permeated throughout the entire codebase, they will be listed in more relevant subsections. + +## Gui Render Types + +Gui rendering methods within `GuiGraphics` now take in a `Function` to determine how to render the image. Also, `blit` methods now require the size of the PNG to be specified. + +```java +// For some GuiGraphics graphics +graphics.blit( + // How to render the texture + RenderType::guiTextured, + // The previous texture parameters + ..., + // The size of the PNG to use + 256, 256); +``` + +This means methods that provided helpers towards setting the texture or other properties that could be specified within a shader have been removed. + +- `com.mojang.blaze3d.pipeline.RenderTarget#blitToScreen(int, int, boolean)` -> `blitAndBlendToScreen` +- `net.minecraft.client.gui.GuiGraphics` + - `drawManaged` is removed + - `setColor` is removed - Now a parameter within the `blit` and `blitSprite` methods + - `blit(int, int, int, int, int, TextureAtlasSprite, *)` is removed + - `bufferSource` -> `drawSpecial`, not one-to-one as this takes in a consumer of the `MultiBufferSource` and ends the current batch instead of just returning the `MultiBufferSource` +- `net.minecraft.client.gui.components.PlayerFaceRenderer` + - All `draw` methods except `draw(GuiGraphics, PlayerSkin, int, int, int)` takes in an additional `int` that defines the color +- `net.minecraft.client.renderer.RenderType` + - `guiTexturedOverlay` - Gets the render type for an image overlayed onto the game screen. + - `guiOpaqueTexturedBackground` - Gets the render type for a GUI texture applied to the background of a menu. + - `guiNauseaOverlay` - Gets the render type for the nausea overlay. + - `guiTextured` - Gets the render type for an image within a GUI menu. +- `net.minecraft.client.resources.metadata.gui.GuiSpriteScaling$NineSlice` now takes in a boolean representing whether the center portion of the texture should be streched to fit the size + +## Shader Rewrites + +The internals of shaders have been rewritten quite a bit. + +### Shaders Files + +The main changes are the defined samplers and post shaders. + +The `DiffuseSampler` and `DiffuseDepthSampler` have been given new names depending on the target to apply: `InSampler`, `MainSampler`, and `MainDepthSampler`. `InSampler` is used in everything but the `transparency` program shader. + +```json5 +// In some shader JSON +{ + "samplers": [ + { "name": "MainSampler" }, + // ... + ] +} +``` + +Within post effect shaders, they have been changed completely. For a full breakdown of the changes, see `PostChainConfig`, but in general, all targets are now keys to objects, all pass inputs and filters are now lists of sampler inputs. As for how this looks: + +```json5 +// Old post effect shader JSON +// In assets//shaders/post +{ + "targets": [ + "swap" + ], + "passes": [ + { + "name": "invert", + "intarget": "minecraft:main", + "outtarget": "swap", + "use_linear_filter": true, + "uniforms": [ + { + "name": "InverseAmount", + "values": [ 0.8 ] + } + ] + }, + { + "name": "blit", + "intarget": "swap", + "outtarget": "minecraft:main" + } + ] +} + +// New post effect JSON +// In assets//post_effect +{ + "targets": { + "swap": {} // Swap is now a target object (fullscreen unless otherwise specified) + }, + "passes": [ + { + // Name of the program to apply (previously 'name') + // assets/minecraft/shaders/post/invert.json + "program": "minecraft:post/invert", + // Inputs is now a list + "inputs": [ + { + // Targets the InSampler + // Sampler must be available in the program shader JSON + "sampler_name": "In", + // Reading from the main screen (previously 'intarget') + "target": "minecraft:main", + // Use GL_LINEAR (previously 'use_linear_filter') + "bilinear": true + } + ], + // Writes to the swap target (previously 'outtarget') + "output": "swap", + "uniforms": [ + { + "name": "InverseAmount", + "values": [ 0.8 ] + } + ] + }, + { + "program": "minecraft:post/blit", + "inputs": [ + { + "sampler_name": "In", + "target": "swap" + } + ], + "output": "minecraft:main" + } + ] +} +``` + +### Shader Programs + +All shaders, regardless of where they are used (as part of a program or post effect), have a JSON within `assets//shaders`. This JSON defines everything the shader will use, as defined by `ShaderProgramConfig`. The main addition is the change to `ResourceLocation` relative references, and adding the `defines` header dynamically during load time. + +```json5 +// For some assets/my_mod/shaders/my_shader.json +{ + // Points to assets/my_mod/shaders/my_shader.vsh (previously 'my_shader', without id specification) + "vertex": "my_mod:my_shader", + // Points to assets/my_mod/shaders/my_shader.fsh (previously 'my_shader', without id specification) + "fragment": "my_mod:my_shader", + // Adds '#define' headers to the shaders + "defines": { + // #define + "values": { + "ALPHA_CUTOUT": "0.1" + }, + // #define flag + "flags": [ + "NO_OVERLAY" + ] + }, + // A list of sampler uniforms to use in the shader + // There are 12 texture sampler uniforms Sampler0-Sampler11, though usually only Sampler0 is supplied + // Additionally, there are dynamic '*Sampler' for post effect shaders which are bound to read the specified targets or 'minecraft:main' + "samplers": [ + { "name": "Sampler0" } + ], + // A list of uniforms that can be accessed within the shader + // A list of available uniforms can be found in CompiledShaderProgram#setUniforms + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +} +``` + +```glsl +// For some assets/my_mod/shaders/my_shader.vsh (Vertex Shader) + +// GLSL Version +#version 150 + +// Imports Mojang GLSL files +// Located in assets//shaders/include/ +#moj_import + +// Defines are injected (can use 'ALPHA_CUTOUT' and 'NO_OVERLAY') + +// Defined by the VertexFormat passed into the ShaderProgram below +in vec3 Position; // vec3 float +in vec4 Color; // vec4 unsigned byte (0-255) + +// Samplers defined by the JSON +uniform sampler2D Sampler0; + +// Uniforms provided by the JSON +uniform mat4 ModelViewMat; +uniform mat4 ProjMat; +uniform vec3 ModelOffset; + +// Values to output to the fragment shader +out float vertexDistance; +out vec4 vertexColor; +out vec2 texCoord0; + +void main() { + // Out values should be set here +} +``` + +```glsl +// For some assets/my_mod/shaders/my_shader.fsh (Fragment Shader) + +// GLSL Version +#version 150 + +// Imports Mojang GLSL files +// Located in assets//shaders/include/ +#moj_import + +// Defines are injected (can use 'ALPHA_CUTOUT' and 'NO_OVERLAY') + +// Defined by the output of the vertex shader above +in float vertexDistance; +in vec4 vertexColor; +in vec2 texCoord0; + +// Samplers defined by the JSON +uniform sampler2D Sampler0; + +// Uniforms provided by the JSON +uniform vec4 ColorModulator; + +// Values to output to the framebuffer (the color of the pixel) +out vec4 fragColor; + +void main() { + // Out values should be set here +} +``` + +On the code side, shaders are stored internally as either a `ShaderProgram` or a `CompiledShaderProgram`. `ShaderProgram` represents the identifier, while the `CompiledShaderProgram` represents the shader itself to run. Both are linked together through the `ShaderManager`. + +Shader programs are compiled dynamically unless specified as a core shader. This is done by registering the `ShaderProgram` to `CoreShaders#PROGRAMS`. + +```java +// List PROGRAMS access +ShaderProgram MY_SHADER = new ShaderProgram( + // Points to assets/my_mod/shaders/my_shader.json + ResourceLocation.fromNamespaceAndPath('my_mod', 'my_shader'), + // Passed in vertex format used by the shader + DefaultVertexFormat.POSITION_COLOR, + // Lists the '#define' values and flags + // Value: '#define ' + // Flag: '#define ' + ShaderDefines.EMPTY +) +``` + +The shader programs are then set by calling `RenderSystem#setShader` with the `ShaderProgram` in question. In fact, all references to `GameRenderer#get*Shader` should be replaced with a `ShaderProgram` reference. + +```java +// In some rendering method +RenderSystem.setShader(MY_SHADER); + +// Creating a new ShaderStateShard for a RenderType +ShaderStateShard MY_SHARD = new ShaderStateShard(MY_SHADER); +``` + +- `com.mojang.blaze3d.ProjectionType` - An enum which holds the logic for how a projection matrix should be rendered. +- `com.mojang.blaze3d.buffers` + - `BufferType` - An enum that specifies the GL target buffer type. + - `GpuBuffer` - A wrapper around the GL buffer calls for handling the rendering of the screen. + - `GpuFence` - A handle for managing the sync status of the GPU fence. +- `com.mojang.blaze3d.platform.GlStateManager` + - `glShaderSource` now takes in a `String` rather than a `List` + - `_glMapBufferRange` - Delegates to `GL30#glMapBufferRange`. + - `_glFenceSync` - Delegates to `GL32#glFenceSync`. + - `_glClientWaitSync` - Delegates to `GL32#glClientWaitSync`. + - `_glDeleteSync` - Delegates to `GL32#glDeleteSync`. + - `_glBuffserSubData` - Delegates to `GL15#glBufferSubData`. +- `com.mojang.blaze3d.preprocessor.GlslPreprocessor#injectDefines` - Injects any defined sources to the top of a loaded `.*sh` file. +- `com.mojang.blaze3d.shaders` + - `BlendMode`, `Effect`, `EffectProgram`, `Program`, `ProgramManager`, `Shader` has been bundled into `CompiledShader` + - `Unform` no longer takes in a `Shader` + - `glGetAttribLocation` is removed + - `glBindAttribLocation` -> `VertexFormat#bindAttributes` + - `setFromConfig` - Sets the uniform parameters given the values and count of another uniform configuration. +- `com.mojang.blaze3d.systems.RenderSystem` + - `setShader` now takes in the `CompiledShaderProgram`, or `ShaderProgram` + - `clearShader` - Clears the current system shader. + - `runAsFancy` is removed, handled internally by `LevelRenderer#getTransparencyChain` + - `setProjectionMatrix` now takes in a `ProjectionType` than just the `VertexSorting` + - `getVertexSorting` -> `getProjectionType`; not one-to-one, but the `VertexSorting` is accessible on the `ProjectionType` +- `com.mojang.blaze3d.vertex.VertexBuffer` + - `drawWithShader` will now noop when passing in a null `CompiledShaderProgram` + - `$Usage` -> `com.mojang.blaze3d.buffers.BufferUsage` +- `net.minecraft.client.Minecraft#getShaderManager` - Returns the manager that loads all the shaders and post effects. +- `net.minecract.client.renderer` + - `EffectInstance` class is removed, replaced by `CompiledShaderProgram` in most cases + - `GameRenderer` + - `get*Shader` -> `CoreShaders#*` + - `shutdownEffect` -> `clearPostEffect` + - `createReloadListener` -> `ShaderManager` + - `currentEffect` -> `currentPostEffect` + - `ItemBlockRenderTypes#getRenderType` no longer takes in a boolean indicating whether to use the translucent render type + - `ShaderInstance` -> `CompiledShaderProgram` + - `CHUNK_OFFSET` -> `MODEL_OFFSET` + - JSON shaders: `ChunkOffset` -> `ModelOffset` + - `getUniformConfig` - Returns the configuration of a uniform given its name. + - `LevelRenderer#graphicsChanged` is removed, handled internally by `LevelRenderer#getTransparencyChain` + - `PostChainConfig` - A configuration that represents how a post effect shader JSON is constructed. + - `PostPass` now takes in the `ResourceLocation` representing the output target instead of the in and out `RenderTarget`s or the `boolean` filter mode, the `CompiledShaderProgram` to use instead of the `ResourceProvider`, and a list of uniforms for the shader to consume + - No longer `AutoCloseable` + - `addToFrame` no longer takes in the `float` time + - `getEffect` -> `getShader` + - `addAuxAsset` -> `addInput` + - `process` -> `addToFrame` + - `$Input` - Represents an input of the post effect shader. + - `$TargetInput` - An input from a `RenderTarget`. + - `$TextureInput` - An input from a texture. + - `PostChain` constructor is now created via `load` + - No longer `AutoCloseable` + - `MAIN_RENDER_TARGET` is now public + - `getName` is removed, replaced with `ShaderProgram#configId` + - `process` no longer takes in the `DeltaTracker` + - `$TargetBundle` - Handles the getting and replacement of resource handles within the chain. + - `RenderType` + - `entityTranslucentCull`, `entityGlintDirect` is removed + - `armorTranslucent` - A render type which renders armor that can have a translucent texture. + - `ShaderDefines` - The defined values and flags used by the shader as constants. + - `ShaderManager` - The resource listener that loads the shaders. + - `ShaderProgram` - An identifier for a shader. + - `ShaderProgramConfig` - The definition of the program shader JSON. + - `Sheets#translucentCullBlockSheet` is removed + - `SkyRenderer` now implements `AutoCloseable` +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `getFoilBufferDirect` is removed, replaced by `getFoilBuffer` + - `ITEM_COUNT_BLIT_OFFSET` -> `ITEM_DECORATION_BLIT_OFFSET` + +## Entity Render States + +Entity models and renderers have been more or less completely reworked due to the addition of `EntityRenderState`s. `EntityRenderState`s are essentially data object classes that only expose the computed information necessary to render the `Entity`. For example, a `Llama` does not need to know what is has in its inventory, just that it has a chest to render in the layer. + +To start, you need to choose an `EntityRenderState` to use, or create one using a subclass if you need additional information passed to the renderer. The most common states to subclass is either `EntityRenderState` or `LivingEntityRenderState` for living entities. These fields should be mutable, as the state class is created only once for a renderer. + +```java +// Assuming MyEntity extends LivingEntity +public class MyEntityRenderState extends LivingEntityRenderState { + // An example of a field + boolean hasExampleData; +} +``` + +From there, you create the `EntityModel` that will render your `Entity`. The `EntityModel` has a generic that takes in the `EntityRenderState` along with taking in the `ModelPart` root, and optionally the `RenderType` factory as part of its super. The are no methods to implement by default; however, if you need to setup any kind of model movement, you will need to overrride `setupAnim` which modifies the `ModelPart`'s mutable fields using the render state. If your model does not have any animation, then a `Model$Simple` implementation can be used instead. This does not need anything implemented. + +```java +public class MyEntityModel extends EntityModel { + + public MyEntityModel(ModelPart root) { + super(root); + // ... + } + + @Override + public void setupAnim(MyEntityRenderState state) { + // Calls resetPose and whatever other transformations done by superclasses + super.setupAnim(state); + + // Perform transformations to model parts here + } +} +``` + +`EntityModel` also has three `final` methods from the `Model` subclass: `root`, which grabs the root `ModelPart`; `allParts`, which returns a list of all `ModelPart`s flattened; and `resetPose`, which returns the `ModelPart` to their default state. + +`LayerDefinition`s, `MeshDefinition`s, `PartDefinition`s, and `CubeDeformation`s remain unchanged in their implementation and construction for the `ModelLayerLocation` -> `LayerDefinition` map in `LayerDefinitions`. + +What about model transformations? For example, having a baby version of the entity, or where the model switches out altogether? In those cases, a separate layer definition is registered for each. For example, a Llama would have a model layer for the main Llama model, the baby model, the decor for both the adult and baby, and finally one for the spit. Since models are generally similar to one another with only a slight transformation, a new method was added to `LayerDefinition` to take in a `MeshTransformer`. `MeshTransformer`s are basically unary operators on the `MeshDefinition`. For baby models, a `BabyModelTransform` mesh transformer is provided, which can be applied via `LayerDefinition#apply`. + +```java +public class MyEntityModel extends EntityModel { + public static final MeshTransformer BABY_TRANSFORMS = ...; + + public static LayerDefinition create() { + // ... + } +} + +// Wherever the model layers are registered +ModelLayerLocation MY_ENTITY = layers.register("examplemod:my_entity"); +ModelLayerLocation MY_ENTITY_BABY = layers.register("examplemod:my_entity_baby"); + +// Wherever the layer definitions are registered +defns.register(MY_ENTITY, MyEntityModel.create()); +defns.register(MY_ENTITY_BABY, MyEntityModel.create().apply(MyEntityModel.BABY_TRANSFORMS)); +``` + +But how does the model know what render state to use? That's where the `EntityRenderer` comes in. The `EntityRenderer` has two generics: the type of the `Entity`, and the type of the `EntityRenderState`. The `EntityRenderer` takes in a `Context` object, similar to before. Additionally, `getTextureLocation` needs to be implemented, though this time it takes in the render state instead of the entity. The new methods to implement/override are `createRenderState` and `extractRenderState`. `createRenderState` constructs the default render state object. `extractRenderState`, meanwhile, populates the render state for the current entity being rendered. `extractRenderState` will need to be overridden if you are not using an existing render state class. + +Of course, there are also subclasses of the `EntityRenderer`. First, there is `LivingEntityRenderer`. This has an additional generic of the `EntityModel` being rendered, and takes that value in the constructor along with the shadow radius. This renderer also accepts `RenderLayer`s, which largely remain unchanged if you access the previous arguments through the render state. Then, there is the `MobRenderer`, which is what all entities extend. Finally, there is `AgeableMobRenderer`, which takes in two models - the adult and the baby - and decides which to render dependent on `LivingEntityRenderState#isBaby`. `AgeableMobRenderer` should be used with `BabyModelTransform` if the entity has a baby form. Otherwise, you will most likely use `MobRenderer` or `EntityRenderer`. + +```java +public class MyEntityRenderer extends AgeableMobRenderer { + + public MyEntityRenderer(EntityRendererProvider.Context ctx) { + super( + ctx, + new MyEntityModel(ctx.bakeLayer(MY_ENTITY)), // Adult model + new MyEntityModel(ctx.bakeLayer(MY_ENTITY_BABY)), // Baby model + 0.7f // Shadow radius + ); + + // ... + } + + @Override + public ResourceLocation getTextureLocation(MyEntityRenderState state) { + // Return entity texture here + } + + @Override + public MyEntityRenderState createRenderState() { + // Constructs the reusable state + return new MyEntityRenderState(); + } + + @Override + public void extractRenderState(MyEntity entity, MyEntityRenderState state, float partialTick) { + // Sets the living entity and entity render state info + super.extractRenderState(entity, state, partialTick); + // Set our own variables + state.hasExampleData = entity.hasExampleData(); + } +} + +// Wherever the entity renderers are registered +renderers.register(MyEntityTypes.MY_ENTITY, MyEntityRenderer::new); +``` + +- `net.minecraft.client.model` + - `AbstractBoatModel` - A model that assumes there is a `left_paddle` and `right_paddle` that is animated according to the boat's rowing time. + - `AgeableHierarchicalModel`, `ColorableAgeableListModel`, `AgeableListModel` -> `BabyModelTransform` + - `AnimationUtils` + - `animateCrossbowCharge` now takes in a `float` representing the charge duration and `int` representing the use ticks instead of a `LivingEntity` + - `swingWeaponDown` now takes in a `HumanoidArm` instead of a `Mob` + - `BabyModelTransform` - A mesh transformer that applies a baby scaled form of the model. + - `BoatModel` + - `createPartsBuilder` is removed + - `createChildren` -> `addCommonParts`, now private + - `createBodyModel` -> `createBoatModel`, `createChestBoatModel` + - `waterPatch` -> `createWaterPatch` + - `parts` is removed + - `ChestBoatModel` -> `BoatModel#createChestBoatModel` + - `ChestedHorseModel` class is removed and now purely lives in `LlamaModel` and `DonkeyModel` + - `ChestRaftModel` -> `RaftModel#createChestRaftModel` + - `ColorableHierarchicalModel` is now stored in the individual `EntityRenderState` + - `EntityModel` + - The generic now takes in a `EntityRenderState` + - `setupAnim` only takes in the `EntityRenderState` generic + - `prepareMobModel` is removed + - `copyPropertiesTo` is removed, still exists in `HumanoidModel` + - `HierarchicalModel` class is removed + - `HumanoidModel#rotLerpRad` -> `Mth#rotLerpRad` + - `ListModel` class is removed + - `Model` + - `renderToBuffer` is now final + - `root` - Returns the root `ModelPart`. + - `getAnyDescendantWithName` - Returns the first descendant of the root that has the specified name. + - `animate` - Give the current state and definition of the aninmation, transforms the model between the current time and the maximum time to play the animation for. + - `animateWalk` - Animates the walking cycle of the model. + - `applyStatic` - Applies an immediate animation to the specified state. + - `$Simple` - Constructs a simple model that has no additional animation. + - `ModelUtils` class is removed + - `ParrotModel#getState` -> `getPose`, now public + - `PlayerModel` no longer has a generic + - `renderEars` -> `PlayerEarsModel` + - `renderCape` -> `PlayerCapeModel` + - `getRandomModelPart` -> `getRandomBodyPart` + - `getArmPose` - Returns the arm pose of the player given its render state. + - `RaftModel#createBodyModel` -> `createRaftModel` + - `WardenModel#getTendrilsLayerModelParts`, `getHeartLayerModelParts`, `getBioluminescentLayerModelParts`, `getPulsatingSpotsLayerModelParts` now take in the `WardenRenderState` + - `WaterPatchModel` -> `BoatModel#createWaterPatch` and `Model$Simple` +- `net.minecraft.client.model.geom` + - `ModelLayerLocation` is now a record + - `ModelLayers` + - `createRaftModelName`, `createChestRaftModelName` is removed + - `createSignModelName` -> `createStandingSignModelName`, `createWallSignModelName` + - `createBoatModelName`, `createChestBoatModelName` is removed + - `ModelPart` + - `rotateBy` - Rotates the part using the given `Quaternionf`. + - `$Cube#polygons`, `$Polygon`, `$Vertex` is now public + - `PartPose` is now a record + - `translated` - Translates a pose. + - `withScale`, `scaled` - Scales a pose. +- `net.minecraft.client.model.geom.builders` + - `LayerDefinition#apply` - Applies a mesh transformer to the definition and returns a new one. + - `MeshDefinition#transformed` - Applies a transformation to the root pose and returns a new one. + - `MeshTransformer` - Transforms an existing `MeshDefinition` into a given form. + - `PartDefinition` + - `addOrReplaceChild` now has an overload that takes in a `PartDefinition` + - `clearChild` - Removes the child from the part definition. + - `getChildren` - Gets all the children of the current part. + - `transformed` - Applies a transformation to the current pose and returns a new one. +- `net.minecraft.client.renderer.entity` + - `AbstractBoatRenderer` - A boat renderer that contains methods for the boat model and any additions to the boat itself. + - `AgeableMobRenderer` - A mob renderer that takes in the baby and adult model. + - `BoatRenderer` now takes in a `ModelLayerLocation` instead of a `boolean` + - `EntityRenderDispatcher` now takes in a `MapRenderer` + - `render` no longer takes in the entity Y rotation + - `EntityRenderer` now takes in a generic for the `EntityRenderState` + - `getRenderOffset` only takes in the `EntityRenderState` + - `getBoundingBoxForCulling` - Returns the bounding box of the entity to determine whether to cull or not. + - `affectedByCulling` - Returns whether the entity can be culled. + - `render` only takes in the render state, along with the stack, buffer source, and packet light + - `shouldShowName` now takes in a `double` for the camera squared distance from the entity + - `getTextureLocation` is removed, being moved to the classes where it is used, like `LivingEntityRenderer` + - Subsequent implementations of `getTextureLocation` may be protected or private + - `renderNameTag` now takes in the render state instead of the entity and removes the partial tick `float` + - `getNameTag` - Gets the name tag from the entity. + - `getShadowRadius` now takes in the render state instead of the entity + - `createRenderState` - Creates the render state object. + - `extractRenderState` - Reads any data from the entity to the render state. + - `EntityRendererProvider$Context` takes in the `MapRenderer` instead of the `ItemInHandRenderer` + - `LivingRenderer` + - `isShaking` now takes in the render state instead of the entity + - `setupRotations` now takes in the render state instead of the entity + - `getAttackAnim`, `getBob` are now within the render state + - `getFlipDegrees` no longer takes in the entity + - `getWhiteOverlayProgress` now takes in the render state instead of the entity and no longer takes in the entity Y rotation + - `scale` now takes in the render state instead of the entity and no longer takes in the entity Y rotation + - `shouldShowName` now takes in a `double` representing the squared distance to the camera + - `getShadowRadius` now takes in the render state instead of the entity + - `RaftRenderer` - A raft renderer that implements the `AbstractBoatRenderer`. + - `RenderLayerParent#getTextureLocation` is removed +- `net.minecraft.client.renderer.entity.layers` + - `EnergySwirlLayer#isPowered` - Returns whether the energy is powered. + - `CustomHeadLayer` and `#translateToHead` takes in a `CustomHeadLayer$Transforms` instead of a scaling information hardcoding the transform + - `PlayerItemInHandRenderer` takes in an `ItemRenderer` instead of a `ItemInHandRenderer` + - `RenderLayer` takes in an `EntityRenderState` generic instead of an `Entity` generic + - `coloredCutoutModelCopyLayerRender` takes in a single `EntityModel` with the state info bundled into the render state + - `renderColoredCutoutModel` takes in non-generic forms of the rendering information, assuming a `LivingEntityRenderState` + - `getTextureLocation` is removed, instead being passed directly into the appropriate location + - `render` now takes in the render state instead of the entity and parameter information + - `SaddleLayer` has a constructor to take in a baby model. + - `SheepFurLayer` -> `SheepWoolLayer` + - `StuckInBodyLayer` now takes in the model to apply the stuck objects to, the texture of the stuck objects, and the placement style of the objects + - `numStuck` now takes in the render state instead of the entity + - `renderStuckItem` is now private + - `WardenEmissiveLayer` -> `LivingEntityEmissiveLayer`, a more generalized implementation +- `net.minecraft.client.renderer.entity.player.PlayerRenderer` + - `renderRightHand`, `renderLeftHand` now take in a `ResourceLocation` instead of the `AbstractClientPlayer` and a `boolean` whether to render the left and/or right sleeve + - `setupRotations` now takes in the render state instead of the entity and parameter information +- `net.minecraft.world.entity` + - `AnimationState#copyFrom` - Copies the animation state from another state. + - `Entity` + - `noCulling` -> `EntityRenderer#affectedByCulling` + - `getBoundingBoxForCulling` -> `EntityRenderer#getBoundingBoxForCulling` + - `LerpingModel` class is removed + - `PowerableMob` class is removed + +### Model Baking + +`UnbakedModel`s now have a different method to resolve any dependencies. Instead of getting the dependencies and resolving the parents, this is now done through a single method called `resolveDependencies`. This method takes in the `Resolver`. The `Resolver` is responsible for getting the `UnbakedModel` for the `ResourceLocation`. + +```java +// For some UnbakedModel instance +public class MyUnbakedModel implements UnbakedModel { + + @Nullable + protected ResourceLocation parentLocation; + @Nullable + protected UnbakedModel parent; + private final List overrides; + + // ... + + @Override + public void resolveDependencies(UnbakedModel.Resolver resolver) { + // Get parent model for delegate resolution + if (this.parentLocation != null) { + this.parent = resolver.resolve(this.parentLocation); + } + } +} +``` + +- `net.minecraft.client.renderer.block` + - `BlockModel#getDependencies`, `resolveParents` -> `resolveDependencies` + - `BlockModelDefintion` now takes in a `MultiPart$Definition`, no `List` constructor exists + - `fromStream`, `fromJsonElement` no longer take in a `$Context` + - `getVariants` is removed + - `isMultiPart` is removed + - `instantiate` -> `MultiPart$Definition#instantiate` + - `MultiVariant` is now a record + - `UnbakedBlockStateModel` - An interface that represents a block state model, contains a single method to group states together with the same model. + - `VariantSelector` - A utility for constructing the state definitions from the model descriptor. +- `net.minecraft.client.renderer.block.model` + - `BlockModel` + - `MISSING_MATERIAL` - The material of the missing block texture. + - `bake` no longer takes in the `ModelBaker` and `BlockModel` + - `$LoopException` class is removed +- `net.minecraft.client.renderer.block.model.multipart.MultiPart` now implements `UnbakedBlockStateModel` + - `getSelectors` -> `$Definition#selectors` + - `getMultiVariants` ->` $Definition#getMultiVariants` +- `net.minecraft.client.resources.model` + - `BakedModel#getOverrides` -> `overrides`, method is defaulted to an empty override + - `BlockStateModelLoader` only takes in the missing unbaked model + - `loadAllBlockStates` is removed + - `definitionLocationToBlockMapper` - Gets the state definition from a given resource location + - `loadBlockStateDefinitions` -> `loadBlockStateDefinitionStack` + - `getModelGroups` -> `ModelGroupCollector` + - `$LoadedJson` -> `$LoadedBlockModelDefinition` + - `$LoadedModel` is now public + - `$LoadedModels` - A record which maps a model location to a loaded model. + - `BuiltInModel` no longer takes in the `ItemOverrides` + - `DelegateBakedModel` - A utility implementation that delegates all logic to the supplied `BakedModel` + - `Material#buffer` takes in another `boolean` that handles whether to apply the glint + - `MissingBlockModel` - The missing model for a block. + - `ModelBaker#getModel` is removed, implementation in `ModelBakery$ModelBakerImpl` is private + - `ModelBakery` only takes in the top models, all unbacked models, and the missing model + - `BUILTIN_SLASH` -> `SpecialModels#builtinModelId` + - `BUILTIN_SLASH_GENERATED` -> `SpecialModels#BUILTIN_GENERATED` + - `BUILTIN_BLOCK_ENTITY` -> `SpecialModels#BUILTIN_BLOCK_ENTITY` + - `MISSING_MODEL_LOCATION` -> `MissingBlockModel#LOCATION` + - `MISSING_MODEL_VARIANT` -> `MissingBlockModel#VARIANT` + - `GENERATION_MARKER` -> `SpecialModels#GENERATED_MARKER` + - `BLOCK_ENTITY_MARKER` -> `SpecialModels#BLOCK_ENTITY_MARKER` + - `getModelGroups` -> `ModelGroupCollector` + - `ModelDiscovery` - A loader for block and item models, such as how to resolve them when reading. + - `ModelGroupCollector` - A blockstate collector meant to map states to their associated block models. + - `ModelResourceLocation#vanilla` is removed + - `MultiPartBakedModel` fields are now obtained from the first model in the selector and are private + - `$Builder` class is removed, replaced with `$Selector` + - `SimpleBakedModel`, `SimpleBakedModel$Builder` no longer takes in the `ItemOverrides` + - `SpecialModels` - A utility for builtin models. + - `UnbakedModel` + - `getDependencies`, `resolveParents` -> `resolveDependencies` + - `bake` is no longer nullable + - `$Resolver` - Determines how the unbaked model should be loaded when on top or on override. + - `WeightedBakedModel` now takes in a `SimpleWeightedRandomList` rather than a list of `WeightedEntry`s + +## Equipments and Items, Models and All + +Equipments and Items have had a major overhaul, most of which is spread throughout this documentation. This is some of the core change which, while they are important, do not deserve more than a cursory explanation due to their ease of change. + +### Item Names and Models + +The item name and model is now set directly within the properties using the `ITEM_NAME` and `ITEM_MODEL` data components, respectively. By default, this will use the same name and model location as previously, but these can be set via `Item$Properties#overrideDescription` and `#overrideModel`. `overrideDescription` takes in the translation key to use. There is also `useBlockDescriptionPrefix` and `useItemDescriptionPrefix` to change it to the default block and item translation keys, respectively. `overrideModel` takes in the relative `ResourceLocation` of the model JSON. For example, a value of `examplemod:example_item` will map to a `ModelResourceLocation` of `examplemod:example_item#inventory`. This is intended to link to the model JSON at `assets/examplemod/models/item/example_item.json`. + +> There is a slight quirk to item models. The same key can also point to `assets/examplemod/models/example_item.json` if the modder decides to for a special model to load at that location under the `inventory` variant. So, it is recommended to avoid having model names with the same name in the root `models` and `models/item` subdirectory. + +### Enchantable, Repairable Items + +The enchantment value and repair item checks are being replaced with data components: `DataComponents#ENCHANTABLE` and `DataComponents#REPAIRABLE`, respectively. These can be set via the `Item$Properties#enchantable` and `#repairable`. As a result, `Item#getEnchantmentValue` and `isValidRepairItem` are removed. + +### Elytras -> Gliders + +Any item can act similarly to an elytra if they have the `DataComponents#GLIDER` value equipped. This essentially functions as a flag to indicate that the item can be used to glide. This works only if the item also has a `DataComponents#EQUIPPABLE` entry. + +```java +new Item( + new Item.Properties() + .component(DataComponents.GLIDER, Unit.INSTANCE) // Sets as a glider + .component(DataComponents.EQUIPPABLE, /*...*/) // Determines the slot to check whether it can be used +); +``` + +### Tools, via Tool Materials + +`Tier`s within items have been replaced with `ToolMaterial`, which better handles the creation of tools and swords without having to implement each method manually. `ToolMaterial` takes in the same arguments as `Tier`, just as parameters to a single constructor rather than as implementable methods. From there, the `ToolMaterial` is passed to the `DiggerItem` subtypes, along with two floats representing the attack damage and attack speed. Interally, `ToolMaterial#apply*Properties` is called, which applies the `ToolMaterial` info to the `DataComponents#TOOL` and the attributes from the given `float`s. + +```java +// Some tool material +public static final ToolMaterial WOOD = new ToolMaterial( + BlockTags.INCORRECT_FOR_WOODEN_TOOL, // Tier#getIncorrectBlocksForDrops + 59, // Tier#getUses + 2.0F, // Tier#getSpeed + 0.0F, // Tier#getAttackDamageBonus + 15, // Tier#getEnchantmentValue + ItemTags.WOODEN_TOOL_MATERIALS // Tier#getRepairIngredient +); + +// When constructing the digger item subtype +new PickaxeItem( + WOOD, // Tool material + 1.0f, // Attack damage + -2.8f, // Attack speed + new Item.Properties() +) +``` + +## Armor Materials, Equipment, and Model (Textures) + +This is, by far, the largest change outside of consumables to items. `ArmorMaterial`s have effectively been made obsolete, as almost all of the logic is handled within data components, and attached to some resource pack JSON to load the associated textures. It is annoyingly complicated to understand at first glance, but is rather intuitive once you are familiar with the process. + +### `ArmorMaterial` + +`ArmorMaterial` is essentially a record that converts a list of properties to their proper location on the data components, NOT a registry object. This is done by passing in the item properties and an additional setting to either `#humanoidProperties` or `#animalProperties`. These settings should be familiar, as they remained unchanged from the previous version, the only difference is that they now specify a 'model id', which we will go into below. The armor material is used in conjunction with the `ArmorType`: an enum which defines the equipment slot the armor is placed into, the unit durability of each armor type, and the name (which is only used to construcct the attribute modifier id). + +```java +ArmorMaterial exampleArmorMaterial = new ArmorMaterial( + 15, // The scalar durability to multiply the armor type against + // A map of ArmorType -> half armor bars to apply to the entity ARMOR attribute + // Should be set for all ArmorTypes + Util.make(new EnumMap<>(ArmorType.class), map -> { + map.put(ArmorType.BOOTS, 2); + map.put(ArmorType.LEGGINGS, 5); + map.put(ArmorType.CHESTPLATE, 6); + map.put(ArmorType.HELMET, 2); + map.put(ArmorType.BODY, 5); + }, + 25, // The enchantment value of the armor + SoundEvents.ARMOR_EQUIP_IRON, // The holder wrapped sound event on what sound to make when the item is equipped + 0f, // The ARMOR_TOUGHNESS attribute value + 2f, // The KNOCKBACK_RESISTANCE attribute value, + ItemTags.REPAIRS_DIAMOND_ARMOR, // An item tag representing the items that can repair this armor + // The relative location of the EquipmentModel JSON + // Points to assets/examplemod/models/equipment/example_armor_material.json + ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material") +) +``` + +With the `ArmorMaterial`, this is either applied to the item properties by calling `humanoidProperties`, to apply the armor to a specific `ArmorType`; or `animalProperties` to apply the armor to the `BODY` and only allow specific entities to wear them. + +Does this mean that `ArmorItem` and `AnimalArmorItem` are effectively pointless? For `AnimalArmorItem`, this can be argued. The only thing that `AnimalArmorItem` does is have a `$BodyType` parameter, which means that the armor can only be applied to a horse or a wolf, and specifies the item breaking sound. `ArmorItem`, on the other hand, only has one specific usecase: determining whether the item can be taken off or swapped. This implicity checks the currently wearing armor item to see whether it can't be taken off (via `PREVENT_ARMOR_CHANGE` enchantment) and calculating the properties on the replacing armor material so that any hotswaps will only improve their wearer's armor attribute values. + +Let's go one level deeper. + +### The Data Components + +`ArmorMaterial` specifies eight data components to apply to item: + +- `MAX_DAMAGE` - Set to the maximum durability of the item multiplied by the `ArmorType` unit durability +- `MAX_STACK_SIZE` - Set to 1 +- `DAMAGE` - Set to 0 +- `ATTRIBUTE_MODIFIERS` - Sets `ARMOR` and `ARMOR_TOUGHNESS` attributes, and `KNOCKBACK_RESISTANCE` when greater than 0 +- `ENCHANTABLE` - Set to the enchantment value (not set when calling `animalProperties`) +- `REPAIRABLE` - Set to the `HolderSet` of the tag key representing the repairing ingredients +- `EQUIPPABLE` - Sets the slot, equip sound, model id, what entities can wear the item, and whether it is dispensible + +Everything but `EQUIPPABLE` has already been explained above or has been around from a prior version, so this primer will only focus on `EQUIPPABLE` from now on. + +### Equippable + +`Equippable`, which used to be an interface, is now a data component that contains how an entity can equip this item and if the equipment should be rendered. Because of this, an item can only be equipped to a single slot. This can be done using the `Equippable` constructor or through the builder via `Equippable#builder`. + +```java +new Item( + new Item.Properties() + .component(DataComponents.EQUIPPABLE, new Equippable( + EquipmentSlot.HEAD, // The slot the item can be equipped to + SoundEvents.ARMOR_EQUIP_IRON, // The sound to play when equipping the item + // The relative location of the EquipmentModel JSON + // Points to assets/examplemod/models/equipment/example_armor_material.json + // When set to an empty optional, the item does not attempt to render as equipment + Optional.of(ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material")), + // The relative location over the texture to overlay on the player screen when wearing + // Points to assets/examplemod/textures/example_overlay.png + // When set to an empty optional, does not render on the player screen + Optional.of(ResourceLocation.withDefaultNamespace("examplemod", "example_overlay")), + // A HolderSet of entities (direct or tag) that can equip this item + // When set to an empty optional, any entity can equip this item + Optional.of(HolderSet.direct(EntityType::builtInRegistryHolder, EntityType.ZOMBIE)), + // Whether the item can be equipped when dispensed from a dispenser + true, + // Whether the item can be swapped off the player during a quick equip + false, + // Whether the item should be damaged when attacked (for equipment typically) + // Must also be a damageable item + false + )) +); +``` + +### Equipment Models? + +So, as mentioned previously, `Equippable` items, and by extension the `ArmorMaterial` delegate, can specify a model id to determine how the equipment should render. However, what does this id link to? Well, it points to an `EquipmentModel` serialized as a JSON within `models/equipment` of the resource pack. This JSON defines the layers and textures of the equippable item to render. This does NOT specify the model, making the record a misnomer. It is better to think of this as the equipment textures applied to the passed in model. + +`EquipmentModel` functions as a more feature generic version of the previous `ArmorMaterial$Layer`, which has been removed. Each `EquipmentModel` is functionally a map of `$LayerType`s to a list of `$Layer` to render. + +A `$LayerType` is an enum representing the layer to render the equipment model as. While these are non-specific, they are implemented and read by specific entity renderer through the layer renderers. For example, `HUMANOID` is used by the `HumanoidArmorLayer` to render the head, chest, and feet; so any usage of `HUMANOID` will be rendered using that system. Another example is `WOLF_BODY` is used by `WolfArmorLayer` to render the body armor. As such, if using existing layer types (which is the only scenario unless your mod loader supports enum extensions), make sure that they are compatible with the existing renderers in place. + +The `$Layer` list specifies the texture and dyeable options to use when rendering over the passed in model. The first parameter specifes the texture location, relative to `textures/entity/equipment`. The second parameter specifies an optional indicating whether the texture can be tinted (stored via the `ItemTags#DYEABLE` in conjunction with the `DYED_COLOR` data component). When specified, an optional color can be specified for when the item is not dyed. If empty, the armor will be invisible when not dyed. The final parameter indicates whether it should use the texture provided to the renderer instead, such as when rendering a custom elytra texture for the player. + +```json5 +// In assets/examplemod/models/equipment/example_armor_material.json +{ + // The layer map + "layers": { + // The serialized name of the EquipmentModel$LayerType to apply to + "humanoid": [ + // A list of layers to render in the order provided in the list + { + // The relative texture of the layer + // Points to assets/examplemod/textures/entity/equipment/example.png + "texture": "examplemod:example", + // When specified, allows the texture to be tinted the color in DYED_COLOR data component + // Otherwise, cannot be tinted + "dyeable": { + // An RGB value (always opaque color) + // 0x7683DE as decimal + // When not specified, set to 0 (meaning transparent or invisible) + "color_when_undyed": 7767006 + }, + // When true, uses the texture passed into the layer renderer instead + "use_player_texture": true + } + // ... + ] + // ... + } +} +``` + +```java +EquipmentModel.builder() + .addLayers(EquipmentModel.LayerType.HUMANOID, new EquipmentModel.Layer( + // The relative texture of the layer + // Points to assets/examplemod/textures/entity/equipment/example.png + ResourceLocation.fromNamespaceAndPath("examplemod", "example"), + // When specified, allows the texture to be tinted the color in DYED_COLOR data component + // Otherwise, cannot be tinted + Optional.of(new EquipmentModel.Dyeable( + // An RGB value (always opaque color) + // When not specified, set to 0 (meaning transparent or invisible) + Optional.of(0x7683DE) + )), + // When true, uses the texture passed into the layer renderer instead + true + )/*, ... */) + .build(); +``` + +The equipment model is then rendered by calling `EquipmentLayerRenderer#renderLayers` in the render function of an `EntityRenderer` or `RenderLayer`. `EquipementLayerRenderer` is passed in as part of the render context via `EntityRendererProvider$Context#getEquipmentRenderer`. + +```java +// In some render method where EquipmentLayerRenderer equipmentLayerRenderer is a field +this.equipmentLayerRenderer.renderLayers( + // The layer type to render + EquipmentModel.LayerType.HUMANOID, + // The model id representing the EquipmentModel JSON + // This would be set in the `EQUIPPABLE` data component via `model` + ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material"), + // The model to apply the textures to + // These are usually separate models from the entity model + // and are separate ModelLayers linking to a LayerDefinition + model, + // The item stack representing the item being rendered as a model + // This is only used to get the dyeable, foil, and armor trim information + stack, + // The stack used to render the model in the correct location + poseStack, + // The source of the buffers to get the vertex consumer of the render type + bufferSource, + // The packed light texture + lighting, + // An absolute path of the texture to render when use_player_texture is true for one of the layer if not null + ResourceLocation.fromNamespaceAndPath("examplemod", "textures/other_texture.png"); +) +``` + +### Technical Changes to Items + +- `net.minecraft.client.Minecraft#getEquipmentModels` - Gets the `EquipmentModelSet` that contains the current equipment model textures. +- `net.minecraft.client.gui.GuiGraphics#renderTooltip`, `renderComponentTooltip` now has a parameter to take in the relative directory of the background and frame textures of the tooltip, or the default if `null` +- `net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil#renderTooltipBackground` now has a parameter to take in the relative directory of the background and frame textures of the tooltip, or the default if `null` +- `net.minecraft.client.renderer.block.model` + - `ItemOverrides` -> `BakedOverrides` + - The construct no longer takes in the parent `BlockModel` + - `resolve` -> `findOverride`, does not take in the fallback model + - `ItemOverride`, `ItemOverride$Predicate` is now a record + - `getPredicates` is removed, use `predicates` + - `getModel` -> `model` +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher` now takes in the `EquipmentModelSet` + - `EntityRendererProvider$Context` + - `getEquipmentModels` - Gets the current equipment textures. + - `getEquipmentRenderer` - Gets the renderer for the equipment. + - `ItemRenderer` no longer takes in the `Minecraft` instance and `TextureManager` + - `TRIDENT_MODEL`, `SPYGLASS_MODEL` is now public + - `TRIDENT_IN_HAND_MODEL`, `SPYGLASS_IN_HAND_MODEL` is removed + - `getItemModelShaper` is removed + - `renderBundleWithSelectedItem` -> `renderBundleItem`, not one-to-one +- `net.minecraft.client.renderer.entity.layers` + - `CapeLayer` now takes in the `EquipmentModelSet` + - `ElytraLayer` -> `WingsLayer` + - The constructor now takes in the `EquipmentLayerRenderer` + - `EquipmentLayerRenderer` - A renderer for equipment layers on the provided model. + - `HorseArmorLayer` now takes in the `EquipmentLayerRenderer` + - `HumanoidArmorLayer` now teaks in the `EquipmentLayerRenderer` instead of the `ModelManager` + - `shouldRender` - Returns whether the equippable item should be rendered in the given slot. + - `LlamaDecorLayer` now takes in the `EquipmentLayerRenderer` + - `WolfArmorLayer` now takes in the `EquipmentLayerRenderer` +- `net.minecraft.client.renderer.entity.player.PlayerRenderer#getArmPose` is now private, replaced publically with a method that only takes in the `HumanoidArm` and `PlayerRenderState` +- `net.minecraft.client.resources.model` + - `EquipmentModelSet` - A resource listener that loads the `EquipmentModel`s from `models/equipment`. + - `ItemModel` - A model for an item. +- `net.minecraft.core.component.DataComponents` + - `ITEM_MODEL` - Returns the model of the item. The `item/` is stripped, meaning that `minecraft:apple` points to `minecraft/textures/models/item/apple.json`. + - `EQUIPPABLE` - Indicates that an item is equippable in the given slot. Also contains the model to render for the equipment. + - `GLIDER` - Indicates that an item can be used to glide across the air. Must also be used in conjunction with `EQUIPPABLE`. + - `TOOLTIP_STYLE` - Determines the relative location representing how the tooltip should render +- `net.minecraft.core.dispenser.EquipmentDispenseItemBehavior` - Handles how equipment is dispensed from a dispenser. +- `net.minecraft.core.registries.BuiltInRegistries#`, `Registries#ARMOR_MATERIAL` is no longer a registry, handled purely through data components +- `net.minecraft.world.entity` + - `EquipmentSlot#getFilterFlag` -> `getId` + - Also a method `getFilterBit` for converting the ID to a bit mask + - `LivingEntity` + - `canContinueToGlide` -> `canGlide`, no longer takes in the `ItemStack` + - `canTakeItem` replaced by `DataComponents#EQUIPPABLE` + - `canEquipWithDispenser` - Returns whether the stack can be equipped when spat from a dispenser. + - `canDispenserEquipIntoSlot` - An entity override that specifies whether a dispenser can put eequipment into a given slot. + - `isEquippableInSlot` - Returns whether the stack can be equipped in the given slot. + - `canGlideUsing` - Whether the entity can glide with the stack in the provided slot. + - `Mob` + - `canReplaceCurrentItem` now takes in the `EquipmentSlot` + - `isBodyArmorItem` replaced by `DataComponents#EQUIPPABLE` +- `net.minecraft.world.entity.animal.horse` + - `Horse#isBodyArmorItem` replaced by `DataComponents#EQUIPPABLE` + - `Llama#isBodyArmorItem`, `getSwag` replaced by `DataComponents#EQUIPPABLE` +- `net.minecraft.world.item` + - `AnimalArmorItem` no longer extends `ArmorItem` + - The constructor no longer takes in a boolean indicating the overlay texture, as that is now part of the `EquipmentModel` + - The constructor can take in an optional `Holder` of the equip sound + - The constructor can take in a `boolean` representing whether the armor should be damaged if the entity is hurt + - `$BodyType` no takes in the allowed entities to wear the armor rather than the path factory to the texture + - `ArmorItem` is no longer equipable + - Basically functions as an item class where its only remaining usage is to prevent armor change when enchanted and get the associated attributes + - `$Type` -> `ArmorType` + - `ArmorMaterial` -> `.equipment.ArmorMaterial` + - Bascially a dummy record to easily handle applying the associated data components (`MAX_DAMAGE`, `ATTRIBUTE_MODIFIERS`, `ENCHANTABLE`, `EQUIPPABLE`, `REPAIRABLE`) + - `ArmorMaterials` -> `.equipment.ArmorMaterials` + - `BookItem`, `EnchantedBookItem` -> `DataComponents#WRITTEN_BOOK_CONTENT` + - `BundleItem` now takes in a `ResourceLocation` for the model rather than just strings + - `$Mutable#setSelectedItem` -> `toggleSelectedItem` + - `ComplexItem` class is removed + - `ElytraItem` class is removed, now just and item with `DataComponents#GLIDER` + - `Equippable` -> `.equipment.Equippable`, now a record which defines how an item can be equipped + - `FoodOnAStackItem` parameter order has been switched + - `InstrumentItem` parameter order has been switched + - `Item` + - `descriptionId` is now protected + - `getDescription` -> `getName` + - `getOrCreateDescriptionId` is removed + - `getDescriptionId(ItemStack)` -> `DataComponents#ITEM_NAME` + - `isEnchantable`, `getEnchantmentValue` is removed + - `isValidRepairItem` is removed + - `getDefaultAttributeModifiers` is removed + - `getDamageSource` - Returns the damage source this item makes against the `LivingEntity` + - `isComplex` is removed + - `$Properties` + - `equippable` - Sets an equippable component, defining how an item can be equipped + - `equippableUnswappable` - Sets an equippable commponent that cannot be swapped via a key shortcut. + - `overrideDescription` - Sets the translation key of the item. + - `overrideModel` - Sets the model resource location. + - `getCraftingRemainingItem`, `hasCraftingRemainingItem` -> `getCraftingRemainder` + - `ItemNameBlockItem` class is removed, just a normal `Item` `useItemDescriptionPrefix` as a property + - `ItemStack` + - `ITEM_NON_AIR_CODEC` -> `Item#CODEC` + - `isValidRepairItem` - Returns whether the stack can be repaired by this stack. + - `nextDamageWillBreak` - Checks if the next damage taken with break the item. + - `getDescriptionId` -> `getItemName`, not one-to-one, as now it returns the full component + - `ShieldItem` no longer implements `Equippable`, passed in through `DataComponents#EQUIPPABLE` + - `SignItem` parameter order has been switched + - `SmithingTemplateItem` parameter order has been swtiched, removes `FeatureFlag`s + - `StandingAndWallBlockItem` paramter order has been switched + - `AxeItem` now takes in two floats representing the attack damage and attack speed + - `DiggerItem` now takes in two floats representing the attack damage and attack speed + - `createAttributes` -> `ToolMaterial#applyToolProperties` + - `HoeItem` now takes in two floats representing the attack damage and attack speed + - `PickaxeItem` now takes in two floats representing the attack damage and attack speed + - `ShovelItem` now takes in two floats representing the attack damage and attack speed + - `SwordItem` now takes in two floats representing the attack damage and attack speed + - `createAttributes` -> `ToolMaterial#applySwordProperties` + - `Tier` -> `ToolMaterial` + - `TieredItem` class is removed + - `Tiers` constants are stored on `ToolMaterial` +- `net.minecraft.world.item.alchemy.Potion` name is now required + - `getName` -> `name`, not one-to-one as this is stored directly on the potion without any other processing +- `net.minecraft.world.item.armortrim.*` -> `.equipment.trim.*` +- `net.minecraft.world.item.component` + - `Tool` methods that return `Tool$Rule` now only take the `HolderSet` of blocks and not a list or tag key + - `DamageResistant` - A component that holds a tag of damage types the item is resistant to as an entity or being worn +- `net.minecraft.world.item.enchantment` + - `Enchantable` - The data component object for the item's enchantment value. + - `Repairable` - The data component object for the items that can repair this item. +- `net.minecraft.world.level.block` + - `AbstractSkullBlock` no longer implements `Equippable` + - `EquipableCarvedPumpkinBlock` class is removed, as replaced by `DataComponents#EQUIPPABLE` + - `WoolCarpetBlock` no longer implements `Equippable` + +## Interaction Results + +`InteracitonResult`s have been completely modified to encompass everything to one series of sealed implementations. The new implementation of `InteractionResult` combines both `InteractionResultHolder` and `ItemInteractionResult`, meaning that all uses have also been replcaed. + +`InteractionResult` is now an interface with four implementations depending on the result type. First there is `$Pass`, which indicates that the interaction check should be passed to the next object in the call stack. `$Fail`, when used for items and blocks, prevents anything further in the call stack for executing. For entities, this is ignored. Finally, `$TryEmptyHandInteraction` tells the call stack to try to apply the click with no item in the hand, specifically for item-block interactions. + +There is also `$Success`, which indicates that the interaction was successful and can be consumed. A success specifies two pieces of information: the `$SwingSource`, which indicates where the source of the swing originated from (`CLIENT` or `SERVER`) or `NONE` if not specified, and `$ItemContext` that handles whether there was an iteraction with the item in the hand, and what the item was transformed to. + +None of the objects should be directly initialized. The implementations are handled through six constants on the `InteractionResult` interface: + +- `SUCCESS` - A `$Success` object that swings the hand on the client. +- `SUCCESS_SERVER` - A `$Success` object that swings the hand on the server. +- `CONSUME` - A `$Success` object that does not swing the hand. +- `FAIL` - A `$Fail` object. +- `PASS` - A `$Pass` object. +- `TRY_WITH_EMPTY_HAND` - A `$TryEmptyHandInteraction` object. + +```java +// For some method that returns an InteractionResult +return InteractionResult.PASS; +``` + +For success objects, if the item interaction should transform the held stack, then you call `$Success#heldItemTransformedTo`, or `$Success#withoutItem` if no item was used for the interaction. + +```java +// For some method that returns an InteractionResult +return InteractionResult.SUCCESS.heldItemTransformedTo(new ItemStack(Items.APPLE)); + +// Or +return InteractionResult.SUCCESS.withoutItem(); +``` + +- `net.minecraft.core.cauldron.CauldronInteraction` + - `interact` now returns an `InteractionResult` + - `fillBucket`, `emptyBucket` now returns an `InteractionResult` +- `net.minecraft.world` + - `InteractionResultHolder`, `ItemInteractionResult` -> `InteractionResult` +- `net.minecraft.world.item` + - `Equipable#swapWithEquipmentSlot` now returns an `InteractionResult` + - `Item#use`, `ItemStack#use` now returns an `InteractionResult` + - `ItemUtils#startUsingInstantly` now returns an `InteractionResult` + - `JukeboxPlayable#tryInsertIntoJukebox` now returns an `InteractionResult` +- `net.minecraft.world.level.block.state.BlockBehaviour#useItemOn`, `$BlockStateBase#useItemOn` now returns an `InteractionResult` + +## Instruments, the Datapack Edition + +`Instrument`s (not `NoteBlockInstrument`s) are now a datapack registry, meaning they must be defined in JSON or datagenned. + +```json5 +// In data/examplemod/instrument/example_instrument.json +{ + // The registry name of the sound event + "sound_event": "minecraft:entity.arrow.hit", + // How many seconds the instrument is used for + "use_duration": 7.0, + // The block range, where each block is 16 units + "range": 256.0, + // The description of the instrument + "description": { + "translate": "instrument.examplemod.example_instrument" + }, +} +``` + +```java +// For some RegistrySetBuilder builder +builder.add(Registries.INSTRUMENT, bootstrap -> { + bootstrap.register( + ResourceKey.create(Registries.INSTRUMENT, ResourceLocation.fromNamespaceAndPath("examplemod", "example_instrument")), + new Instrument( + BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.ARROW_HIT), + 7f, + 256f, + Component.translatable(Util.makeDescriptionId("instrument", ResourceLocation.fromNamespaceAndPath("examplemod", "example_instrument"))) + ) + ) +}); +``` + +- `net.minecraft.world.item` + - `Instrument` takes in a `float` for the use duration and a `Component` description. + - `InstrumentItem#setRandom` is removed + +## Trial Spawner Configurations, now in Datapack Form + +`TrialSpawnConfig` are now a datapack registry, meaning they must be defined in JSON or datagenned. + +```json5 +// In data/examplemod/trial_spawner/example_config.json +{ + // The range the entities can spawn from the trial spawner block + "spawn_range": 2, + // The total number of mobs that can be spawned + "total_mobs": 10.0, + // The number of mobs that can be spawned at one time + "simultaneous_mobs": 4.0, + // The number of mobs that are added for each player in the trial + "total_mobs_added_per_player": 3.0, + // The number of mobs that can be spawned at one time that are added for each player in the trial + "simultaneous_mobs_added_per_player": 2.0, + // The ticks between each spawn + "ticks_between_spawn": 100, + // A weighted list of entities to select from when spawning + "spawn_potentials": [ + { + // The SpawnData + "data": { + // Entity to spawn + "entity": { + "id": "minecraft:zombie" + } + }, + // Weighted value + "weight": 1 + } + ], + // A weight list of loot tables to select from when the reward is given + "loot_tables_to_eject": [ + { + // The loot key + "data": "minecraft:spawners/ominous/trial_chamber/key", + // Weight value + "weight": 1 + } + ], + // Returns the loot table to use when the the trial spawner is ominous + "items_to_drop_when_ominous": "minecraft:shearing/bogged" +} +``` + +```java +// For some RegistrySetBuilder builder +builder.add(Registries.TRIAL_SPAWNER_CONFIG, bootstrap -> { + var entityTag = new CompoundTag(); + entityTag.putString("id", BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ZOMBIE).toString()); + + bootstrap.register( + ResourceKey.create(Registries.INSTRUMENT, ResourceLocation.fromNamespaceAndPath("examplemod", "example_config")), + TrialSpawnerConfig.builder() + .spawnRange(2) + .totalMobs(10.0) + .simultaneousMobs(4.0) + .totalMobsAddedPerPlayer(3.0) + .simultaneousMobsAddedPerPlayer(2.0) + .ticksBetweenSpawn(100) + .spawnPotentialsDefinition( + SimpleWeightedRandomList.single(new SpawnData(entityTag, Optional.empty(), Optional.empty())) + ) + .lootTablesToEject( + SimpleWeightedRandomList.single(BuiltInLootTables.SPAWNER_OMINOUS_TRIAL_CHAMBER_KEY) + ) + .itemsToDropWhenOminous( + BuiltInLootTables.BOGGED_SHEAR + ) + .build() + ) +}); +``` + +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner` now takes in a `Holder` of the `TrialSpawnerConfig` + - `canSpawnInLevel` now takes in a `ServerLevel` + - `TrialSpawnerConfig` + - `CODEC` -> `DIRECT_CODEC` + - `$Builder`, `builder` - A builder for a trial spawner configuration + +## Recipe Providers, the 'not actually' of Data Providers + +`RecipeProvider` is no longer a `DataProvider`. Instead, a `RecipeProvider` is constructed via a `RecipeProvider$Runner` by implementing `createRecipeProvider`. The name of the provider must also be specified. + +```java +public class MyRecipeProvider extends RecipeProvider { + + // The parameters are stored in protected fields + public MyRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + super(registries, output); + } + + @Override + protected void buildRecipes() { + // Register recipes here + } + + // The runner class, this should be added to the DataGenerator as a DataProvider + public static class Runner extends RecipeProvider.Runner { + + public Runner(PackOutput output, CompletableFuture registries) { + super(output, registries) + } + + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new VanillaRecipeProvider(registries, output); + } + + @Override + public String getName() { + return "My Recipes"; + } + } +} +``` + +- `net.minecraft.data.recipes` + - `RecipeOutput#includeRootAdvancement` - Generates the root advancement for recipes. + - `RecipeProvider` no longer extends `DataProvider` + - The constructor takes in the lookup provider and a `RecipeOutput`, which are protected fields + - `buildRecipes` does not take in any parameters + - All generation methods do not take in a `RecipeOutput` and are instance methods + - `$FamilyRecipeProvider` - Creates a recipe for a `BlockFamily` by passing in the `Block` the resulting block and the base block. + - `$Runner` - A `DataProvider` that constructs the `RecipeProvider` via `createRecipeProvider` + - `ShapedRecipeBuilder`, `ShapelessRecipeBuilder` now have private constructors and take in a holder getter for the items + +## The Ingredient Shift + +`Ingredient`s have be reimplemented to use a `HolderSet` as its base rather that it own internal `Ingredient$Value`. This most changes the call to `Ingredient#of` as you either need to supply it with `Item` objects or the `HolderSet` representing the tag. For more information on how to do this, see the [holder set section](#the-holder-set-transition). + +- `net.minecraft.world.item.crafting.Ingredient` + - `EMPTY` -> `Ingredient#of`, though the default usecases do not allow empty ingredients + - `CODEC` is removed + - `CODEC_NONEMPTY` -> `CODEC` + - `testOptionalIngredient` - Tests whether the stack is within the ingredient if present, or default to an empty check if not. + - `getItems` -> `items` + - `getStackingIds` is removed + - `of(ItemStack...)`, `of(Stream)` is removed + - `of(TagKey)` -> `of(HolderSet)`, need to resolve tag key + +## BlockEntityTypes Privatized! + +`BlockEntityType`s have been completely privatized and the builder being removed! This means that if a mod loader or mod does not provide some access widening to the constructor, you will not be able to create new block entities. The only other change is that the `Type` for data fixers was removed, meaning that all that needs to be supplied is the client constructor and the set of valid blocks the block entity can be on. + +```java +// If the BlockEntityType constructor is made public +// MyBlockEntity(BlockPos, BlockState) constructor +BlockEntityType type = new BlockEntityType(MyBlockEntity::new, MyBlocks.EXAMPLE_BLOCK); +``` + +## Consumables + +Consuming an item has been further expanded upon, with most being transitioned into separate data component entries. + +### The `Consumable` Data Component + +The `Consumable` data component defines how an item is used when an item is finished being used. This effectively functions as `FoodProperties` used to previously, except all consumable logic is consolidated in this one component. A consumable has five properties: the number of seconds it takes to consume or use the item, the animation to play while consuming, the sound to play while consuming, whether particles should appear during consumption, and the [effects to apply once the consumption is complete](#consumeeffect). + +A `Consumable` can be applied using the `food` item property. If only the `Consumable` should be added, then `component` should be called. A list of vanilla consumables and builders can be found in `Consumables`. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().component(DataComponents.CONSUMABLE, + Consumable.builder() + .consumeSeconds(1.6f) // Will use the item in 1.6 seconds, or 32 ticks + .animation(ItemUseAnimation.EAT) // The animation to play while using + .sound(SoundEvents.GENERIC_EAT) // The sound to play while using the consumable + .soundAfterConsume(SoundEvents.GENERIC_DRINK) // The sound to play after consumption (delegates to 'onConsume') + .hasConsumeParticles(true) // Sets whether to display particles + .onConsume( + // When finished consuming, applies the effects with a 30% chance + new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.3F) + ) + // Can have multiple + .onConsume( + // Teleports the entity randomly in a 50 block radius + new TeleportRandomlyConsumeEffect(100f) + ) + .build() +)); +``` + +#### `OnOverrideSound` + +Sometimes, an entity may want to play a different sound when consuming an item. In that case, the entity can implement `Consumable$OverrideConsumeSound` and return the sound event that should be played. + +```java +// On your own entity +public class MyEntity extends Mob implements Consumable.OverrideCustomSound { + // ... + + @Override + public SoundEvent getConsumeSound(ItemStack stack) { + // Return the sound event to play + } +} +``` + +### `ConsumableListener` + +`ConsumableListener`s are data components that indicate an action to apply once the stack has been 'consumed'. This means whenever `Consumable#consumeTicks` has passed since the player started using the consumable. An example of this would be `FoodProperties`. `ConsumableListener` only has one method `#onConsume` that takes in the level, entity, stack doing the consumption, and the `Consumable` that has finished being consumed. + +```java +// On your own data component +public record MyDataComponent() implements ConsumableListener { + + // ... + + @Override + public void onConsume(Level level, LivingEntity entity, ItemStack stack, Consumable consumable) { + // Perform stuff once the item has been consumed. + } +} +``` + +### `ConsumeEffect` + +There is now a data component that handles what happens when an item is consumed by an entity, aptly called a `ConsumeEffect`. The current effects range from adding/removing mob effects, teleporting the player randomly, or simply playing a sound. These are applied by passing in the effect to the `Consumable` or `onConsume` in the builder. + +```java +// When constructing a consumable +Consumable exampleConsumable = Consumable.builder() + .onConsume( + // When finished consuming, applies the effects with a 30% chance + new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.3F) + ) + // Can have multiple + .onConsume( + // Teleports the entity randomly in a 50 block radius + // NOTE: CURRENTLY BUGGED, only allows for 8 block raidus + new TeleportRandomlyConsumeEffect(100f) + ) + .build(); +``` + +### On Use Conversion + +Converting an item into another stack on consumption is now handled through `DataComponents#USE_REMAINDER`. The remainder will only be converted if the stack is empty after this use. Otherwise, it will return the current stack, just with one item used. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().usingConvertsTo( + Items.APPLE // Coverts this into an apple on consumption +)); +Item exampleItem2 = new Item(new Item.Properties().component(DataComponents.USE_REMAINDER, + new UseCooldown( + new ItemStack(Items.APPLE, 3) // Converts into three apples on consumption + ) +)); +``` + +### Cooldowns + +Item cooldowns are now handled through `DataComponents#USE_COOLDOWN`; however, they have been expanded to apply cooldowns to stacks based on their defined group. A cooldown group either refers to the `Item` registry name if not specified, or a custom resource location. When applying the cooldown, it will store the cooldown instance on anything that matches the defined group. This means that, if a stack has some defined cooldown group, it will not be affected when a normal item is used. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().useCooldown( + 60 // Wait 60 seconds + // Will apply cooldown to items in the 'my_mod:example_item' group (assuming that's the registry name) +)); +Item exampleItem2 = new Item(new Item.Properties().component(DataComponents.USE_COOLDOWN, + new UseCooldown( + 60, // Wait 60 seconds + // Will apply cooldown to items in the 'my_mod:custom_group' group + Optional.of(ResourceLocation.fromNamespaceAndPath("my_mod", "custom_group")) + ) +)); +``` + +- `net.minecraft.core.component.DataComponents#FOOD` -> `CONSUMABLE` +- `net.minecraft.world.entity.LivingEntity` + - `getDrinkingSound`, `getEatingSound` is removed, handled via `ConsumeEffect` + - `triggerItemUseEffects` is removed + - `eat` is removed +- `net.minecraft.world.entity.npc.WanderingTrader` now implements `Consumable$OverrideConsumeSound` +- `net.minecraft.world.food` + - `net.minecraft.world.food.FoodData` + - `tick` now takes in a `ServerPlayer` + - `getLastFoodLevel`, `getExhaustionLevel`, `setExhaustion` is removed + - `FoodProperties` is now a `ConsumableListener` + - `eatDurationTicks`, `eatSeconds` -> `Consumable#consumeSeconds` + - `usingConvertsTo` -> `DataComponents#USE_REMAINDER`, + - `effects` -> `ConsumeEffect` +- `net.minecraft.world.item` + - `ChorusFruitItem` class is removed + - `HoneyBottleItem` class is removed + - `Item` + - `getDrinkingSound`, `#getEatingSound` is removed, handled via `ConsumeEffect` + - `releaseUsing` now returns a `boolean` whether it was successfully released + - `$Properties#food` can now take in a `Consumable` for custom logic + - `$Properties#usingConvertsTo` - The item to convert to after use. + - `$Properties#useCooldown` - The amount of seconds to wait before the item can be used again. + - `ItemCooldowns` now take in `ItemStack`s or `ResourceLocation`s to their methods rather than just an `Item` + - `getCooldownGroup` - Returns the key representing the group the cooldown is applied to + - `ItemStack#getDrinkingSound`, `getEatingSound` is removed + - `MilkBucketItem` class is removed + - `OminousBottleItem` class is removed + - `SuspiciousStewItem` class is removed +- `net.minecraft.world.item.alchemy.PotionContents` now implements `ConsumableListener` + - The constructor takes in an optional string representing the translation key suffix of the custom name + - `applyToLivingEntity` - Applies all effects to the provided entity. + - `getName` - Gets the name component by appending the custom name to the end of the provided contents string. +- `net.minecraft.world.item.component` + - `Consumable` - A data component that defines when an item can be consumed. + - `ConsumableListener` - An interface applied to data components that can be consumed, executes once consumption is finished. + - `SuspiciousStewEffects` now implements `ConsumableListener` + - `UseCooldown` - A data component that defines how the cooldown for a stack should be applied. + - `UseRemainder` - A data component that defines how the item should be replaced once used up. + - `DeathProtection` - A data component that contains a list of `ConsumeEffect`s on what to do when using the item to survive death. +- `net.minecraft.world.item.consume_effects.ConsumeEffect` - An effect to apply after the item has finished being consumed. + +## Registry Objcet Id, in the Properties? + +When providing the `BlockBehaviour$Properties` to the `Block` or the `Item$Properties` to the `Item`, it must set the `ResourceKey` in the block directly by calling `#setId`. An error will be thrown if this is not set before passing in. + +```java +new Block(BlockBehaviour.Properties.of() + .setId(ResourceKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("examplemod", "example_block")))); + +new BlockItem(exampleBlock, new Item.Properties() + .useBlockDescriptionPrefix() // Makes the description id for a block item + .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")))); + +new Item(new Item.Properties() + .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")))); +``` + +- `net.minecraft.world.item.Item$Properties` + - `setId` - Sets the resource key of the item to get the default description and model from. This property must be set. + - `useBlockDescriptionPrefix` - Creates the description id using the `block.` prefix. + - `useItemDescriptionPrefix` - Creates the description id using the `item.` prefix. +- `net.minecraft.world.level.block.state.BlockBehaviour$Properties#setId` - Sets the resource key of the block to get the default drops and description from. This property must be set. + +## Properties Changes + +`DirectionProperty` has been removed, and must now be called and referenced via `EnumProperty#create` with a `Direction` generic. Additionally, all property classes have been made final and must be constructed through one of the exposed `create` methods. + +- `net.minecraft.world.level.block.state.properties` + - `BooleanProperty` is now final + - `DirectionProperty` class is removed + - `EnumProperty` is now final + - `create` now takes in a `List` instead of a `Collection` + - `IntegerProperty` is now final + - `Property#getPossibleValues` now returns a `List` instead of a `Collection` + +## Recipes, now in Registry format + +Recipes have been upgraded to a data pack registry, similar to how loot tables are handled. They are still queried in the same fashion, it just simply using a pseudo-registry-backed instance. Some of the more common changes is that `RecipeHolder` may be replaced by `RecipeDisplayId`, `RecipeDisplay`, or `RecipeDisplayEntry` if the holder itself is not needed. With this, there are a few changes to how recipe books are handled. + +### Recipe Books + +`RecipeBookComponent`s have been modified somewhat to hold a generic instance of the menu to render. As such, the component no longer implements `PlacedRecipe` and instead takes in a generic representing the `RecipeBookMenu`. The menu is passed into the component via its constructor instead of through the `init` method. This also menas that `RecipeBookMenu` does not have any associated generics. To create a component, the class needs to be extended. + +```java +// Assume some MyRecipeMenu extends AbstractContainerMenu +public class MyRecipeBookComponent extends RecipeBookComponent { + + public MyRecipeBookComponent(MyRecipeMenu menu, List tabInfos) { + super(menu, tabInfos); + // ... + } + + @Override + protected void initFilterButtonTextures() { + // ... + } + + @Override + protected boolean isCraftingSlot(Slot slot) { + // ... + } + + @Override + protected void selectMatchingRecipes(RecipeCollection collection, StackedItemContents contents) { + // ... + } + + @Override + protected Component getRecipeFilterName() { + // ... + } + + @Override + protected void fillGhostRecipe(GhostSlots slots, RecipeDisplay display, ContextMap ctx) { + + } +} + +public class MyContainerScreen extends AbstractContainerScreen implements RecipeUpdateListener { + + public MyContainerScreen(MyRecipeMenu menu, List tabInfos, ...) { + super(menu, ...); + this.recipeBookComponent = new MyRecipeBookComponent(menu, tabInfos); + } + + + // See AbstractFurnaceScreen for a full implementation +} +``` + +### Recipe Displays + +However, how does a recipe understand what should be displayed in a recipe book? This falls under two new static registries: the `RecipeDisplay` and the `SlotDisplay`. + +The `SlotDisplay` represents what displays in a single slot within a recipe. The display only has one method (ignoring types): `resolve`. `resolve` takes in the `ContextMap` holding the data and the `DisplayContentsFactory` which accepts the stacks and remainders that will be displayed in this slot. `SlotDisplay` also has a lot of helper implementations, such as `$Composite` that takes in a list of displays or `$ItemStackSlotDisplay` that takes in the stack to display. The display is registered by its `$Type`, which takes in the map codec and stream codec. + +The slot also has methods to get for the associated stacks that can be displayed via `resolveForStacks` and `resolveForFirstStack`. + +```java +public static record MySlotDisplay() implements SlotDisplay { + + @Override + public Stream resolve(ContextMap ctx, DisplayContentsFactory output) { + // Call output.forStack(...) or addRemainder(..., ...) using instanceof to display items + if (output instanceof ForStacks stacks) { + stacks.forStack(...); + } else if (output instanceof ForRemainders remainders) { + remainders.addRemainder(..., ...); + } + } + + @Override + public SlotDisplay.Type type() { + // Return the registered object here registered to Registries#SLOT_DISPLAY + } +} +``` + +`RecipeDisplay` represents how a recipe is displayed. As an implementation detail, the `RecipeDisplay` only needs to be aware of the result (via `result` slot display) and the place the recipe is being used (via `craftingStation` slot display) as those are the only two details the recipe book cares about. However, it is recommended to also have slot displays for the ingredients and then have those consumed by your `RecipeBookComponent`. The display is registered by its `$Type`, which takes in the map codec and stream codec. + + +```java +public record MyRecipeDisplay(SlotDisplay result, SlotDisplay craftingStation, ...) implements RecipeDisplay { + + @Override + public RecipeDisplay.Type type() { + // Return the registered object here registered to Registries#RECIPE_DISPLAY + } +} +``` + +### Recipe Placements + +Recipe ingredients and placements within the recipe book are now handled through `Recipe#placementInfo`. A `PlacementInfo` is basically a definition of items the recipe contains and where they should be placed within the menu if supported. If the recipe cannot be placed, such as if it is not an `Item` or uses stack information, then it should return `PlacementInfo#NOT_PLACEABLE`. + +A `PlacementInfo` can be created either from an `Ingredient`, a `List`, or a `List>` using `create` or `createFromOptionals`, respectively. + +```java +public class MyRecipe implements Recipe { + + private PlacementInfo info; + + public MyRecipe(Ingredient input) { + // ... + } + + // ... + + @Override + public PlacementInfo placementInfo() { + // This delegate is done as the HolderSet backing the ingredient may not be fully populated in the constructor + if (this.info == null) { + this.info = PlacementInfo.create(input); + } + + return this.info; + } +} +``` + +If an `Optional` is used, they can be tested via `Ingredient#testOptionalIngredient`. + +- `net.minecraft.world.item.crafting` + - `Ingredient#display` - Returns the `SlotDisplay` that shows this ingredient. + - `PlacementInfo` - Defines all ingredients necessary to construct the result of a recipe. + - `Recipe` + - `getToastSymbol` -> `getCategoryIconItem` + - `getIngredients`, `isIncomplete` -> `placementInfo` + - `getIngredients` -> `PlacementInfo#stackedRecipeContents`, + - `isIncomplete` -> `PlacementInfo#isImpossibleToPlace` + - `RecipeManager#getSynchronizedRecipes` - Returns all recipes that can be placed and sends them to the client. No other recipes are synced. + - `ShapedRecipePattern` now takes in a `List>` instead of a `NonNullList` + - `ShapelessRecipe` now takes in a `List` instead of a `NonNullList` + - `SmithingTransformRecipe`, `SmithingTrimRecipe` now takes in `Optional`s instead of `Ingredient`s + - `SuspiciousStewRecipe` class is removed + +### Recipe Changes + +There have been a few changes within the recipe class itself, which mirror all of the above changes. First, `canCraftInDimensions` is removed and now hardcoded into the match function. `getResultItem` and `getCategoryIconItem` has been replaced by `RecipeDisplay` via `display`. `getRemainingItems` has moved to `CraftingRecipe`. Finally, all recipes now return their `RecipeBookCategory` via `recipeBookCategory`. + +```java +public class MyRecipe implements Recipe { + + @Override + public String group() { + // Return here what `getGroup` was + } + + @Override + public List display() { + return List.of( + // Some recipe display instance + // RecipeDisplay#result should return `getResultItem` + // RecipeDisplay#craftingStation should return `getCategoryIconItem` + ) + } + + @Override + public RecipeBookCategory recipeBookCategory() { + // Functions similar to the book category passed into the recipe builders during data generation + return RecipeBookCategories.CRAFTING_MISC; + } +} +``` + +### Creating Recipe Book Categories + +Recipe book categories are unified by `ExtendedRecipeBookCategory` and split into two sections: `RecipeBookCategory` for actual categories, and `SearchRecipeBookCategory` for aggregate categories. While `SearchRecipeBookCategory`s are enums, `RecipeBookCategory` is like any other static registry object. This is done by creating a new `RecipeBookCategory`. + +```java +// Using the standard vanilla registry method +public static final RecipeBookCategory EXAMPLE_CATEGORY = Registry.register( + BuiltInRegistries.RECIPE_BOOK_CATEGORY, + // The registry object name + ResourceLocation.fromNamespaceAndPath("examplemod", "example_category"), + // This creates a new recipe book category. It functions as a marker object. + new RecipeBookCategory() +); +``` + +### Technical Changes + +- `net.minecraft.advancements.AdvancementRewards` now takes in a list of `ResourceKey`s instead of `ResourceLocation`s for the recipe + - `$Builder#recipe`, `addRecipe` now takes in a `ResourceKey` +- `net.minecraft.advancements.critereon` + - `PlayerPredicate` now takes in a `ResourceKey` for the recipe map + - `$Builder#addRecipe` now takes in a `ResourceKey` + - `RecipeCraftedTrigger` + - `trigger` now takes in a `ResourceKey` + - `$TriggerInstance` now takes in a `ResourceKey` + - `$TriggerInstance#craftedItem`, `crafterCraftedItem` now takes in a `ResourceKey` + - `RecipeUnlockedTrigger` + - `unlocked` now takes in a `ResourceKey` + - `$TriggerInstance` now takes in a `ResourceKey` +- `net.minecraft.client` + - `ClientRecipeBook` + - `setupCollections` -> `rebuildCollections`, not one-to-one + - `getCollection(RecipeBookCategories)` -> `getCollection(ExtendedRecipeBookCategory)` + - `add`, `remove` - Handles adding/removing a recipe entry to display within the recipe book. + - `addHighLight`, `removeHighlight`, `hasHighlight` - Handles if the entry is highlighted when filtered or selected by the player. + - `clear` - Clears the known and highlighted recipes. + - `RecipeBookCategories#*_MISC` -> `SearchRecipeBookCategory#*` + - This can also be replaced within methods by `RecipeBookComponent$TabInfo`, `ExtendedRecipeBookCategory`, or `RecipeBookCategory` +- `net.minecraft.client.gui.components.toasts` + - `RecipeToast(RecipeHolder)` -> `RecipeToast()`, now private + - `addOrUpdate` now takes in a `RecipeDisplay` instead of a `RecipeHolder` +- `net.minecraft.client.gui.screens.inventory.AbstractFurnaceScreen` + - `recipeBookComponent` is now private + - `AbstractFurnaceScreen(T, AbstractFurnaceRecipeBookComponent, Inventory, Component, ResourceLocation, ResourceLocation, ResourceLocation)` - `AbstractFurnaceRecipeBookComponent` has been replaced with a `Component` as the recipe book is not constructed internally and now takes in a list of `RecipeBookComponent$TabInfo` +- `net.minecraft.client.gui.screens.recipebook` + - `AbstractFurnaceReipceBookComponent`, `BlastingFurnaceReipceBookComponent`, `SmeltingFurnaceReipceBookComponent`, `SmokingFurnaceReipceBookComponent` -> `FurnaceReipceBookComponent` + - `GhostRecipe` -> `GhostSlots` not one-to-one, as the recipe itself is stored as a private field in `RecipeBookComponent` as a `RecipeHolder` + - `addResult` -> `setResult`, not one-to-one + - `addIngredient` -> `setIngredient`, not one-to-one + - `setSlot`, `setInput`, `setResult` now take in a `ContextMap` + - `OverlayRecipeComponent()` -> `OverlayRecipeComponent(SlotSelectTime, boolean)` + - `init` takes in a `ContextMap` containing registry data to display within the components and a `boolean` representing whether the recipe book is filtering instead of computing it from the `Minecraft` instance + - `getLastRecipeClicked` now returns a `RecipeDisplayId` + - `$OverlayRecipeButton` is now an abstract package-private class, taking in the `ContextMap` + - `$Pos` is now a record + - `RecipeBookComponent` no longer implements `RecipeShownListener` + - The constructor takes in a list of `$TabInfo`s containing the tabs shown in the book + - `init` no longer takes in a `RecipeBookMenu` + - `initVisuals` is now private + - `initFilterButtonTextures` is now abstract + - `updateCollections` now takes in another boolean representing if the book is filtering + - `renderTooltip` now takes in a nullable `Slot` instead of an `int` representing the slot index + - `renderGhostRecipe` no longer takes in a float representing the delay time + - `setupGhostRecipe` -> `fillGhostRecipe`, no longer takes in the `List` to place, that is stored within the component itself + - `selectMatchingRecipes` no longer takes in the `RecipeBook` + - `recipesShown` now takes in a `RecipeDisplayId` + - `setupGhostRecipeSlots` -> `fillGhostRecipe`, taking in the `ContextMap` + - `$TabInfo` - A record that denotes the icons and categories of recipe to display within a recipe book page. + - `RecipeBookPage()` -> `RecipeBookPage(RecipeBookComponent, SlotSelectTime, boolean)` + - `updateCollections` now takes in a boolean representing if the book is filtering + - `getMinecraft` is removed + - `addListener` is removed + - `getLastRecipeClicked` now returns a `RecipeDisplayId` + - `recipesShown` now takes in a `RecipeDisplayId` + - `getRecipeBook` now returns a `ClientRecipeBook` + - `RecipeBookTabButton` now takes in a `RecipeBookComponent$TabInfo` + - `startAnimation(Minecraft)` -> `startAnimation(ClientRecipeBook, boolean)` + - `getCategory` now returns a `ExtendedRecipeBookCategory` + - `RecipeButton()` -> `RecipeButton(SlotSelectTime)` + - `init` now takes in a `boolean` representing if the book is filtering and a `ContextMap` holding the registry data + - `getRecipe` -> `getCurrentRecipe`, not one-to-one + - `getDisplayStack` - Returns the result stack of the recipe. + - `getTooltipText` now takes in the `ItemStack` + - `RecipeCollection(RegistryAccess, List)` -> `RecipeCollection(List)` + - `canCraft` -> `selectRecipes` + - `getRecipes`, `getDisplayRecipes` -> `getSelectedRecipes` + - `registryAccess`, `hasKnownRecipes`, `updateKnownRecipes` is removed + - `isCraftable` now takes in a `RecipeDisplayId` + - `hasFitting` -> `hasAnySelected` + - `getRecipes` now returns a list of `RecipeDisplayEntry`s + - `RecipeShownListener` class is removed + - `RecipeUpdateListener` + - `getRecipeBookComponent` is removed + - `fillGhostRecipe` -> Fills the ghost recipe given the `RecipeDisplay` + - `SearchRecipeBookCategory` - An enum which holds the recipe book categories for aggregate types. + - `SlotSelectTime` - Represents the current index of the slot selected by the player. +- `net.minecraft.client.multiplayer` + - `ClientPacketListener#getRecipeManager` -> `recipes`, returns `RecipeAccess` + - `ClientRecipeContainer` - A client side implementation of the `RecipeAccess` when synced from the server. + - `MultiPlayerGameMode#handlePlaceRecipe` now takes in a `RecipeDisplayId` + - `SessionSearchTrees#updateRecipes` now takes in a `Level` instead of the `RegistryAccess$Frozen` +- `net.minecraft.client.player.LocalPlayer#removeRecipeHightlight` now takes in a `RecipeDisplayId` +- `net.minecraft.commands.SharedSuggestionProvider#getRecipeNames` is removed as it can be queried from the registry access +- `net.minecraft.commands.arguments.ResourceLocationArgument` + - `getRecipe` -> `ResourceKeyArgument#getRecipe` + - `getAdvancement` -> `ResourceKeyArgument#getAdvancement` +- `net.minecraft.commands.synchronization.SuggestionProviders#ALL_RECIPES` is removed +- `net.minecraft.core.component.DataComponents#RECIPES` now takes in a list of `ResourceKey`s +- `net.minecraft.data.recipes` + - `RecipeBuilder#save` now takes in a `ResourceKey` instead of a `ResourceLocation` + - `RecipeOutput#accept` now takes in a `ResourceKey` instead of a `ResourceLocation` + - `RecipeProvider#trimSmithing` now takes in a `ResourceKey` instead of a `ResourceLocation` +- `net.minecraft.network.protocol.game` + - `ClientboundPlaceGhostRecipePacket` - A packet that contains the container id and the `RecipeDisplay` + - `ClientboundRecipeBookAddPacket` - A packet that adds entries to the recipe book + - `ClientboundRecipeBookRemovePacket` - A packet that removes entries to the recipe book + - `ClientboundRecipeBookSettingsPacket` - A packet that specifies the settings of the recipe book + - `ClientboundRecipePacket` class is removed + - `ClientboundUpdateRecipesPacket` is now a record, taking in the property sets of the recipes and the stonecutter recipes + - `getRecipes` is removed + - `ServerboundPlaceRecipePacket` is now a record + - `ServerboundRecipeBookSeenRecipePacket` is now a record +- `net.minecraft.recipebook` + - `PlaceRecipe` -> `PlaceRecipeHelper` + - `addItemToSlot` -> `$Output#addItemToSlot` + - `placeRecipe` now takes in a `Recipe` instead of the `RecipeHolder` + - There is an overload that takes in two more ints that represent the pattern height and width for a `ShapedRecipe`, or just the first two integers repeated + - `RecipeBook` + - `add`, `contains`, `remove` -> `ServerRecipeBook#add`, `contains`, `remove` + - `addHighlight`, `removeHighlight`, `willHighlight` -> `ServerRecipeBook#addHighlight`, `removeHighlight`, `ClientRecipeBook#hasHighlight` + - `bookSettings` is now protected + - `RecipeBookSettings#read`, `write` is now private + - `ServerPlaceRecipe` is not directly accessible anymore, instead it is accessed and returned as a `RecipeBookMenu$PostPlaceAction` via `#placeRecipe` + - `$CraftingMenuAccess` - Defines how the placable recipe menu can be interacted with. + - `ServerRecipeBook` + - `fromNbt` now takes in a predicate of a `ResourceKey` instead of the `RecipeManager` + - `copyOverData` - Reads the data from another recipe book. + - `$DisplayResolver` - Resoluves the recipes to display by passing in a `RecipeDisplayEntry` +- `net.minecraft.stats.RecipeBook#isFiltering(RecipeBookMenu)` is removed +- `net.minecraft.world.entity.player` + - `Player#awardRecipesByKey` now takes in a list of `ResourceKey`s + - `StackedItemContents#canCraft` overloads that take in a list of ingredient infos +- `net.minecraft.world.inventory` + - `AbstractCraftingMenu` - A menu for a crafting interface. + - `AbstractFurnaceMenu` now takes in the `RecipePropertySet` key + - `CraftingMenu#slotChangedCraftingGrid` now takes in a `ServerLevel` instead of a `Level` + - `ItemCombinerMenu` now takes in an `ItemCombinerMenuSlotDefinition` + - `mayPickup` now defaults to `true` + - `ItemCombinerMenuSlotDefinition#hasSlot`, `getInputSlotIndexes` is removed + - `RecipeBookMenu` no longer takes in any generics + - `handlePlacement` is now abstract and returns a `$PostPlaceAction`, taking in an additional `ServerLevel` + - This remove all basic placement recipes calls, as that would be handled internally by the `ServerPlaceRecipe` + - `RecipeCraftingHolder#setRecipeUser` no longer takes in a `Level` + - `SmithingMenu#hasRecipeError` - Returns whether the recipe had an error when placing items in the inventory. +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now implements `SingleItemRecipe` + - The constructor no longer takes in the `RecipeType`, making the user override the `getType` method + - `getExperience` -> `experience` + - `getCookingTime` -> `cookingTime` + - `furnaceIcon` - Returns the icon of the furnace. + - `$Serializer` - A convenience implementation for the cooking recipe serializer instance. + - `CookingBookCategory` now has an integer id + - `CraftingRecipe#defaultCrafingRemainder` - Gets the stacks that should remain behind in the crafting recipe. + - `CustomRecipe$Serializer` - A convenience implementation for the custom recipe serializer instance. + - `ExtendedRecipeBookCategory` - A unifying interface that denotes a category within the recipe book. + - `Ingredient#optionalIngredientToDisplay` - Converts an optional ingredient to a `SlotDisplay`. + - `Recipe#getRemainingItems` -> `CraftingRecipe#getRemainingItems` + - `RecipeAccess` - An accessor that returns the property sets that contain the inputs of available recipes. + - `RecipeBookCategory` - An object that represents a single category within the recipe book. + - `RecipeCache#get` now takes in a `ServerLevel` instead of a `Level` + - `RecipeHolder` now takes in a `ResourceKey` + - `RecipeManager` now extends `SimplePreparableReloadLsitener` and implements `RecipeAccess` + - `prepare` - Creates the recipe map from the recipe registry + - `logImpossibleRecipes`, `hasErrorsLoading` is removed + - `getRecipeFor` now takes in a `ResourceKey` where there was a `ResourceLocation` repviously + - `getRecipesFor`, `getAllRecipesFor` -> `RecipeMap#getRecipesFor` + - `byType` is removed + - `getRemainingItemsFor` is Removed + - `byKey`.`byKeyTyped` now takes in a `ResourceKey` + - `getOrderedRecipes` is revmoed + - `getSynchronizedRecipes` -> `getSynchronizedItemProperties`, `getSynchronizedStonecutterRecipes`; not one-to-one + - `getRecipeIds` is removed + - `getRecipeFromDisplay` - Gets the recipe display info given its id. + - `listDisplaysForRecipe` - Accepts a list of display entries of the recipes to display. + - `replaceRecipes` is removed + - `$CachedCheck#getRecipeFor` now takes in a `ServerLevel` instead of a `Level` + - `$IngredientCollector` - A recipe consumer that extracts the ingredient from a recipe and adds it to a `RecipePropertySet` + - `$IngredientExtractor` - A method that gets the ingredients of a recipe when present. + - `$ServerDisplayInfo` - A record that links a display entry to its recipe holder. + - `RecipeMap` - A class which maps recipe holders by their recipe type and resource key. + - `RecipePropertySet` - A set of ingredients that can be used as input to a given recipe slot. Used to only allow specific inputs to slots on screens. + - `SelectableRecipe` - A record that holds the slot display and its associated recipe. Currently only used for the stonecutting menu. + - `SimpleCookingSerializer` -> `AbstractCookingRecipe$Serializer` + - `SingleItemRecipe` no longer takes in the `RecipeType` or `RecipeSerializer` + - `ingredient`, `result`, `group` is now private + - `input`, `result` - The slots of the recipe. +- `net.minecraft.world.item.crafting.display` + - `DisplayContentsFactory` - A factory for accepting contents of a recipe. Its subtypes accepts the stacks of the recipe and the remainder. + - `RecipeDisplay` - A display handler to show the contents of a recipe. + - `RecipeDisplayEntry` - A record that links the recipe display to its identifier, category, and crafting requirements. + - `RecipeDisplayId` - An identifier for the recipe display. + - `SlotDisplay` - A display handler to show the contents of a slot within a recipe. + - `SlotDisplayContext` - Context keys used by slot displays. +- `net.minecraft.world.level.Level#getRecipeManager` -> `recipeAccess`, returns `RecipeAccess` on level but `RecipeManager` on `ServerLevel` +- `net.minecraft.world.level.block.CrafterBlock#getPotentialResults` now takes in a `ServerLevel` instead of a `Level` +- `net.minecraft.world.level.block.entity.CampfireBlockEntity` + - `getCookableRecipe` is removed + - `placeFood` now takes in a `ServerLevel` instead of a `Level` + +## 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. + +### Language File Removals and Renames + +All removals and renames to translations keys within `assets/minecraft/lang` are now shown in a `deprecated.json`. + +### Critereons, Supplied with HolderGetters + +All critereon builders during construction now take in a `HolderGetter`. While this may not be used, this is used instead of a direct call to the static registry to grab associated `Holder`s and `HolderSet`s. + +- `net.minecraft.advancement.critereon` + - `BlockPredicate$Builder#of` + - `ConsumeItemTrigger$TriggerInstance#usedItem` + - `EntityEquipmentPredicate#captainPredicate` + - `EntityPredicate$Builder#of` + - `EntityTypePredicate#of` + - `ItemPredicate$Builder#of` + - `PlayerTrigger$TriggerInstance#walkOnBlockWithEquipment` + - `ShotCrossbowTrigger$TriggerInstance#shotCrossbow` + - `UsedTotemTrigger$TriggerInstance#usedToItem` + +### MacosUtil#IS_MACOS + +`com.mojang.blaze3d.platform.MacosUtil#IS_MACOS` has been added to replace specifying a boolean during the render process. + +- `com.mojang.blaze3d.pipeline` + - `RenderTarget#clear(boolean)` -> `clear()` + - `TextureTarget(int, int, boolean, boolean)` -> `TextureTarget(int, int, boolean)` +- `com.mojang.blaze3d.platform.GlStateManager#_clear(boolean)` -> `_clear()` +- `com.mojang.blaze3d.systems.RenderSystem#clear(int, boolean)` -> `clear(int)` + +### Fog Parameters + +Fog methods for individual values have been replaced with a `FogParameters` data object. + +- `com.mojang.blaze3d.systems.RenderSystem` + - `setShaderFogStart`, `setShaderFogEnd`, `setShaderFogColor`, `setShaderFogShape` -> `setShaderFog` + - `getShaderFogStart`, `getShaderFogEnd`, `getShaderFogColor`, `getShaderFogShape` -> `getShaderFog` +- `net.minecraft.client.renderer.FogRenderer` + - `setupColor` -> `computeFogColor`, returns a `Vector4f` + - `setupNoFog` -> `FogParameters#NO_FOG` + - `setupFog` now takes in a `Vector4f` for the color and returns the `FogParameters` + - `levelFogColor` is removed + +### New Tags + +- `minecraft:banner_pattern` + - `bordure_indented` + - `field_masoned` +- `minecraft:block` + - `bats_spawnable_on` + - `pale_oak_logs` +- `minecraft:damage_type` + - `mace_smash` +- `minecraft:item` + - `diamond_tool_materials` + - `furnace_minecart_fuel` + - `gold_tool_materials` + - `iron_tool_materials` + - `netherite_tool_materials` + - `villager_picks_up` + - `wooden_tool_materials` + - `piglin_safe_armor` + - `repairs_leather_armor` + - `repairs_chain_armor` + - `repairs_iron_armor` + - `repairs_gold_armor` + - `repairs_diamond_armor` + - `repairs_netherite_armor` + - `repairs_turtle_helmet` + - `repairs_wolf_armor` + - `duplicates_allays` + - `brewing_fuel` + - `panda_eats_from_ground` + - `shulker_boxes` + - `bundles` + - `map_invisibility_equipment` + - `pale_oak_logs` + - `gaze_disguise_equipment` +- `minecraft:entity_type` + - `boat` + +### Smarter Framerate Limiting + +Instead of simply limiting the framerate when the player is not in a level or when in a screen or overlay, there is different behavior depending on different actions. This is done using the `InactivityFpsLimit` via the `FramerateLimitTracker`. This adds two additional checks. If the window is minimized, the game runs at 10 fps. If the user provides no input for a minute, then the game runs at 30 fps. 10 fps after ten minutes of no input. + +- `com.mojang.blaze3d.platform.FramerateLimitTracker` - A tracker that limits the framerate based on the set value. +- `com.mojang.blaze3d.platform#Window#setFramerateLimit`, `getFramerateLimit` is removed +- `net.minecraft.client` + - `InactivityFpsLimit` - An enum that defines how the FPS should be limited when the window is minimzed or the player is away from keyboard. + - `Minecraft#getFramerateLimitTracker` - Returns the framerate limiter. + +### Fuel Values + +`FuelValues` has replaced the static map within `AbstractFurnaceBlockEntity`. This functions the same as that map, except the fuel values are stored on the `MinecraftServer` itself and made available to individual `Level` instances. The map can be obtained with access to the `MinecraftServer` or `Level` and calling the `fuelValues` method. + +- `net.minecraft.client.multiplayer.ClientPacketListener#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.server.MinecraftServer#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.server.level.Level#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity` + - `invalidateCache`, `getFuel` -> `Level#fuelValues` + - `getBurnDuration` now takes in the `FuelValues` + - `isFuel` -> `FuelValues#isFuel` + - `FuelValues` - A class which holds the list of fuel items and their associated burn times + +### Light Emissions + +Light emission data is now baked into the quad and can be added to a face using the `light_emission tag`. + +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` now takes in an `int` representing the light emission + - `getLightEmission` - Returns the light emission of a quad. + - `BlockElement` now takes in an `int` representing the light emission + - `FaceBakery#bakeQuad` now takes in an `int` representing the light emission + +### Map Textures + +Map textures are now handled through the `MapTextureManager`, which handles the dynamic texture, and the `MapRenderer`, which handles the map rendering. Map decorations are still loaded through the `map_decorations` sprite folder. + +- `net.minecraft.client` + - `Minecraft` + - `getMapRenderer` - Gets the renderer for maps. + - `getMapTextureManager` - Gets the texture manager for maps. +- `net.minecraft.client.resources#MapTextureManager` - Handles creating the dynamic texture for the map. +- `net.minecraft.client.gui.MapRenderer` -> `net.minecraft.client.renderer.MapRenderer` +- `net.minecraft.client.renderer#GameRenderer#getMapRenderer` -> `Minecraft#getMapRenderer` + +### Orientations + +With the edition of the redstone wire experiments comes a new class provided by the neighbor changes: `Orientation`. `Orientation` is effectively a combination of two directions and a side bias. `Orientation` is used as a way to propogate updates relative to the connected directions and biases of the context. Currently, this means nothing for people not using the new redstone wire system as all other calls to neighbor methods set this to `null`. However, it does provide a simple way to propogate behavior in a stepwise manner. + + +- `net.minecraft.client.renderer.debug.RedstoneWireOrientationsRenderer` - A debug renderer for redstone wires being oriented. +- `net.minecraft.world.level.Level` + - `updateNeighborsAt` - Updates the neighbor at the given position with the specified `Orientation`. + - `updateNeighborsAtExceptFromFacing`, `neighborChanged` now takes in an `Orientation` +- `net.minecraft.world.level.block.RedStoneWireBlock` + - `getBlockSignal` - Returns the strength of the block signal. +- `net.minecraft.world.level.block.state.BlockBehaviour` + - `neighborChanged`, `$BlockStateBase#handleNeighborChanged` now takes in an `Orientation` instead of the neighbor `BlockPos` + - `updateShape` now takes in the `LevelReader`, `ScheduledTickAccess`, and a `RandomSource` instead of the `LevelAccessor`; the `Direction` and `BlockState` parameters are reordered + - `$BlockStateBase#updateShape` now takes in the `LevelReader`, `ScheduledTickAccess`, and a `RandomSource` instead of the `LevelAccessor`; the `Direction` and `BlockState` parameters are reordered +- `net.minecraft.world.level.redstone` + - `CollectingNeighborUpdater$ShapeUpdate#state` -> `neighborState` + - `NeighborUpdater` + - `neighborChanged`, `updateNeighborsAtExceptFromFacing`, `executeUpdate` now takes in an `Orientation` instead of the neighbor `BlockPos` + - `executeShapeUpdate` switches the order of the `BlockState` and neighbor `BlockPos` + - `Orientation` - A group of connected `Directions` on a block along with a bias towards either the front or the up side. + - `RedstoneWireEvaluator` - A strength evaluator for incoming and outgoing signals. + +### Minecart Behavior + +Minecarts now have a `MinecartBehavior` class that handles how the entity should be moved and rendered. + +- `net.minecraft.core.dispenser.MinecartDispenseItemBehavior` - Defines how a minecart should behave when dispensed from a dispenser. +- `net.minecraft.world.entity.vehicle` + - `AbstractMinecart` + - `getMinecartBehavior` - Returns the behavior of the minecart. + - `exits` is now public + - `isFirstTick` - Returns whether this is the first tick the entity is alive. + - `getCurrentBlockPosOrRailBelow` - Gets the current position of the minecart or the rail beneath. + - `moveAlongTrack` -> `makeStepAlongTrack` + - `setOnRails` - Sets whether the minecart is on rails. + - `isFlipped`, `setFlipped` - Returns whetherh the minecart is upside down. + - `getRedstoneDirection` - Returns the direction the redstone is powering to. + - `isRedstoneConductor` is now public + - `applyNaturalSlowdown` now returns the vector to slowdown by. + - `getPosOffs` -> `MinecartBehavior#getPos` + - `setInitialPos` - Sets the initial position of the minecart. + - `createMinecart` is now abstract in its creation, meaning it can be used to create any minecart given the provided parameters + - `getMinecartType` is removed + - `getPickResult` is now abstract + - `$Type` and `getMinecartType` is replaced by `isRideable` and `isFurnace`, which is not one-to-one. + - `AbstractMinecartContainer(EntityType, double, double, double, Level)` is removed + - `MinecartBehavior` - holds how the entity should be rendered and positions during movement. + - `MinecartFurnace#xPush`, `zPush` -> `push` +- `net.minecraft.world.level.block.state.properties.RailShape#isAscending` -> `isSlope` +- `net.minecraft.world.phys.shapes.MinecartCollisionContext` - An entity collision context that handles the collision of a minecart with some other collision object. + +### EXPLOOOOSSSION! + +`Explosion` is now an interface that defines the metadata of the explosion. It does not contain any method to actually explode itself. However, `ServerExplosion` is still used internally to handle level explosions and the like. + +- `net.minecraft.world.level` + - `Explosion` -> `ServerExplosion` + - `Explosion` - An interface that defines how an explosion should occur. + - `getDefaultDamageSource` - Returns the default damage source of the explosion instance. + - `shouldAffectBlocklikeEntities` - Returns whether block entites should be affected by the explosion. + - `level` - Gets the `ServerLevel` + - `ExplosionDamageCalculator#getEntityDamageAmount` now takes in an additional `float` representing the seen percent + - `Level#explode` no longer returns anything +- `net.minecraft.world.level.block.Block#wasExploded` now takes in a `ServerLevel` instead of a `Level` +- `net.minecraft.world.level.block.state.BlockBehaviour#onExplosionHit`, `$BlockStateBase#onExplosionHit` now takes in a `ServerLevel` instead of a `Level` + + +### The Removal of the Carving Generation Step + +`GenerationStep$Carving` has been removed, meaning that all `ConfiguredWorldCarver`s are provided as part of a single `HolderSet`. + +```json +// In some BiomeGenerationSettings JSON +{ + "carvers": [ + // Carvers here + ] +} +``` + +- `net.minecraft.world.level.biome.BiomeGenerationSettings` + - `getCarvers` no longer takes in a `GenerationStep$Carving` + - `$Builder#addCarver` no longer takes in a `GenerationStep$Carving` + - `$PlainBuilder#addCarver` no longer takes in a `GenerationStep$Carving` +- `net.minecraft.world.level.chunk` + - `ChunkGenerator#applyCarvers` no longer takes in a `GenerationStep$Carving` + - `ProtoChunk#getCarvingMask`, `getOrCreateCarvingMask`, `setCarvingMask` no longer takes in a `GenerationStep$Carving` +- `net.minecraft.world.level.levelgen.placement` + - `CarvingMaskPlacement` class is removed + - `PlacementContext#getCarvingMask` no longer takes in a `GenerationStep$Carving` + +### Codecable Json Reload Listener + +The `SimpleJsonResourceReloadListener` has been rewritten to use codecs instead of pure `Gson`. + +```java +public class MyJsonListener extends SimpleJsonResourceReloadListener { + + // If you do not need registry access, the HolderLookup$Provider parameter can be removed + public MyJsonListener(HolderLookup.Provider registries, Codec codec, String directory) { + super(registries, codec, directory); + } +} +``` + +- `net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener` now takes in a generic representing the data object of the JSON + - The constructor is now protected, taking in the codec of the data object, the string of the directory, and an optional `HolderLookup$Provider` to construct the `RegistryOps` serialization context as necessary + - `prepare` now returns a map of names to objects + - `scanDirectory` now takes in the `DynamicOps` and `Codec` + +### Consecutive Executors + +`ProcessorMailbox` and `ProcessorHandle` have been replaced with `AbstractConsecutiveExecutor` and `TaskScheduler`, respectively. These are effectively the same in their usage, just with potentially different method names. + +- `net.minecraft.util.thread` + - `ProcessorMailbox` -> `AbstractConsecutiveExecutor`, not one-to-one + - `ConsecutiveExecutor` would be the equivalent implementation + - `PriorityConsecutiveExecutor` - An executor that specifies the priority of the task to run when scheduling. + - `BlockableEventLoop#wrapRunnable` -> `AbstractConsecutiveExecutor#wrapRunnable` + - `ProcessorHandle` -> `TaskScheduler`, where the generic is a subtype of `Runnable` + - `tell` -> `schedule` + - `ask`, `askEither` -> `scheduleWithResult`, not one-to-one + - `of` -> `wrapExecutor` + - `StrictQueue` no longer takes in an `F` generic and makes `T` a subtype of `Runnable` + - `pop` now returns a `Runnable` + - `$IntRunnable` -> `$RunnableWithPriority` + + +### Mob Conversions + +Mobs, converted via `#convertTo`, have their logic handled by `ConversionType`, `ConversionParams`. `ConversionType` is an enum that dictates the logic to apply when copying the information from one mob to another via `#convert`. The common properties are handled via `#convertCommon`, which is called within the `#convert` method. There are currently two types: `SINGLE`, where the entity is converted one-to-one to another entity; and `SPLIT_ON_DEATH`, where the `Mob#convertTo` method is called mutiple times such as when a slime dies. `ConversionParams` contains the metadata about the conversion process: the type, whether the entity can keep its equipment or pick up loot, and what team the entity is on. `Mob#convertTo` also takes in a mob consumer to apply any finalization settings to the entity itself. + +```java +// For some Mob exampleMob +exampleMob.convertTo( + EntityType.SHEEP, // The entity to convert to + new ConversionParams( + ConversionType.SINGLE, // One-to-one + true, // Keep equipment + false // Do not preserve pick up loot + ), + EntitySpawnReason.CONVERSION, // Reason entity spawned + sheep -> { + // Perform any other settings to set on the newly converted entity + }, +) +``` + +- `net.minecraft.world.entity` + - `ConversionParams` - A record containing the settings of what happens when a mob is converted to another entity + - `ConversionType` - An enum that defines how one mob is transformed to another. Currently either `SINGLE` for one-to-one, or `SPLIT_ON_DEATH` for one-to-many (only used for slimes) + - `Mob#convertTo` now takes in the `ConversionParams`, an optional `EntitySpawnReason` of the entity (default `CONVERSION`), and a mob consumer to set any other information after conversion + +### Ender Pearl Chunk Loading + +Ender pearls now load the chunks they cross through by adding a ticket to the chunk source and storing the entity on the player. + +- `net.minecraft.server.level.ServerPlayer` + - `registerEnderPearl`, `deregisterEnderPearl`, `getEnderPearls` - Handles the ender pearls thrown by the player. + - `registerAndUpdateEnderPearlTicket`, `placeEnderPearlTicket` - Handles the region tickets for the thrown ender pearls. + +### Profilers and the Tracy Client + +Profilers have been separated from the minecraft instance, now obtained through `Profiler#get`. A new profiler instance can be added via a try-resource block on `Profiler#use`. In addition, the profiler addds a new library called Tracy, made to track the current stack frame along with capturing images on the screen, if the associated `--tracy` argument is passed in. These sections can be split into 'zones' to more granularly distinguish what is happening. + +```java +Profiler.get().push("section"); +// Do code here +Profiler.get().pop(); +``` + +- `com.mojang.blaze3d.systems.RenderSystem#flipFrame` now takes in a `TracyFrameCapture`, or `null` +- `net.minecraft.client.Minecraft#getProfiler` -> `Profiler#get` +- `net.minecraft.client.main.GameConfig$GameData` now takes in a boolean on whether to capture the screen via the tracy client. +- `net.minecraft.client.multiplayer.ClientLevel` no longer takes in the `ProfilerFiller` +- `net.minecraft.server.MinecraftServer#getProfiler` -> `Profiler#get` +- `net.minecraft.server.packs.resources.PreparableReloadListener#reload` no longer takes in the `ProfilerFiller`s +- `net.minecraft.util.profiling` + - `Profiler` - A static handler for managing the currently active `ProfilerFiller`. + - `ProfilerFiller` + - `addZoneText` - Adds text to label when profiling the current frame. + - `addZoneValue` - Adds the value of the zone when profiling the current frame. + - `setZoneColor` - Sets the color of the zone when profiling the current frame. + - `zone` - Adds a profiler section while creating a new zone to call the above methods for. + - `tee` -> `combine` + - `$CombinedProfileFiller` - A profiler that writes to multiple profilers. + - `TracyZoneFiller` - A profiler used by the tracy client to keep track of the currently profiling zones. + - `Zone` - A section that is current being profiled and interpreted by Tracy. +- `net.minecraft.world.entity.ai.goal.GoalSelector` no longer takes in the supplied `ProfilerFiller` +- `net.minecraft.world.level` + - `Level` no longer takes in the `ProfilerFiller` + - `getProfiler`, `getProfilerSupplier` -> `Profiler#get` + - `PathNavigationRegion#getProfiler` -> `Profiler#get` +- `net.minecraft.world.ticks.LevelTicks` no longer takes in the `ProfilerFiller` + +### Tick Throttler + +To prevent the player from spamming certain actions, `TickThrottler` was added. The throttler takes in the threshold and the increment to add to the count. If the count is less than the threshold, the action can occur. The count is reduced every tick. + +- `net.minecraft.util.TickThrottler` - A utility for throttling certain actions from happening too often. + +### Context Keys + +Loot context parameters have been replaced with Context keys, which is simply a more general naming scheme for the previous classes. This also caused the context keys to be used in other contexts that may have arbitrary data. + +For a brief description, the context key system is effectively a general typed dictionary, where each `ContextKey` holds the value type, which is then stored in a backed-map within a `ContextMap`. To enforce required and optional parameters, a `ContextMap` is built with a `ContextKeySet`, which defines the keys of the dictionary map. + +- `net.minecraft.advancements.critereon.CriterionValidator#validate` now takes in a `ContextKeySet` instead of a `LootContextParamSet` +- `net.minecraft.data.loot.LootTableProvider$SubProviderEntry#paramSet` now takes in a `ContextKeySet` instead of a `LootContextParamSet` +- `net.minecraft.util.context` + - `ContextKey` - A key that represents an object. It can be thought of a dictionary key that specifies the value type. + - `ContextKeySet` - A key set which indicates what keys the backing dictionary must have, along with optional keys that can be specified. + - `ContextMap` - A map of context keys to their typed objects. +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect#codec` now takes in a `ContextKeySet` instead of a`LootContextParamSet` + - `TargetedConditionalEffect#codec` now takes in a `ContextKeySet` instead of a`LootContextParamSet` +- `net.minecraft.world.level.storage.loot` + - `LootContext` + - `hasParam` -> `hasParameter` + - `getParam` -> `getParameter` + - `getParamOrNull` - `getOptionalParameter` + - `$EntityTraget#getParam` now returns a `ContextKey` instead of a `LootContextParam` + - `LootContextUser#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + - `LootParams` now takes in a `ContextMap` instead of a map of params to objects + - `hasParam`, `getParameter`, `getOptionalParameter`, `getParamOrNull` are accessible through the `ContextMap` under different names + - `$Builder#withParameter`, `withOptionalParameter`, `getParameter`, `getOptionalParameter` now takes in a `ContextKey` instead of a `LootContextParam` + - `$Builder#create` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `LootTable` + - `getParameSet` now returns a `ContextKeySet` instead of a `LootContextParamSet` + - `$Builder#setParamSet` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `ValidationContext` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `validateUser` -> `validateContextUsage` + - `setParams` - `setContextKeySet` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction$Source#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s +- `net.minecraft.world.level.storage.loot.parameters` + - `LootContextParam` -> `net.minecraft.util.context.ContextKey` + - `LootContextParamSet` -> `net.minecraft.util.context.ContextKeySet` +- `net.minecraft.world.level.storage.loot.providers.nbt` + - `ContextNbtProvider$Getter#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + - `NbtProvider#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s +- `net.minecraft.world.level.storage.loot.providers.score.ScoreboardNameProvider#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + +### List of Additions + +- `com.mojang.blaze3d.framegraph` + - `FrameGraphBuilder` - A builder that constructs the frame graph that define the resources used and the frame passes to render. + - `FramePass` - An interface that defines how to read/write resources and execute them for rendering within the frame graph. +- `com.mojang.blaze3d.platform` + - `ClientShutdownWatchdog` - A watchdog created for what happens when the client is shutdown. + - `NativeImage#getPixelsABGR` - Gets the pixels of the image in ABGR format. + - `Window` + - `isIconified` - Returns whether the window is currently iconified (usually minimized onto the taskbar). + - `setWindowCloseCallback` - Sets the callback to run when the window is closed. +- `com.mojang.blaze3d.resource` + - `CrossFrameResourcePool` - Handles resources that should be rendered across multiple frames + - `GraphicsResourceAllocator` - Handles resources to be rendered and removed. + - `RenderTargetDescriptor` - Defines a render target to be allocated and freed. + - `ResourceDescriptor` - Defines a resource and how it is allocated and freed. + - `ResourceHandle` - Defines a pointer to an individual resource. +- `com.mojang.blaze3d.systems.RenderSystem#overlayBlendFunc` - Sets the default overlay blend function between layers with transparency. +- `com.mojang.blaze3d.vertex` + - `PoseStack#translate(Vec3)` - Translates the top pose using a vector + - `VertexConsumer#setNormal(PoseStack$Pose, Vec3)` - Sets the normal of a vertex using a vector +- `net.minecraft` + - `Optionull#orElse` - If the first object is null, return the second object. + - `TracingExecutor` - An executor that traces the stack frames of the class references executing. + - `Util` + - `allOf` - ANDs all predicates or a list of predicates provided. If there are no supplied predicates, the method will default to `true`. + - `anyOf` - ORs all predicates or a list of predicates provided. If there are no supplied predicates, the method will default to `false`. + - `makeEnumMap` - Creates an enum map given the enum class and a function to convert the enum to a value. +- `net.minecraft.advancements.critereon` + - `InputPredicate` - A predicate that matches the input the player is making. + - `SheepPredicate` - A predicate for when the entity is a sheep. +- `net.minecraft.client` + - `Minecraft` + - `saveReport` - Saves a crash report to the given file. + - `triggerResourcePackRecovery` - A function that attempts to save the game when a compilation exception occurs, currently used by shaders when loading. + - `Options#highContrastBlockOutline` - When enabled, provides a greater contrast when hovering over a block in range. + - `ScrollWheelHandler` - A handler for storing information when a mouse wheel is scrolled. +- `ItemSlotMouseAction` - An interface that defines how the mouse interacts with a slot when hovering over. +- `net.minecraft.client.gui.components` + - `AbstractSelectionList#setSelectedIndex` - Sets the selected entry based on its index. + - `AbstractWidget#playButtonClickSound` - Plays the button click sound. + - `DebugScreenOverlay#getProfilerPieChart` - Gets the pie chart profiler renderer. +- `net.minecraft.client.gui.components.debugchart.AbstractDebugChart#getFullHeight` - Returns the height of the rendered chart. +- `net.minecraft.client.gui.components.toasts` + - `Toast` + - `getWantedVisbility` - Returns the visbility of the toast to render. + - `update` - Updates the data within the toast. + - `TutorialToast` has a constructor that takes in an `int` to represent the time to display in milliseconds. +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` + - `renderChar` - Renders a character in the specified color. + - `$GlyphInstance` - An instance of a glyph with the metadata of its screen location. +- `net.minecraft.client.gui.screens` + - `BackupConfirmScreen` has a constructor that takes in another `Component` that represents the prompt for erasing the cache. + - `Screen` + - `getFont` - Returns the current font used for rendering the screen. + - `showsActiveEffects` - When true, shows the mob effects currently applied to the player, assuming that such functionality is added to the screen in question. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen` + - `BACKGROUND_TEXTURE_WIDTH`, `BACKGROUND_TEXTURE_HEIGHT` - Both set to 256. + - `addItemSlotMouseAction` - Adds a mouse action when hovering over a slot. + - `renderSlots` - Renders all active slots within the menu. + - `AbstractRecipeBookScreen` - A screen that has a renderable and interactable `RecipeBookComponent` supplied from the constructor. +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent#showTooltipWithItemInHand`- Returns whether the tooltip should be rendered when the item is in the player's hand. +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldCallback` - An interface that creates the world given the current screen, registries, level data, and path directory. + - `CreateWorldScreen#testWorld` - Tries to open the world create screen with the provided generation settings context. + - `InitialWorldCreationOptions` - Contains the options set when creating the world to generate. + - `WorldCreationContextMapper` - An interface that creates the world context from the available resource reloaders and registries. +- `net.minecraft.client.multiplayer` + - `ClientChunkCache` + - `getLoadedEmptySections` - Returns the sections that have been loaded by the game, but has no data. + - `ClientLevel` + - `isTickingEntity` - Returns whether the entity is ticking in the level. + - `setSectionRangeDirty`- Marks an area as dirty to update during persistence and network calls. + - `onSectionBecomingNonEmpty` - Updates the section when it has data. + - `PlayerInfo#setTabListOrder`, `getTabListOrder` - Handles the order of players to cycle through in the player tab. +- `net.minecraft.client.multiplayer.chat.report.ReportReason#getIncompatibleCategories` - Gets all reasons that cannot be reported for the given type. +- `net.minecraft.client.particle.TrailParticle` - A particle to trail from its current position to the target position. +- `net.minecraft.client.player.LocalPlayer#getDropSpamThrottler` - Returns a throttler that determines when the player can drop the next item. +- `net.minecract.client.renderer` + - `CloudRenderer` - Handles the rendering and loading of the cloud texture data. + - `DimensionSpecialEffects#isSunriseOrSunset` - Returns whether the dimension time represents sunrise or sunset in game. + - `LevelEventHandler` - Handles the events sent by the `Level#levelEvent` method. + - `LevelRenderer` + - `getCapturedFrustrum` - Returns the frustrum box of the renderer. + - `getCloudRenderer` - Returns the renderer for the clouds in the skybox. + - `onSectionBecomingNonEmpty` - Updates the section when it has data. + - `LevelTargetBundle` - Holds the resource handles and render targets for the rendering stages. + - `LightTexture` + - `getBrightness` - Returns the brightness of the given ambient and sky light. + - `lightCoordsWithEmission` - Returns the packed light coordinates. + - `RenderType` + - `entitySolidZOffsetForward` - Gets a solid entity render type where the z is offset from the individual render objects. + - `flatClouds` - Gets the render type for flat clouds. + - `debugTriangleFan` - Gets the render type for debugging triangles. + - `vignette` - Gets the vignette type. + - `crosshair` - Gets the render type for the player crosshair. + - `mojangLogo` - Gets the render type for the mojang logo + - `Octree` - A traversal implementation for defining the order sections should render in the frustum. + - `ShapeRenderer` - Utility for rendering basic shapes in the Minecraft level. + - `SkyRenderer` - Renders the sky. + - `WeatherEffectRenderer` - Renders weather effects. + - `WorldBorderRenderer` - Renders the world border. +- `net.minecraft.client.renderer` + - `SectionOcclusionGraph#getOctree` - Returns the octree to handle traversal of the render sections. + - `ViewArea#getCameraSectionPos` - Gets the section position of the camera. +- `net.minecraft.client.renderer.culling.Frustum` + - `getFrustumPoints` - Returns the frustum matrix as an array of `Vector4f`s. + - `getCamX`, `getCamY`, `getCamZ` - Returns the frustum camera coordinates. +- `net.minecraft.client.renderer.chunk.CompileTaskDynamicQueue` - A syncrhonized queue dealing with the compile task of a chunk render section. +- `net.minecraft.client.renderer.debug` + - `ChunkCullingDebugRenderer` - A debug renderer for when a chunk is culled. + - `DebugRenderer` + - `renderAfterTranslucents` - Renders the chunk culling renderer after translucents have been rendered. + - `renderVoxelShape` - Renders the outline of a voxel shape. + - `toggleRenderOctree` - Toggles whether `OctreeDebugRenderer` is rendered. + - `OctreeDebugRenderer` - Renders the order of the section nodes. +- `net.minecraft.client.renderer.texture.AbstractTexture#defaultBlur`, `getDefaultBlur` - Returns whether the blur being applied is the default blur. +- `net.minecraft.client.resources.DefaultPlayerSkin#getDefaultSkin` - Returns the default `PlayerSkin`. +- `net.minecraft.commands.CommandBuildContext#enabledFeatures` - Returns the feature flags +- `net.minecraft.commands.arguments.selector.SelectorPattern` - A record that defines an `EntitySelector` resolved from some pattern. +- `net.minecraft.core` + - `BlockPos#betweenClosed` - Returns an iterable of all positions within the bounding box. + - `Direction` + - `getYRot` - Returns the Y rotation of a given direction. + - `getNearest` - Returns the nearest direction given some XYZ coordinate, or the fallback direction if no direction is nearer. + - `getUnitVec3` - Returns the normal unit vector. + - `$Axis#getPositive`, `getNegative`, `getDirections` - Gets the directions along the axis. + - `GlobalPos#isCloseEnough` - Returns whether the distance from this position to another block position in a dimension is within the given radius. + - `HolderLookup$Provider` + - `listRegistries` - Returns the registry lookups for every registry. + - `allRegistriesLifecycle` - Returns the lifecycle of all registries combined. + - `HolderSet#isBound` - Returns whether the set is bound to some value. + - `Registry$PendingTags#size` - Gets the number of tags to load. + - `Vec3i#distChessboard` - Gets the maximum absolute distance between the vector components. +- `net.minecraft.core.component` + - `DataComponentHolder#getAllOfType` - Returns all data components that are of the specific class type. + - `DataComponentPredicate` + - `someOf` - Constructs a data component predicate where the provided map contains the provided component types. + - `$Builder#expect` - Adds that we should expect the data component has some value. + - `PatchedDataComponentMap#clearPatch` - Clears all patches to the data components on the object. +- `net.minecraft.core.particles.TargetColorParticleOption` - A particle option that specifies a target location and a color of the particle. +- `net.minecraft.data.DataProvider` + - `saveAll` - Writes all values in a resource location to value map to the `PathProvider` using the provided codec. + - `saveStable` - Writes a value to the provided path given the codec. +- `net.minecraft.data.loot#BlockLootSubProvider` + - `createMossyCarpetBlockDrops` - Creates a loot table for a mossy carpet block. + - `createShearsOrSlikTouchOnlyDrop` - Creates a loot table that can only drop its item when mined with shears or an item with the silk touch enchantment. +- `net.minecraft.data.worldgen.Pools#createKey` - Creates a `ResourceKey` for a template pool. +- `net.minecraft.data.models.EquipmentModelProvider` - A model provider for equipment models, only includes vanilla bootstrap. +- `net.minecraft.data.info.DatapackStructureReport` - A provider that returns the structure of the datapack. +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `absoluteAABB`, `relativeAABB` - Moves the bounding box between absolute coordinates and relative coordinates to the test location + - `assertEntityData` - Asserts that the entity at the provided block position matches the predicate. + - `hurt` - Hurts the entity the specified amount from a source. + - `kill` - Kills the entity. + - `GameTestInfo#getTestOrigin` - Gets the origin of the spawn structure for the test. + - `StructureUtils#getStartCorner` - Gets the starting position of the test to run. +- `net.minecraft.network` + - `FriendlyByteBuf` + - `readVec3`, `writeVec3` - Static methods to read and write vectors. + - `readContainerId`, `writeContainerId` - Methods to read and write menu identifiers. + - `readChunkPos`, `writeChunkPos` - Methods to read and write the chunk position. + - `StreamCodec#composite` - A composite method that takes in seven/eight parameters. +- `net.minecraft.network.codec.ByteBufCodecs` + - `CONTAINER_ID` - A stream codec to handle menu identifiers. + - `ROTATION_BYTE` - A packed rotation into a byte. + - `LONG` - A stream codec for a long, or 64 bytes. + - `OPTIONAL_VAR_INT` - A stream codec for an optional integer, serializing `0` when not present, or one above the stored value. + - `-1` cannot be sent properly using this stream codec. +- `net.minecraft.network.protocol.game` + - `ClientboundEntityPositionSyncPacket` - A packet that syncs the entity's position. + - `ClientboundPlayerRotationPacket` - A packet that contains the player's rotation. +- `net.minecraft.server` + - `MinecraftServer` + - `tickConnection` - Ticks the connection for handling packets. + - `reportPacketHandlingException` - Reports a thrown exception when attempting to handle a packet + - `pauseWhileEmptySeconds` - Determines how many ticks the server should be paused for when no players are on. + - `SuppressedExceptionCollector` - A handler for exceptions that were supressed by the server. +- `net.minecraft.server.commands.LookAt` - An interface that defines what should happen to an entity when the command is run, typically moving it to look at another. +- `net.minecraft.server.level` + - `ChunkHolder#hasChangesToBroadcast` - Returns whether there is any updates within the chunk to send to the clients. + - `ChunkTaskDispatcher` - A task scheduler for chunks. + - `DistanceManager` + - `getSpawnCandidateChunks` - Returns all chunks that the player can spawn within. + - `getTickingChunks` - Returns all chunks that are currently ticking. + - `ServerChunkCache#onChunkReadyToSend` - Adds a chunk holder to broadcast to a queue. + - `ServerEntityGetter` - An entity getter interface implementation that operates upon the `ServerLevel`. + - Replcaes the missing methods from `EntityGetter` + - `ServerPlayer` + - `getTabListOrder` - Handles the order of players to cycle through in the player tab. + - `getLastClientInput`, `setLastClientInput`, `getLastClientMoveIntent` - Handles how the server player interprets the client impulse. + - `commandSource` - Returns the player's source of commands. + - `createCommandSourceStack` - Creates the source stack of the player issuing the command. + - `ThrottlingChunkTaskDispatcher` - A chunk task dispatcher that sets a maximum number of chunks that can be executing at once. + - `TickingTracker#getTickingChunks` - Returns all chunks that are currently ticking. +- `net.minecraft.server.packs.repository.PackRepository#isAbleToClearAnyPack` - Rebuilds the selected packs and returns whether it is different from the currently selected packs. +- `net.minecraft.resources.DependantName` - A reference object that maps some registry object `ResourceKey` to a value. Acts similarly to `Holder` except as a functional interface. +- `net.minecraft.tags.TagKey#streamCodec` - Constructs a stream codec for the tag key. +- `net.minecraft.util` + - `ARGB#vector3fFromRGB24` - Creates a `Vector3f` containing the RGB components using the low 24 bits of an integer. + - `BinaryAnimator` - A basic animator that animates between two states using an easing function. + - `ExtraCodecs` + - `NON_NEGATIVE_FLOAT` - A float codec that validates the value cannot be negative. + - `RGB_COLOR_CODEC` - An integer, float, or three vector float codec representing the RGB color. + - `nonEmptyMap` - A map codec that validates the map is not empty. + - `Mth` + - `wrapDegrees` - Sets the degrees to a value within (-180, 180]. + - `lerp` - Linear interpolation between two vectors using their components. + - `length` - Gets the length of a 2D point in space. + - `easeInOutSine` - A cosine function that starts at (0,0) and alternates between 1 and 0 every pi. + - `packDegrees`, `unpackDegrees` - Stores and reads a degree in `float` form to a `byte`. + - `RandomSource#triangle` - Returns a random `float` between the two `floats` (inclusive, exclusive) using a trangle distribution. + - `StringRepresentable$EnumCodec#byName` - Gets the enum by its string name or the provided supplier value if null. + - `TriState` - An enum that represents three possible states: true, false, or default. +- `net.minecraft.util.datafix.ExtraDataFixUtils` + - `patchSubType` - Rewrites the second type to the third type within the first type. + - `blockState` - Returns a dynamic instance of the block state + - `fixStringField` - Modifies the string field within a dynamic. +- `net.minecraft.util.thread.BlockableEventLookup` + - `BLOCK_TIME_NANOS` - Returns the amount of time in nanoseconds that an event will block the thread. + - `isNonRecoverable` - Returns whether the exception can be recovered from. +- `net.minecraft.world.damagesource.DamageSources` + - `enderPearl` - Returns a damage source from when an ender pearl is hit. + - `mace` - Returns a damage source where a direct entity hits another with a mace. +- `net.minecraft.world.entity` + - `Entity` + - `applyEffectsFromBlocks` - Applies any effects from blocks via `Block#entityInside` or hardcoded checks like snow or rain. + - `isAffectedByBlocks` - Returns whether the entity is affect by the blocks when inside. + - `checkInsideBlocks` - Gets all blocks that teh player has traversed and checks whether the entity is inside one and adds them to a set when present. + - `oldPosition`, `setOldPosAndrot`, `setOldPos`, `setOldRot` - Helpers for updating the last position and rotation of the entity. + - `getXRot`, `getYRot` - Returns the linearly interpolated rotation of the entity given the partial tick. + - `isAlliedTo(Entity)` - Returns whether the entity is allied to this entity. + - `teleportSetPosition` - Sets the position and rotation data of the entity being teleported via a `DimensionTransition` + - `getLootTable` - Returns the `ResourceKey` of the loot table the entity should use, if present. + - `isControlledByOrIsLocalPlayer` - Return whether the entity is the local player or is controlled by a local player. + - `shouldPlayLavaHurtSound` - When `true`, plays the lava hurt sound when the entity is hurt by lava. + - `onRemoval` - A method that gets called when the entity is removed. + - `cancelLerp` - Stops any lerped movement. + - `forceSetRotation` - Sets the rotation of the entity. + - `isControlledByClient` - Returns whether the entity is controlled by client inputs. + - `EntityType` + - `getDefaultLootTable` now returns an `Optional` in case the loot table is not present + - `$Builder#noLootTable` - Sets the entity type to have no loot spawn on death. + - `$Builder#build` now takes in the resouce key of the entity type + - `EntitySelector#CAN_BE_PICKED` - Returns a selector that gets all pickable entities not in spectator. + - `LivingEntity` + - `dropFromShearingLootTable` - Resolves a loot table with a shearing context. + - `getItemHeldByArm` - Returns the stack held by the specific arm. + - `getEffectiveGravity` - Returns the gravity applied to the entity. + - `canContinueToGlide` - Returns whether the entity can stil glide in the sky. + - `getItemBlockingWith` - Returns the stack the player is currently blocking with. + - `canPickUpLoot` - Returns whether the entity can pick up items. + - `dropFromGiftLootTable` - Resolves a loot table with a gift context. + - `handleExtraItemsCreatedOnUse` - Handles when a living entity gets a new item as a result of using another item. + - `isLookingAtMe` - Checks whether the provided entity is looking at this entity. + - `PositionMoveRotation` - A helper for handling the position and rotation of the entity in context. + - `WalkAnimationState#stop` - Stops the walking animation of the entity. +- `net.minecraft.world.entity.ai.attributes` + - `AttributeInstance` + - `getPermanentModifiers` - Returns all permanent modifiers applied to the entity. + - `addPermanentModifiers` - Adds a collection of permanent modifiers to apply. + - `AttributeMap#assignPermanentModifiers` - Copies the permanent modifiers from another map. +- `net.minecraft.world.entity.ai.control.Control#rotateTowards` - Returns a float that rotates to some final rotation by the provided difference within a clamped value. +- `net.minecraft.world.entity.ai.goal.Goal#getServerLevel` - Gets the server level given the entity or a level. +- `net.minecraft.world.entity.ai.navigation.PathNavigation` + - `updatePathfinderMaxVisitedNodes` - Updates the maximum number of nodes the entity can visit. + - `setRequiredPathLength` - Sets the minimum length of the path the entity must take. + - `getMaxPathLength` - Returns the maximum length of the path the entity can take. +- `net.minecraft.world.entity.ai.sensing` + - `PlayerSensor#getFollowDistance` - Returns the following distance of this entity. + - `Sensor#wasEntityAttackableLastNTicks` - Returns a predicate that checks whether the entity is attackable within the specified number of ticks. +- `net.minecraft.world.entity.ai.village.poi.PoiRecord#pack`, `PoiSection#pack` - Packs the necessary point of interest information. This only removes the dirty runnable. +- `net.minecraft.world.entity.animal` + - `AgeableWaterCreature` - A water creature that has an age state. + - `Animal` + - `createAnimalAttributes` - Creates the attribute supplier for animals. + - `playEatingSound` - Plays the sound an animal makes while eating. + - `Bee#isNightOrRaining` - Returns whether the current level has sky light and is either at night or raining. + - `Cat#isLyingOnTopOfSleepingPlayer` - Returns whether the cat is on top of a sleeping player. + - `Salmon#getSalmonScale` - Returns the scale factor to apply to the entity's bounding box. + - `Wolf#DEFAULT_TAIL_ANGLE` - Returns the default tail angle of the wolf. +- `net.minecraft.world.entity.boss.enderdragon.DragonFlightHistory` - Holds the y and rotation of the dragon when flying through the sky. Used for animating better motion of the dragon's parts. +- `net.minecraft.world.entity.monster.Zombie#canSpawnInLiquids` - When true, the zombie can spawn in a liquid. +- `net.minecraft.world.entity.player` + - `Inventory` + - `isUsableForCrafting` - Returns whether the state can be used in a crafting recipe. + - `createInventoryUpdatePacket` - Creates the packet to update an item in the inventory. + - `Player` + - `handleCreativeModeItemDrop` - Handles what to do when a player drops an item from creative mode. + - `shouldRotateWithMinecart` - Returns whether the player should also rotate with the minecart. + - `canDropItems` - When `true`, the player can drop items from the menu. + - `getPermissionLevel`, `hasPermissions` - Returns the permissions of the player. + - `StackedContents` - Holds a list of contents along with their associated size. + - `$Output` - An interface that defines how the contents are accepted when picked. +- `net.minecraft.world.entity.projectile.Projectile` + - `spawnProjectileFromRotation` - Spawns a projectile and shoots from the given rotation. + - `spawnProjectileUsingShoot` - Spawns a projectile and sets the initial impulse via `#shoot`. + - `spawnProjectile` - Spawns a projectile. + - `applyOnProjectileSpawned` - Applies any additional configurations from the given level and `ItemStack`. + - `onItemBreak` - Handles what happens when the item that shot the projectile breaks. + - `shouldBounceOnWorldBorder` - Returns whether the projectile should bounce off the world border. + - `setOwnerThroughUUID` - Set the owner of the projectile by querying it through its UUID. + - `$ProjectileFactory` - Defines how a projectile is spawned from some `ItemStack` by an entity. +- `net.minecraft.world.entity.vehicle` + - `AbstractBoat` - An entity that represents a boat. + - `AbstractChestBoat` - An entity that represent a boat with some sort of inventory. + - `ChestRaft` - An entity that represents a raft with some sort of inventory. + - `Raft` - An entity that represents a raft. +- `net.minecraft.world.inventory.AbstractContainerMenu` + - `addInventoryHotbarSlots` - Adds the hotbar slots for the given container at the x and y positions. + - `addInventoryExtendedSlots` - Adds the player inventory slots for the given container at the x and y positions. + - `addStandardInventorySlots` - Adds the hotbar and player inventory slots at their normal location for the given container at the x and y positions. + - `setSelectedBundleItemIndex` - Toggles the selected bundle in a slot. +- `net.minecraft.world.item` + - `BundleItem` + - `getOpenBundleModelFrontLocation`, `getOpenBundleModelBackLocation` - Returns the model locations of the bundle. + - `toggleSelectedItem`, `hasSelectedItem`, `getSelectedItem`, `getSelectedItemStack` - Handles item selection within a bundle. + - `getNumberOfItemsToShow` - Determines the number of items in the bundle to show at once. + - `getByColor` - Handles the available links from bundle to dyed bundles. + - `getAllBundleItemColors` - Returns a stream of all dyed bundles. + - `ItemStack` + - `clearComponents` - Clears the patches made to the stack, not the item components. + - `isBroken` - Returns wheter the stack has been broken. + - `hurtWithoutBreaking` - Damages the stack without breaking the stack. + - `getStyledHoverName` - Gets the stylized name component of the stack. +- `net.minecraft.world.item.component.BundleContents` + - `canItemBeInBundle` - Whether the item can be put into the bundle. + - `getNumberOfItemsToShow` - Determines the number of items in the bundle to show at once. + - `hasSelectedItem`, `getSelectedItem` - Handles item selection within a bundle. +- `net.minecraft.world.item.enchantment.EnchantmentHelper` + - `createBook` - Creates an enchanted book stack. + - `doPostAttackEffectsWithItemSourceOnBreak` - Applies the enchantments after attack when the item breaks. +- `net.minecraft.world.level` + - `BlockCollisions` has a constructor to take in a `CollisionContext` + - `BlockGetter#boxTraverseBlocks` - Returns an iterable of the positions traversed along the vector in a given bounding box. + - `CollisionGetter` + - `noCollision` - Returns whether there is no collision between the entity and blocks, entities, and liquids if the `boolean` provided is `true`. + - `getBlockAndLiquidCollisions` - Returns the block and liquid collisions of the entity within the bounding box. + - `clipIncludingBorder` - Gets the block hit result for the specified clip context, clamped by the world border if necessary. + - `EmptyBlockAndTintGetter` - A dummy `BlockAndTintGetter` instance. + - `GameType#isValidId` - Checks whether the id matches an existing game type. + - `LevelHeightAccessor#isInsideBuildHeight` - Returns whether the specified Y coordinate is within the bounds of the level. +- `net.minecraft.world.level.block` + - `Block#UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE` - A block flag that, when enabled, does not update the shape of a redstone wire. + - `BonemealableFeaturePlacerBlock` - A block that places a configured feature and can be bonemealed. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData#resetStatistics` - Resets the data of the spawn to an empty setting, but does not clear the current mobs or the next spawning entity. +- `net.minecraft.world.level.block.piston.PistonMovingBlockEntity#getPushDirection` - Returns the push direction of the moving piston. +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `getEntityInsideCollisionShape`, `$BlockStateBase#getEntityInsideCollisionShape` - Determines the voxel shape of the block when the entity is within it. + - `$Properties#overrideDescription` - Sets the translation key of the block name. + - `StateHolder` + - `getValueOrElse` - Returns the value of the property, else the provided default. + - `getNullableValue` - Returns the value of the property, or null if it does not exist. +- `net.minecraft.world.level.block.state.properties.Property#getInternalIndex` - Converts the provided boolean to a 0 when true, or 1 otherwise. +- `net.minecraft.world.level.border.WorldBorder#clampVec3ToBound` - Clamps the vector to within the world border. +- `net.minecraft.world.level.chunk` + - `ChunkAccess#canBeSerialized` - Returns true, allows the chunk to be written to disk. + - `ChunkSource#onSectionEmptinessChanged` - Updates the section when it has data. + - `LevelChunkSection` + - `copy` - Makes a shallow copy of the chunk section. + - `setUnsavedListener` - Adds a listener which takes in the chunk position whenever the chunk is marked dirty. + - `$UnsavedListener` - A consumer of a chunk position called when the chunk is marked dirty. + - `PalettedContainerRO#copy` - Creates a shallow copy of the `PalettedContainer`. + - `UpgradeData#copy` - Creates a deep copy of `UpgradeData`. +- `net.minecraft.world.level.chunk.storage.IOWorker#store` - Stores the writes of the chunk to the worker. +- `net.minecraft.world.level.levelgen` + - `SurfaceRules$Context#getSeaLevel`, `SurfaceSystem#getSeaLevel` - Gets the sea level of the generator settings. + - `WorldOptions#testWorldWithRandomSeed` - Creates a test world with a randomly generated seed. +- `net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecorator$Context#checkBlock` - Checks if the block at the given position matches the predicate. +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate` + - `getJigsaws` - Returns the jigsaw blocks that are at the provided position with the given rotation. + - `getJointType` - Returns the joint type of the jigsaw block. + - `$JigsawBlockInfo` - A record which contains the block info for a jigsaw block. + - Most methods that involve jigsaws have replaced the `$StructureBlockInfo` with a `$JigsawBlockInfo`. +- `net.minecraft.world.level.lighting.LayerLightSectionStorage#lightOnInColumn` - Returns whether there is light in the zero node section position. +- `net.minecraft.world.level.pathfinder.PathFinder#setMaxVisitedNodes` - Sets the maximum number of nodes that can be visited. +- `net.minecraft.world.level.portal` + - `DimensionTransition#withRotation` - Updates the entity's spawn rotation. + - `PortalShape#findAnyShape` - Finds a `PortalShape` that can be located at the given block position facing the specific direction. +- `net.minecraft.world.phys` + - `AABB` + - `clip` - Clips the vector inside the given bounding box, or returns an empty optional if there is no intersection. + - `collidedAlongVector` - Returns whether this box collided with one of the bounding boxes provided in the list along the provided movement vector. + - `getBottomCenter` - Gets the bottom center of the bounding box as a vector. + - `Vec3` + - `add`, `subtract` - Translates the vector and returns a new object. + - `horizontal` - Returns the horizontal components of the vector. + - `projectedOn` - Gets the unit vector representing this vector projected onto another vector. +- `net.minecraft.world.phys.shapes` + - `CollisionContext` + - `of(Entity, boolean)` - Creates a new entity collision context, where the `boolean` determines whether the entity can always stand on the provided fluid state. + - `getCollisionShape` - Returns the collision shape collided with. + - `VoxelShape#move(Vec3)` - Offsets the voxel shape by the provided vector. +- `net.minecraft.world.ticks.ScheduledTick#toSavedTick` - Converts a scheduled tick to a saved tick. + +### List of Changes + +- `F3 + F` now toggles fog rendering +- `com.mojang.blaze3d.platform` + - `NativeImage` + - `getPixelRGBA`, `setPixelRGBA` are now private. These are replaced by `getPixel` and `setPixel`, respectively + - `getPixelsRGBA` -> `getPixels` + - `Window#updateDisplay` now takes in a `TraceyFrrameCapture`, or `null` +- `net.minecraft.Util` + - `backgroundExecutor`, `ioPool`, and `nonCriticalIoPool` now return a `TracingExecutor` instead of an `ExecutorService` + - `wrapThreadWithTaskName` -> `runNamed` with its parameters flipped and no return value +- `net.minecraft.advancements.critereon` + - `KilledByCrossbowTrigger` -> `KilledByArrowTrigger`, not one-to-one, takes in the stack in question + - `PlayerPredicate` can now match the player's input +- `net.minecraft.client` + - `Minecraft` + - `debugFpsMeterKeyPress` -> `ProfilerPieChart#profilerPieChartKeyPress` obtained via `Minecraft#getDebugOverlay` and then `DebugScreenOverlay#getProfilerPieChart` + - `getTimer` -> `getDeltaTracker` + - `getToasts` -> `getToastManager` + - `Options#setModelPart` is now public, replaces `toggleModelPart` but without broadcasting the change + - `ParticleStatus` -> `net.minecraft.server.level.ParticleStatus` +- `net.minecraft.client.animation.KeyframeAnimations#animate` now takes in a `Model` instead of a `HierarchicalModel` +- `net.minecraft.client.gui.Font` + - `drawInBatch(String, float, float, int, boolean, Matrix4f, MultiBufferSource, Font.DisplayMode, int, int, boolean)` is removed and should use the `Component` replacement + - There is also a delegate that sets the inverse depth boolean to true by default for the `Component` `drawInBatch` method + - `$StringRenderOutput` now takes in the `Font`, an optional background color, and a boolean representing if inverse depth should be use when drawing the text + - `$StringRenderOutput#finish` is now package private +- `net.minecraft.client.gui.components` + - `AbstractSelectionList` + - `replaceEntries` is now public + - `getRowTop`, `getRowBottom` is now public + - `PlayerFaceRenderer#draw(GuiGraphics, ResourceLocation, int, int, int, int)` takes in a `PlayerSkin` instead of a `ResourceLocation` +- `net.minecraft.client.gui.components.toasts` + - `Toast` + - `Toast$Visibility render(GuiGraphics, ToastComponent, long)` -> `void render(GuiGraphics, Font, long)` + - `slotCount` - `occupiedSlotCount` + - `ToastComponent` -> `ToastManager` +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` + - `render` now takes in a single integer representing the color instead of four floats and is private + - `renderChar` is the public replacement, taking in the `$GlyphInstance`, the `Matrix4f`, `VertexConsumer`, and color integer + - `$Effect` is a record, now taking in a single integer representing the color instead of four floats +- `net.minecraft.client.gui.screens` + - `LoadingOverlay#MOJANG_STUDIOS_LOGO_LOCATION` is now public + - `Screen` + - `renderBlurredBackground(float)` -> `renderBlurredBackground()` + - `wrapScreenError` -> `fillCrashDetails`, not one to one as it only adds the relevant crash information and not actually throw the error +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen#renderSlotHighlight` -> `renderSlotHighlightBack`, `renderSlotHighlightFront`, now private + - `BookEditScreen` now takes in the `WritableBookContent` + - `AbstractSignEditScreen` + - `sign` is now protected + - `renderSignBackground` no longer takes in the `BlockState` + - `EffectRenderingInventoryScreen` -> `Screen#hasActiveEffects`, `EffectsInInventory`. Not one-to-one as `EffectsInInventory` now acts as a helper class to a screen to render its effects at the specified location. +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent` + - `getHeight()` -> `getHeight(Font)` + - `renderImage` now takes in the `int` width and height of the rendering tooltip +- `net.minecraft.client.gui.screens.recipebook` + - `GhostSlots#render` no longer takes in an x and y offset. + - `RecipeBookComponent` no longer takes in an x and y offset. +- `net.minecraft.client.gui.screens.reporting.ReportReasonSelectionScreen` now takes in a `ReportType` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldScreen` + - `$DataPackReloadCookie` -> `DataPackReloadCookie` + - `openFresh` now has an overload that takes in the `CreateWorldCallback` + - `WorldCreationContext` now takes in the `InitialWorldCreationOptions` + - `WorldOpenFlows#createFreshLevel` takes in a `Function` instead of `Function` +- `net.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon` now takes in a `float` instead of an `int` to represent the alpha value +- `net.minecraft.client.multiplayer` + - `ClientLevel` now takes in an `int` representing the sea level + - `getSkyColor` now returns a single `int` instead of a `Vec3` + - `getCloudColor` now returns a single `int` instead of a `Vec3` + - `setGameTime`, `setDayTime` -> `setTimeFromServer` + - `TagCollector` -> `RegistryDataCollector$TagCollector`, now package-private +- `net.minecraft.client.player` + - `AbstractClientPlayer#getFieldOfViewModifier` now takes in a boolean representing whether the camera is in first person and a float representing the partial tick + - `Input` -> `ClientInput` and `net.minecraft.world.entity.player.Input` + - `KeyboardInput` now extends `ClientInput` + - `LocalPlayer#input` is now `ClientInput` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#getSunriseColor` -> `getSunriseOrSunsetColor` + - `GameRenderer` + - `processBlurEffect` no longer takes in the partial tick `float` + - `getFov` returns a `float` instead of a `double` + - `getProjectionMatrix` now takes in a `float` instead of a `double` + - `ItemModelShaper` + - `shapes` is now private + - `getItemModel(Item)` is removed + - `getItemModel(ResourceLocation)` - Gets the baked model associated with the provided `ResourceLocation`. + - `register` is removed + - `getModelManager` is removed + - `invalidateCache` - Clears the model map. + - `LevelRenderer` + - `renderSnowAndRain` -> `WeatherEffectRenderer` + - `tickRain` -> `tickParticles` + - `renderLevel` now takes in a `GraphicsResourceAllocator` + - `renderClouds` -> `CloudRenderer` + - `addParticle` is now public + - `globalLevelEvent` -> `LevelEventHandler` + - `entityTarget` -> `entityOutlineTarget` + - `$TransparencyShaderException` no longer takes in the throwable cause + - `SectionOcclusionGraph` + - `onSectionCompiled` -> `schedulePropagationFrom` + - `update` now takes in a `LongOpenHashSet` that holds the currently loaded section nodes + - `$GraphState` is now package-private + - `addSectionsInFrustum` now takes in a list to add the render sections to + - `ShapeRenderer#renderShape` now takes in a single integer for the color instead of four floats + - `ViewArea` + - `repositionCamera` now takes in the `SectionPos` instead of two `double`s + - `getRenderSectionAt` -> `getRenderSection` +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#renderPatterns` now takes in a `boolean` determining the glint render type to use + - `*Renderer` classes that constructed `LayerDefinition`s have now been moved to their associated `*Model` class + - `SignRenderer$SignModel` -> `SignModel` +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` now takes in a `TracingExecutor` rather than just a `Executor` + - `$CompiledSection#hasNoRenderableLayers` -> `hasRenderableLayers` + - `$RenderSection` now takes in a compiled `long` of the section node + - `setOrigin` -> `setSectionNode` + - `getRelativeOrigin` -> `getNeighborSectionNode` + - `cancelTasks` now returns nothing + - `pointOfView` - A reference to the location of where the translucent render type is rendered from. + - `resortTransparency` no longer takes in the `RenderType` and returns nothing + - `hasTranslucentGeometry` - Returns whether the compiled blocks have a translucent render type. + - `transparencyResortingScheduled` - Returns whether the last task was scheduled but not completed. + - `isAxisAlignedWith` -> `$TranslucencyPointOfView#isAxisAligned` + - `$CompileTask` is now public + - No longer `Comparable` + - The constructor no longer takes in the distance at creation + - `isHighPriority` -> `isRecompile` + - `$TranslucencyPointOfView` - Returns the coordinate representing the view point of the tranlucent render type in this section. +- `net.minecraft.client.renderer.culling.Frustum#cubeInFrustum` now returns an `int` representing the index of the first plane that culled the box +- `net.minecraft.client.renderer.DebugRenderer#render` now takes in the `Frustum` +- `net.minecraft.client.renderer.texture.atlas.sources.PalettedPermutations#loadPaletteEntryFromImage` is now private +- `net.minecraft.client.tutorial` + - `Tutorial` + - `addTimedToast`, `#removeTimedToast`, `$TimedToast` -> `TutorialToast` parameter + - `onInput` takes in a `ClientInput` instead of an `Input` + - `TutorialStepInstance` + - `onInput` takes in a `ClientInput` instead of an `Input` +- `net.minecraft.core` + - `Direction` + - `getNearest` -> `getApproximateNearest` + - `getNormal` -> `getUnitVec3i` + - `HolderGetter$Provider#get` no longer takes in the registry key, instead reading it from the `ResourceKey` + - `HolderLookup$Provider` now implements `HolderGetter$Provider` + - `asGetterLookup` is removed as the interface is a `HolderGetter$Provider` + - `listRegistries` -> `listRegistryKeys` + - `Registry` now implements `HolderLookup$RegistryLookup` + - `getTags` only returns a stream of named holder sets + - `asTagAddingLookup` -> `prepareTagReload` + - `bindTags` -> `WritabelRegistry#bindTag` + - `get` -> `getValue` + - `getOrThrow` -> `getValueOrThrow` + - `getHolder` -> `get` + - `getHolderOrThrow` -> `getOrThrow` + - `holders` -> `listElements` + - `getTag` -> `get` + - `holderOwner`, `asLookup` is removed as `Registry` is an instance of them + - `RegistryAccess` + - `registry` -> `lookup` + - `registryOrThrow` -> `lookupOrThrow` + - `RegistrySynchronization#NETWORKABLE_REGISTRIES` -> `isNetworkable` +- `net.minecraft.core.cauldron.CauldronInteraction` + - `FILL_WATER` -> `fillWaterInteraction`, now private + - `FILL_LAVA` -> `fillLavaInteraction`, now private + - `FILL_POWDER_SNOW` -> `fillPowderSnowInteraction`, now private + - `SHULKER_BOX` -> `shulkerBoxInteraction`, now private + - `BANNER` -> `bannerInteraction`, now private + - `DYED_ITEM` -> `dyedItemIteration`, now private +- `net.minecraft.core.dispenser.BoatDispenseItemBehavior` now takes in the `EntityType` to spawn rather that the variant and chest boat boolean +- `net.minecraft.core.particles.DustColorTransitionOptions`, `DustParticleOptions` now takes in integers representing an RGB value instead of `Vector3f`s. +- `net.minecraft.data.loot` + - `BlockLootSubProvider` + - `HAS_SHEARS` -> `hasShears` + - `createShearsOnlyDrop` is now an instance method + - `EntityLootSubProvider` + - `killedByFrog`, `killedByFrogVariant` now take in the getter for the `EntityType` registry + - `createSheepTable` -> `createSheepDispatchPool`, not one-to-one as the table was replaced with a pool builder given a map of dye colors to loot tables +- `net.minecraft.gametest.framework` + - `GameTestHelper#assertEntityPresent`, `assertEntityNotPresent` takes in a bounding box instead of two vectors + - `GameTestInfo#getOrCalculateNorthwestCorner` is now public +- `net.minecraft.network.chat.Component#score` now takes in a `SelectorPattern` +- `net.minecraft.network.chat.contents.ScoreContents`, `SelectorContents` is now a record +- `net.minecraft.network.protocol.login.ClientboundGameProfilePacket` -> `ClientboundLoginFinishedPacket` +- `net.minecraft.network.protocol.game` + - `ClientboundMoveEntityPacket#getyRot`, `getxRot` now returns a `float` of the degrees + - `ClientboundPlayerPositionPacket` is now a record, taking in a `PositionMoverotation` representing the change + - `relativeArguments` -> `relatives` + - `yRot`, `xRot` -> `ClientboundPalyerRotationPacket` + - `ClientboundSetTimePacket` is now a record + - `ClientboundRotateHeadPacket#getYHeadRot` now returns a `float` of the degrees + - `ClientboundTeleportEntityPacket` is now a record, where the necessary parameters are passed into the packet instead of the entity + - `ServerboundPlayerInputPacket` is now a record, taking in an `Input` +- `net.minecraft.resources.RegistryDataLoader$Loader#loadFromNetwork` now takes in a `$NetworkedRegistryData`, which contains the packed registry entries +- `net.minecraft.server` + - `MinecraftServer` no longer implements `AutoCloseable` + - `tickChildren` is now protected + - `wrapRunnable` is now public + - `ReloadableServerRegistries#reload` now takes in a list of pending tags and returns a `$LoadResult` instead of a layered registry access + - `ReloadableServerResources` + - `loadResources` now takes in a list of pending tags and the server `Executor` + - `updateRegistryTags` -> `updateStaticRegistryTags` + - `ServerFunctionLibrary#getTag`, `ServerFunctionManager#getTag` returns a list of command functions +- `net.minecraft.server.level` + - `ChunkHolder` + - `blockChanged`, `sectionLightChanged` now returns `boolean` if the information has changed + - `addSaveDependency` is now protected, a method within `GenerationChunkHolder` + - `ChunkTaskPriorityQueue` no longer takes in a generic + - The constructor no longer takes in the maximum number of tasks to do + - `submit` now takes in a `Runnable` rather than an `Optional` + - `pop` returns a `$TasksForChunk` instead of a raw `Stream` + - `ChunkTaskPriorityQueueSorter` -> `ChunkTaskDispatcher` + - `ServerPlayer` + - `teleportTo` takes in a `boolean` that determines whether the camera should be set + - `INTERACTION_DISTANCE_VERIFICATION_BUFFER` -> `BLOCK_INTERACTION_DISTANCE_VERIFICATION_BUFFER` + - Also splits into `ENTITY_INTERACTION_DISTANCE_VERIFICATION_BUFFER` set to 3.0 + - `findRespawnPositionAndUseSpawnBlock` now deals with `TeleportTransition` + - `TextFilterClient` -> `ServerTextFilter` + - `ThreadedLevelLightEngine` now takes in a `ConsecutiveExecutor` and `ChunkTaskDispatcher` instead of a `ProcessorMailbox` and a `ProcessorHandle`, respectively +- `net.minecraft.server.packs.resources.ProfiledReloadInstance$State` is now a record +- `net.minecraft.sounds.SoundEvent` is now a record +- `net.minecraft.tags` + - `TagEntry$Lookup#element` now takes in a `boolean` representing if the element is required + - `TagLoader` now takes in an `$ElementLookup`, which functions the same as its previous function parameter + - `build` now returns a value of lists + - `loadAndBuild` -> `loadTagsFromNetwork`, `loadTagsForExistingRegistries`, `loadTagsForRegistry`, `buildUpdatedLookups` + - `TagNetworkSerialization$NetworkPayload` + - `size` -> `isEmpty` + - `applyToRegistry` -> `resolve` +- `net.minecraft.util` + - `FastColor` -> `ARGB` + - `scaleRGB` overload with an alpha integer and three floats. + - `Mth#color` -> `ARGB#color` +- `net.minecraft.util.profiling.metrics.MetricCategory#MAIL_BOXES` -> `CONSECUTIVE_EXECUTORS` +- `net.minecraft.util.thread` + - `BlockableEventLoop#waitForTasks` is now protected + - `ProcessorMailbox` no longer implements `AutoCloseable` +- `net.minecraft.util.worldupdate.WorldUpgrader` implements `AutoCloseable` +- `net.minecraft.world.LockCode` now takes in an `ItemPredicate` instead of a `String` representing the item name + - `addToTag`, `fromTag` now takes in a `HolderLookup$Provider` +- `net.minecraft.world.effect` + - `MobEffect#applyEffectTick`, `applyInstantenousEffect`, `onMobRemoved`, `onMobHurt` now takes in the `ServerLevel` + - `MobEffectInstance#onMobRemoved`, `onMobHurt` now takes in the `ServerLevel` +- `net.minecraft.world.entity` + - `AgeableMob$AgeableMobGroupData` now has a public constructor + - `AnimationState#getAccumulatedTime` -> `getTimeInMillis` + - `Entity` no longer implements `CommandSource` + - `setOnGroundWithMovement` now takes in an additional `boolean` representing whether there is any horizontal collision. + - `getInputVector` is now protected + - `isAlliedTo(Entity)` -> `considersEntityAsAlly` + - `teleportTo` now takes in an additional `boolean` that determines whether the camera should be set + - `checkInsideBlocks()` -> `recordMovementThroughBlocks`, not one-to-one as it takes in the movement vectors + - `checkInsideBlocks(Set)` -> `collectBlockCollidedWith`, now private + - `kill` now takes in the `ServerLevel` + - `hurt` has been marked as deprecated, to be replaced by `hurtServer` and `hurtClient` + - `hurtOrSimulate` acts as a helper to determine which to call, also marked as deprecated + - `spawnAtLocation` now takes in a `ServerLevel` + - `isInvulnerableTo` -> `isInvulnerableToBase`, now protected and final + - `isInvulnerableTo` is moved to `LivingEntity#isInvulnerableTo` + - `teleportSetPosition` now public and takes in a `PositionMoveRotation` and `Relative` set instead of the `DimensionTransition` + - `createCommandSourceStack` -> `createCommandSourceStackForNameResolution`, not one to one as it takes in the `ServerLevel` + - `mayInteract` now takes in the `ServerLevel` instead of just the `Level` + - `setOldRot` is now public + - `changeDimension` -> `teleport`, returns `ServerPlayer` given `TeleportTransition` + - `canChangeDimensions` -> `canTeleport` + - `EntitySpawnReason#SPAWN_EGG` -> `SPAWN_ITEM_USE`, not one-to-one as this indicates the entity can be spawned from any item + - `EntityType` + - `create`, `loadEntityRecursive`, `loadEntitiesRecursive`, `loadStaticEntity` now takes in an `EntitySpawnReason` + - `*StackConfig` now takes in a `Level` instead of a `ServerLevel` + - `EquipmentTable` now has a constructor that takes in a single float representing the slot drop chance for all equipment slots + - `MobSpawnType` -> `EntitySpawnReason` + - `Leashable#tickLeash` now takes in the `ServerLevel` + - `LivingEntity` + - `getScale` is now final + - `onAttributeUpdated` is now protected + - `activeLocationDependentEnchantments` now takes in an `EquipmentSlot` + - `handleRelativeFrictionAndCalculateMovement` is now private + - `updateFallFlying` is now protected + - `onEffectRemoved` -> `onEffectsRemoved` + - `spawnItemParticles` is now public + - `getLootTable` -> `Entity#getLootTable`, wrapped in optional + - `getBaseExperienceReward` now takes in the `ServerLevel` + - `triggerOnDeathMobEffects` now takes in the `ServerLevel` + - `canAttack` is removed + - `dropEquipment` now takes in the `ServerLevel` + - `dropExperience` now takes in the `ServerLevel` + - `dropFromLootTable` now takes in the `ServerLevel` + - `actuallyHurt`, `doHurtTarget` now takes in the `ServerLevel` + - `hasLineOfSight` overload with clip contexts and a eye y supplier + - `makePoofParticles` is now public + - `Mob` + - `pickUpItem`, `wantsToPickUp` now takes in the `ServerLevel` + - `equipItemIfPossible` now takes in the `ServerLevel` + - `customServerAiStep` now takes in the `ServerLevel` + - `dropPreservedEquipment` now takes in the `ServerLevel` + - `NeutralMob` + - `isAngryAt`, `isAngryAtAllPlayers` now takes in the `ServerLevel` + - `playerDied` now takes in the `ServerLevel` + - `PortalProcessor#getPortalDestination` now returns a `TeleportTransition` + - `PositionMoveRotation` + - `of(ClientboundPlayerPositionPacket)` -> `ofEntityUsingLerpTarget(Entity)` + - `of(DimensionTransition)` -> `of(TeleportTransition)` + - `Shearable#shear` now takes in the `ServerLevel` and `ItemStack` that is shearing the entity + - `RelativeMovement` -> `Relative`, expanded to contain delta movement + - `WalkAnimationState#update` now takes in an additional `float` representing the position scale when moving. +- `net.minecraft.world.entity.ai.behavior` + - `StartAttacking` now takes in a `$TargetFinder` and additionally a `$StartAttackingCondition` + - Both are functional interfaces that replace the previous functions/predicates, though with an extra `ServerLevel` parameter + - `StopAttackingIfTargetInvalid` now takes in a `$TargetErasedCallback` and/or a `$StopAttackCondition` + - Both are functional interfaces that replace the previous consumers/predicates, though with an extra `ServerLevel` parameter + - `MeleeAttack#create` can now take in a predicate to test the mob for + - `Swim` now takes in a generic representing the mob +- `net.minecraft.world.entity.ai.control.LookControl#rotateTowards` -> `Control#rotateTowards` +- `net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal` now takes in a `$Selector` + - It is a functional interface that replaces the previous predicate, though with an extra `ServerLevel` parameter +- `net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities` now takes in a `ServerLevel` +- `net.minecraft.world.entity.ai.sensing` + - `NearestLivingEntitySensor` + - `radiusXZ`, `radiusY` -> `Attributes#FOLLOW_RANGE` + - `isMatchingEntity` now takes in a `ServerLevel` + - `Sensor` + - `TARGETING_RANGE` is now private + - `isEntityTargetable`, `isEntityAttackable`, `isEntityAttackableIgnoringLineOfSight` now take in a `ServerLevel` + - `wasEntityAttackableLastNTicks`, `rememberPositives` now delas with `BiPredicate`s instead of `Predicate`s +- `net.minecraft.world.entity.ai.targeting.TargetingConditions` + - `selector` now takes in a `$Selector` + - It is a functional interface that replaces the previous predicate, though with an extra `ServerLevel` parameter + - `test` now takes in a `ServerLevel` +- `net.minecraft.world.entity.ai.village.poi.PoiRecord#codec`, `PoiSection#codec` -> `$Packed#CODEC` +- `net.minecraft.world.entity.animal` + - `Fox$Type` -> `$Variant` + - `MushroomCow$MushroomType` -> `$Variant` + - `$Variant` no longer takes in the loot table + - `Salmon` now has a variant for its size + - `Wolf` + - `getBodyRollAngle` -> `#getShakeAnim`, not one-to-one as the angle is calculated within the render state + - `hasArmor` is removed +- `net.minecraft.world.entity.animal.horse.AbstractHorse#followMommy` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.enderdragon.EnderDragon#onCrystalDestroyed` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.enderdragon.phases.DragonPhaseInstance#doServerTick` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.wither.WitherBoss#getHead*Rot` -> `getHead*Rots`, returns all rotations rather than just the provided index +- `net.minecraft.world.entity.decoration` + - `ArmorStand` default rotations are now public + - `isShowArms` -> `showArms` + - `isNoBasePlate` -> `showBasePlate` + - `PaintingVariant` now takes in a title and author `Component` +- `net.minecraft.world.entity.item.ItemEntity#getSpin` is now static +- `net.minecraft.world.entity.monster.Monster#isPreventingPlayerRest` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.breeze.Breeze#getSnoutYPosition` -> `getFiringYPosition` +- `net.minecraft.world.entity.monster.hoglin.HoglinBase#hurtAndThrowTarget` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.piglin.PiglinAi#isWearingGold` -> `#isWearingSafeArmor` +- `net.minecraft.world.entity.npc.InventoryCarrier#pickUpItem` now takes in a `ServerLevel` +- `net.minecraft.world.entity.player` + - `Player#disableShield` now takes in the stack to apply the cooldown to + - `Inventory` + - `findSlotMatchingUnusedItem` -> `findSlotMatchingCraftingIngredient` + - `swapPaint` -> `setSelectedHotbarSlot` + - `StackedContents` -> `StackedItemContents` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow#inGround` -> `IN_GROUND`, now an `EntityDataAccessor` + - Protected accessible via `isInGround` and `setInGround` + - `ThrowableItemProjectile` can now take in an `ItemStack` of the item thrown +- `net.minecraft.world.entity.raid.Raid#getLeaderBannerInstance` -> `getOminousBannerInstance` +- `net.minecraft.world.entity.vehicle` + - `Boat$Type` now takes in the supplied boat item and the translation key for the item, but no longer take in the planks they are made from + - `ContainerEntity` + - `*LootTable*` -> `ContainerLootTable` + - `chestVehicleDestroyed` now takes in a `ServerLevel` + - `VehicleEntity` + - `destroy` now takes in a `seerverLevel` + - `getDropItem` is now protected +- `net.minecraft.world.item` + - `BoatItem` now takes in an `EntityType` instead of the variant and chest boolean + - `ItemStack#hurtEnemy`, `postHurtEnemy` now take in a `LivingEntity` instead of a `Player` + - `SmithingTemplateItem` now takes in the `Item.Properties` instead of hardcoding it, also true for static initializers + - `UseAnim` -> `ItemUseAnimation` +- `net.minecraft.world.item.crafting.ShulkerBoxColoring` -> `TransmuteRecipe`, expanded to copy any data stored on the item to the result item +- `net.minecraft.world.item.enchantment.EnchantmentHelper` + - `onProjectileSpawned` now takes in a `Projectile` instead of an `AbstractArrow` +- `net.minecraft.world.item.enchantment.effects.DamageItem` -> `ChangeItemDamage` +- `net.minecraft.world.level` + - `GameRules` takes in a `FeatureFlagSet` during any kind of construction + - `$IntegerValue#create` takes in a `FeatureFlagSet` + - `$Type` takes in a `FeatureFlagSet` + - `Level` + - `setSpawnSettings` no longer takes in a `boolean` to determine whether to spawn friendlies + - `getGameRules` -> `ServerLevel#getGameRules` + - `LevelAccessor` now implements `ScheduledTickAccess`, an interface that now contains the tick scheduling methods that were originally on `LevelAccessor` + - `neighborShapeChanged` switches the order of the `BlockState` and neighbor `BlockPos` parameters + - `LevelHeightAccessor` + - `getMinBuildHeight` -> `getMinY` + - `getMaxBuildHeight` -> `getMaxY`, this value is one less than the previous version + - `getMinSection` -> `getMinSectionY` + - `getMaxSection` -> `getMaxSectionY`, this value is one less than the previous version + - `NaturalSpawner#spawnForChunk` has been split into two methods: `getFilteredSpawningCategories`, and `spawnForChunk` +- `net.minecraft.world.level.biome#Biome#getPrecipitationAt`, `coldEnoughToSnow`, `warmEnoughToRain`, `shouldMeltFrozenOceanIcebergSlightly` now takes in an `int` representing the the base height of the biome +- `net.minecraft.world.level.block` + - `Block` + - `shouldRenderFace` takes in the relative state for the face being checked, no longer passing in the `BlockGetter` or `BlockPos`s. + - `updateEntityAfterFallOn` -> `updateEntityMovementAfterFallOn` + - `$BlockStatePairKey` -> `FlowingFluid$BlockStatePairKey`, now package private + - `getDescriptionId` -> `BlockBehaviour#getDescriptionId`, also a protected field `descriptionId` + - `ChestBlock` constructor switched its parameter order + - `Portal#getPortalDestination` now returns `TeleportTransition` +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity#serverTick` now takes in a `ServerLevel` instead of a `Level` + - `BrushableBlockEntity` + - `brush` now takes in the level and stack performing the brushing behavior + - `unpackLootTable` is now private + - `checkReset` now takes in the server level +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `getOcclusionShape`, `getLightBlock`, `propagatesSkylightDown` only takes in the `BlockState`, not the `BlockGetter` or `BlockPos` + - `getLootTable` now returns an `Optional`, also a protected field `drops` + - `$BlockStateBase#getOcclusionShape`, `getLightBlock`, `getFaceOcclusionShape`, `propagatesSkylightDown`, `isSolidRender` no longer takes in the `BlockGetter` or `BlockPos` + - `$BlockStateBase#getOffset` no longer takes in the `BlockGetter` + - `$OffsetFunction#evaluate` no longer takes in the `BlockGetter` + - `$Properties#dropsLike` -> `overrideLootTable` + - `StateHolder#findNextInCollection` now takes in a `List` instead of a `Collection` +- `net.minecraft.world.level.chunk` + - `ChunkAccess` + - `addPackedPostProcess` now takes in a `ShortList` instead of a single `short` + - `getTicksForSerialization` now takes in a `long` of the game time + - `unsaved` is now private + - `setUnsaved` -> `markUnsaved`, `tryMarkSaved` + - `$TicksToSave` -> `$PackedTicks` + - `ChunkSource#setSpawnSettings` no longer takes in a `boolean` to determine whether to spawn friendlies + - `LevelChunk#postProcessGeneration` now takes in a `ServerLevel` + - `Palette#copy` now takes in a `PaletteResize` +- `net.minecraft.world.level.chunk.status.WorldGenContext` now takes in an `Executor` or the main thread rather than a processor handle mail box + - The construtor also takes in a `LevelChunk$UnsavedListener` for when a chunk is marked as dirty +- `net.minecraft.world.level.chunk.storage` + - `ChunkSerializer` -> `SerializableChunkData` + - `ChunkStorage#write` now takes in a supplied `CompoundTag` instead of the instance itself + - `SectionStorage` now takes in a second generic representing the packed form of the storage data + - The constructor now takes in the packed codec, a function to convert the storage to a packed format, and a function to convert the packed and dirty runnable back into the storage. +- `net.minecraft.world.level.levelgen` + - `Aquifer$FluidStatus` is now a record + - `WorldDimensions#withOverworld` now takes in a `HolderLookup` instead of the `Registry` itself + - `BlendingData` now has a packed and unpacked state for serializing the interal data as a simple object +- `net.minecraft.world.level.levelgen.material.MaterialRuleList` now takes in an array instead of a list +- `net.minecraft.world.level.levelgen.placement.PlacementContext#getMinBuildHeight` -> `getMinY` +- `net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement#getShuffledJigsawBlocks` now returns a `StructureTemplate$JigsawBlockInfo` +- `net.minecraft.world.level.lighting` + - `LevelLightEngine#lightOnInSection` -> `lightOnInColumn` + - `LightEngine` + - `hasDifferentLightProperties`, `getOcclusionShape` no longer takes in the `BlockGetter` or `BlockPos` + - `getOpacity` no longer takes in the `BlockPos` + - `shapeOccludes` no longer takes in the two `longs` representing the packed positions +- `net.minecraft.world.level.material` + - `FlowingFluid` + - `spread` now takes in the `BlockState` at the current position + - `getSlopeDistance` previous parameters have been merged into a `$SpreadContext` object + - `spread`, `getNewLiquid`, `canConvertToSource`, `getSpread` now takes in a `ServerLevel` + - `Fluid` + - `tick` now takes in the `BlockState` at the current position + - `tick` and `randomTick` now take in the `ServerLevel` + - `FluidState` + - `tick` now takes in the `BlockState` at the current position + - `tick` and `randomTick` now take in the `ServerLevel` + - `MapColor#calculateRGBColor` -> `calculateARGBColor` +- `net.minecraft.world.level.portal` + - `DimensionTransition` -> `TeleportTransition` + - `pos` -> `position` + - `speed` -> `deltaMovement` + - The constructor can now take in a set of `Relatives` to indicate in what motions should the positions be moved relative to another + - `PortalShape#createPortalBlocks` now takes in a `LevelAccessor` +- `net.minecraft.world.level.saveddata.SavedData#save(File, HolderLookup$Provider)` now returns `CompoundTag`, not writing the data to file in the method +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` now implements `AutoCloseable` + - The constructor takes in a `Path` instead of a `File` + - `save` -> `scheduleSave` and `saveAndJoin` + - `LevelData#getGameRules` -> `ServerLevelData#getGameRules` +- `net.minecraft.world.phys.BlockHitResult` now takes in a boolean representing if the world border was hit + - Adds in two helpers `hitBorder`, `isWorldBorderHit` +- `net.minecraft.world.ticks` + - `ProtoChunkTicks#load` now takes in a list of saved ticks + - `SavedTick#loadTickList` now returns a list of saved ticks, rather than consuming them + - `SerializableTickContainer#save` -> `pack` + +### List of Removals + +- `com.mojang.blaze3d.Blaze3D` + - `process` + - `render` +- `com.mojang.blaze3d.pipeline.RenderPipeline` + - Replaced by `com.mojang.blaze3d.framegraph.*` and `com.mojang.blaze3d.resources.*` +- `com.mojang.blaze3d.platform.NativeImage` + - `setPixelLuminance` + - `getRedOrLuminance`, `getGreenOrLuminance`, `getBlueOrLuminance` + - `blendPixel` + - `asByteArray` +- `com.mojang.blaze3d.systems.RenderSystem` + - `glGenBuffers` + - `glGenVertexArrays` + - `_setShaderTexture` + - `applyModelViewMatrix` +- `net.minecraft.Util#wrapThreadWithTaskName(String, Supplier)` +- `net.minecraft.advancements.critereon.EntitySubPredicates#BOAT` +- `net.minecraft.client.Options#setKey` +- `net.minecraft.client.gui.screens.inventory.EnchantmentScreen#time` +- `net.minecraft.client.multiplayer` + - `ClientCommonPacketListenerImpl#strictErrorHandling` + - `ClientLevel#isLightUpdateQueueEmpty` + - `CommonListenerCookie#strictErrorHandling` +- `net.minecraft.client.particle.ParticleRenderType#PARTICLE_SHEET_LIT` +- `net.minecraft.client.renderer` + - `GameRenderer#resetProjectionMatrix` + - `LevelRenderer` + - `playJukeboxSong` + - `clear` + - `PostChain` + - `getTempTarget`, `addTempTarget` + - `PostPass` + - `setOrthoMatrix` + - `getFilterMode` +- `net.minecraft.client.renderer.block.model.BlockModel#fromString` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture#blur`, `mipmap` + - `TextureManager#bindForSetup` +- `net.minecraft.commands.arguments.coordinates.WorldCoordinates#current` +- `net.minecraft.core` + - `Direction#fromDelta` + - `Registry#getOrCreateTag`, `getTagNames`, `resetTags` +- `net.minecraft.server.MinecraftServer` + - `isSpawningAnimals` + - `areNpcsEnabled` +- `net.minecraft.server.level` + - `GenerationChunkHolder#getGenerationRefCount` + - `ServerPlayer` + - `setPlayerInput` + - `teleportTo(ServerLevel, double, double, double, float, float, boolean)` +- `net.minecraft.tags` + - `TagManager` + - `TagManagerSerialization$TagOutput` +- `net.minecraft.world.entity` + - `AnimationState#updateTime` + - `Entity` + - `walkDist0`, `walkDist` + - `wasOnFire` + - `tryCheckInsideBlocks` + - `EntitySelector$MobCanWearArmorEntitySelector` +- `net.minecraft.world.entity.ai.sensing` + - `BreezeAttackEntitySensor#BREEZE_SENSOR_RADIUS` + - `TemptingSensor#TEMPTATION_RANGE` +- `net.minecraft.world.entity.animal` + - `Cat#getTextureId` + - `Squid#setMovementVector` + - `Wolf#isWet` +- `net.minecraft.world.entity.boss.dragon.EnderDragon` + - `getLatencyPos` + - `getHeadPartYOffset` +- `net.minecraft.world.entity.monster.Zombie#supportsBreakDoorGoal` +- `net.minecraft.world.entity.npc.Villager#setChasing`, `isChasing` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow#shotFromCrossbow` + - `ThrowableProjectile(EntityType, LivingEntity, Level)` +- `net.minecraft.world.item` + - `BannerPatternItem#getDisplayName` + - `ItemStack#LIST_STREAM_CODEC` +- `net.minecraft.world.level.BlockGetter#getMaxLightLevel` +- `net.minecraft.world.level.block.entity.JigsawBlockEntity$JointType#byName` +- `net.minecraft.world.level.block.state.BlockBehaviour#isOcclusionShapeFullBlock` +- `net.minecraft.world.level.chunk.ChunkAccess#setBlendingData` +- `net.minecraft.world.level.storage.loot.LootDataType#deserialize` +- `net.minecraft.world.phys.AABB#getBottomCenter` +- `net.minecraft.world.phys.shapes.Shapes#getFaceShape` +- `net.minecraft.world.ticks.SavedTick#saveTick` diff --git a/src/detailed-primers/1.21.4-from-1.21.2-3.md b/src/detailed-primers/1.21.4-from-1.21.2-3.md new file mode 100644 index 0000000..03c7f7f --- /dev/null +++ b/src/detailed-primers/1.21.4-from-1.21.2-3.md @@ -0,0 +1,1448 @@ +# Minecraft 1.21.2/3 -> 1.21.4 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.2/3 to 1.21.4. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +## 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](https://misode.github.io/versions/?id=1.21.4&tab=changelog). + +## Client Items + +Minecraft has moved the lookup and definition of how an item should be rendered to its own data generated system, which will be referred to as **Client Items**, located at `assets//items/.json`. Client Items is similar to the block state model definition, but has the potential to have more information enscribed in the future. Currently, it functions as simply a linker to the models used for rendering. + +All client items contain some `ItemModel$Unbaked` using the `model` field. Each unbaked model has an associated type, which defines how the item should be set up for rendering, or rendered in one specific case. These `type`s can be found within `ItemModels`. This primer will review all but one type, as that unbaked model type is specifically for bundles when selecting an item. + +The item also contains a `properties` field which holds some metadata-related parameters. Currently, it only specifies a boolean that, when false, make the hand swap the currently held item instantly rather than animate the hand coming up. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "" // Set type here + // Add additional parameters + }, + "properties": { + // When false, disables animation when swapping this item into the hand + "hand_animation_on_swap": false + } +} +``` + +### A Basic Model + +The basic model definition is handled by the `minecraft:model` type. This contains two fields: `model`, to define the relative location of the model JSON, and an optional list of `tints`, to define how to tint each index. + +`model` points to the model JSON, relative to `assets//models/.json`. In most instances, a client item defintion will look something like this: + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:model", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item" + } +} +``` + +#### Tint Sources + +In model JSONs, some element faces will have a `tintindex` field which references some index into the `tints` list in the `minecraft:model` unbaked model type. The list of tints are `ItemTintSource`s, which are all defined in `net.minecraft.client.color.item.*`. All defined tint sources can be found within `ItemTintSources`, like `minecraft:constant` for a constant color, or `minecraft:dye`, to use the color of the `DataComponents#DYED_COLOR` or default if not present. All tint sources must return an opaque color, though all sources typically apply this by calling `ARGB#opaque`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:model", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item", + // A list of tints to apply + "tints": [ + { + // For when tintindex: 0 + "type": "minecraft:constant", + // 0x00FF00 (or pure green) + "value": 65280 + }, + { + // For when tintindex: 1 + "type": "minecraft:dye", + // 0x0000FF (or pure blue) + // Only is called if `DataComponents#DYED_COLOR` is not set + "default": 255 + } + ] + } +} +``` + +To create your own `ItemTintSource`, you need to implement the `calculate` method register the `MapCodec` associated for the `type` field. `calculate` takes in the current `ItemStack`, level, and holding entity and returns an RGB integer with an opaque alpha, defining how the layer should be tinted. + +Then, the `MapCodec` needs to be registered to `ItemTintSources#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The item source class +public record FromDamage(int defaultColor) implements ItemTintSource { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + ExtraCodecs.RGB_COLOR_CODEC.fieldOf("default").forGetter(FromDamage::defaultColor) + ).apply(instance, FromDamage::new) + ); + + public FromDamage(int defaultColor) { + this.defaultColor = ARGB.opaque(defaultColor); + } + + @Override + public int calculate(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity) { + return stack.isDamaged() ? ARGB.opaque(stack.getBarColor()) : defaultColor; + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where ItemTintSources#ID_MAPPER is exposed +ItemTintSources.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "from_damage"), + // The map codec + FromDamage.MAP_CODEC +); +``` + +```json5 +// For some object in the 'tints' array +{ + "type": "examplemod:from_damage", + // 0x0000FF (or pure blue) + // Only is called if the item has not been damaged yet + "default": 255 +} +``` + +### Ranged Property Model + +Ranged property models, as defined by the `minecraft:range_dispatch` unbaked model type, are the most similar to the previous item override system. Essentially, the type defines some item property that can be scaled along with a list of thresholds and associated models. The model chosen is the one with the closest threshold value that is not over the property (e.g. if the property value is `4` and we have thresholds `3` and `5`, `3` would be chosen as it is the cloest without going over). The item property is defined via a `RangeSelectItemModelProperty`, which takes in the stack, level, entity, and some seeded value to get a float, usually scaled betwen 0 and 1 depending on the implementation. All properties can be found within `net.minecraft.client.renderer.item.properties.numeric.*` and are registered in `RangeSelectItemModelProperties`, such as `minecraft:cooldown`, for the cooldown percentage, or `minecraft:count`, for the current number of items in the stack or percentage of the max stack size when normalized. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:range_dispatch", + + // The `RangeSelectItemModelProperty` to use + "property": "minecraft:count", + // A scalar to multiply to the computed property value + // If count was 0.3 and scale was 0.2, then the threshold checked would be 0.3*0.2=0.06 + "scale": 1, + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `Count` ~~ + // When true, normalizes the count using its max stack size + "normalize": true, + + // ~~ Entries with threshold information ~~ + "entries": [ + { + // When the count is a third of its current max stack size + "threshold": 0.33, + "model": { + // Can be any unbaked model type + } + }, + { + // When the count is two thirds of its current max stack size + "threshold": 0.66, + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +To create your own `RangeSelectItemModelProperty`, you need to implement the `get` method register the `MapCodec` associated for the `type` field. `get` takes in the stack, level, entity, and seeded value and returns an arbitrary float to be interpreted by the ranged dispatch model. + +Then, the `MapCodec` needs to be registered to `RangeSelectItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The ranged property class +public record AppliedEnchantments() implements RangeSelectItemModelProperty { + + public static final MapCodec MAP_CODEC = MapCodec.unit(new AppliedEnchantments()); + + @Override + public float get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { + return (float) stack.getEnchantments().size(); + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where RangeSelectItemModelProperties#ID_MAPPER is exposed +RangeSelectItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "applied_enchantments"), + // The map codec + AppliedEnchantments.MAP_CODEC +); +``` + +```json5 +// For some client item in 'model' +{ + "type": "minecraft:range_dispatch", + + // The `RangeSelectItemModelProperty` to use + "property": "examplemod:applied_enchantments", + // A scalar to multiply to the computed property value + "scale": 0.5, + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `AppliedEnchantments` ~~ + // N/A (no arguments to constructor) + + // ~~ Entries with threshold information ~~ + "entries": [ + { + // When there is one enchantment present + // Since 1 * the scale 0.5 = 0.5 + "threshold": 0.5, + "model": { + // Can be any unbaked model type + } + }, + { + // When there are two enchantments present + "threshold": 1, + "model": { + // Can be any unbaked model type + } + } + ] +} +``` + +### Select Property Model + +Select property models, as defined by the `minecraft:select` unbaked model type, are functionally similar to ranged property models, except now it switches on some property, typically an enum. The item property is defined via a `SelectItemModelProperty`, which takes in the stack, level, entity, some seeded value, and the current display context to get one of the property values. All properties can be found within `net.minecraft.client.renderer.item.properties.select.*` and are registered in `SelectItemModelProperties`, such as `minecraft:block_state`, for the stringified value of a specified block state property, or `minecraft:display_context`, for the current `ItemDisplayContext`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:select", + + // The `SelectItemModelProperty` to use + "property": "minecraft:display_context", + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `DisplayContext` ~~ + // N/A (no arguments to constructor) + + // ~~ Switch cases based on Selectable Property ~~ + "cases": [ + { + // When the display context is `ItemDisplayContext#GUI` + "when": "gui", + "model": { + // Can be any unbaked model type + } + }, + { + // When the display context is `ItemDisplayContext#FIRST_PERSON_RIGHT_HAND` + "when": "firstperson_righthand", + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +To create your own `SelectItemModelProperty`, you need to implement the `get` method register the `SelectItemModelProperty$Type` associated for the `type` field. `get` takes in the stack, level, entity, seeded value, and display context and returns an encodable object to be interpreted by the select model. + +Then, the `MapCodec` needs to be registered to `SelectItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The select property class +public record StackRarity() implements SelectItemModelProperty { + + public static final SelectItemModelProperty.Type TYPE = SelectItemModelProperty.Type.create( + // The map codec for this property + MapCodec.unit(new StackRarity()), + // The codec for the object being selected + Rarity.CODEC + ); + + @Nullable + @Override + public Rarity get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext displayContext) { + // When null, uses the fallback model + return stack.get(DataComponents.RARITY); + } + + @Override + public SelectItemModelProperty.Type type() { + return TYPE; + } +} + +// Then, in some initialization location where SelectItemModelProperties#ID_MAPPER is exposed +SelectItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "rarity"), + // The property type + StackRarity.TYPE +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:select", + + // The `SelectItemModelProperty` to use + "property": "examplemod:rarity", + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `StackRarity` ~~ + // N/A (no arguments to constructor) + + // ~~ Switch cases based on Selectable Property ~~ + "cases": [ + { + // When rarity is `Rarity#UNCOMMON` + "when": "uncommon", + "model": { + // Can be any unbaked model type + } + }, + { + // When rarity is `Rarity#RARE` + "when": "rare", + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +### Conditional Property Model + +Conditional property models, as defined by the `minecraft:condition` unbaked model type, are functionally similar to ranged property models, except now it switches on boolean. These are usually combined with range dispatch, such as when pulling the bow. The item property is defined via a `ConditionalItemModelProperty`, which takes in the stack, level, entity, some seeded value, and the current display context to get a true of false statement. All properties can be found within `net.minecraft.client.renderer.item.properties.conditional.*` and are registered in `ConditionalItemModelProperties`, such as `minecraft:damaged`, for if the item is damaged, or `minecraft:has_component`, if it has a given data component. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:condition", + + // The `SelectItemModelProperty` to use + "property": "minecraft:damaged", + + // ~~ Properties defined by `Damaged` ~~ + // N/A (no arguments to constructor) + + // ~~ What the boolean outcome is ~~ + "on_true": { + // Can be any unbaked model type + }, + "on_false": { + // Can be any unbaked model type + } + } +} +``` + +To create your own `ConditionalItemModelProperty`, you need to implement the `get` method register the `MapCodec` associated for the `type` field. `get` takes in the stack, level, entity, seeded value, and display context and returns a boolean to be interpreted by `on_true` and `on_false`, respectively. + +Then, the `MapCodec` needs to be registered to `ConditionalItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The predicate property class +public record TimePeriod(int month, MinMaxBounds.Ints dates, boolean enabled) implements ConditionalItemModelProperty { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + Codec.intRange(1, 12).fieldOf("month").forGetter(TimePeriod::month), + MinMaxBounds.Ints.CODEC.fieldOf("dates").forGetter(TimePeriod::dates) + ).apply(instance, TimePeriod::new) + ); + + public TimePeriod(int month, MinMaxBounds.Ints dates) { + this.month = month; + this.dates = dates; + + Calendar cal = Calendar.getInstance(); + this.enabled = cal.get(Calendar.MONTH) + 1 == this.month + && this.dates.matches(cal.get(Calendar.DATE)); + } + + @Override + public boolean get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext context) { + return this.enabled; + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where ConditionalItemModelProperties#ID_MAPPER is exposed +ConditionalItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "time_period"), + // The map codec + TimePeriod.MAP_CODEC +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:condition", + + // The `SelectItemModelProperty` to use + "property": "examplemod:time_period", + + // ~~ Properties defined by `TimePeriod` ~~ + // Month of July + "month": 7, + "dates": { + // Between July 1st - 14th + "min": 1, + "max": 14 + }, + + // ~~ What the boolean outcome is ~~ + "on_true": { + // Can be any unbaked model type + }, + "on_false": { + // Can be any unbaked model type + } + } +} +``` + +### Composite Model + +Composite models, defined by `minecraft:composite`, are essentially a combination of other model types to render. Specifically, this sets up multiple players to overlay models on top of one another when rendering. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:composite", + + // Will render in the order they appear in the list + "models": [ + { + // Can be any unbaked model type + }, + { + // Can be any unbaked model type + } + ] + } +} +``` + +### Special Dynamic Models + +Special dynamic models, as defined by the `minecraft:special` unbaked model type, are the new system for block entity without level renderers (e.g., chests, banners, and the like). Instead of storing a baked model, these provide a render method to call. The special model wrapper takes in a base model used for grabbing the basic model settings (not the elements) and a `SpecialModelRenderer`. All special model renderers can be found within `net.minecraft.client.renderer.special.*` and are registered in `SpecialModelRenderers`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:special", + + // The model to read the particle texture and display transformation from + "base": "minecraft:item/template_skull", + "model": { + // The special model renderer to use + "type": "minecraft:head", + + // ~~ Properties defined by `SkullSpecialRenderer.Unbaked` ~~ + // The type of the skull block + "kind": "wither_skeleton" + } + } +} +``` + +To create your own `SpecialModelRenderer`, you need to implement both the renderer and the `$Unbaked` model to read the data from the JSON. The `$Unbaked` model creates the `SpecialModelRenderer` via `bake` and is registered using a `MapCodec` for its `type`. The `SpecialModelRenderer` then extracts the necessary data from the stack needed to render via `extractArgument` and passes that to the `render` method. If you do not need any information from the stack, you can implement `NoDataSpecialModelRenderer` instead. + +Then, the `MapCodec` needs to be registered to `SpecialModelRenderers#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +If your item is a held block, it also needs to be added to the `SpecialModelRenderers#STATIC_BLOCK_MAPPING` for specific rendering scenarios via `BlockRenderDispatcher#renderSingleBLock` (e.g. in minecart, or picked up by endermen). Both the default model renderer and the special model renderer are called in this method; allowing for both the static block model and the dynamic special model to be rendered at the same time. As this map is immutable, you will either need to replace it or hook into `SpecialBlockModelRenderer` and somehow add to the stored map there. + +```java +// The special renderer +public record SignSpecialRenderer(WoodType defaultType, Model model) implements SpecialModelRenderer { + + // Render the model + @Override + public void render(@Nullable WoodType type, ItemDisplayContext displayContext, PoseStack pose, MultiBufferSource bufferSource, int light, int overlay, boolean hasFoil) { + VertexConsumer consumer = Sheets.getSignMaterial(type).buffer(bufferSource, this.model::renderType); + this.model.renderToBuffer(pose, consumer, light, overlay); + } + + // Get the wood type from the stack + @Nullable + @Override + public WoodType extractArgument(ItemStack stack) { + return (stack.getItem() instanceof BlockItem item && item.getBlock() instanceof SignBlock sign) + ? sign.type() : this.defaultType; + } + + // The model to read the json from + public static record Unbaked(WoodType defaultType) implements SpecialModelRenderer.Unbaked { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + WoodType.CODEC.fieldOf("default").forGetter(SignSpecialRenderer.Unbaked::defaultType) + ).apply(instance, SignSpecialRenderer.Unbaked::new) + ); + + // Create the special model renderer, or null if it fails + @Nullable + @Override + public SpecialModelRenderer bake(EntityModelSet modelSet) { + return new SignSpecialRenderer( + this.defaultType, + SignRenderer.createSignModel(modelSet, defaultType, true) + ) + } + + @Overrides + public MapCodec type() { + return MAP_CODEC; + } + } +} + +// Then, in some initialization location where SpecialModelRenderers#ID_MAPPER is exposed +SpecialModelRenderers.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "sign"), + // The map codec + SignSpecialRenderer.Unbaked.MAP_CODEC +); +// Let assume we can add directly to SpecialModelRenderers#STATIC_BLOCK_MAPPING as well +// We'll have a Block EXAMPLE_SIGN +SpecialModelRenderers.STATIC_BLOCK_MAPPING.put( + // The block with a special rendering as an item + EXAMPLE_SIGN, + // The unbaked renderer to use + new SignSpecialRenderer.Unbaked(WoodType.BAMBOO) +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:special", + + // The model to read the particle texture and display transformation from + "base": "minecraft:item/bamboo_sign", + "model": { + // The special model renderer to use + "type": "examplemod:sign", + + // ~~ Properties defined by `SignSpecialRenderer.Unbaked` ~~ + // The default wood type if none can be found + "default": "bamboo" + } + } +} +``` + +### Rendering an Item + +Rendering an item is now done through the `ItemModelResolver` and `ItemStackRenderState`. This is similar to how the `EntityRenderState` works: first, the `ItemModelResolver` sets up the `ItemStackRenderState`, then the state is rendered via `ItemStackRenderState#render`. + +Let's start with the `ItemStackRenderState`. For rendering, the only one we care about the following methods: `isEmpty`, `isGui3d`, `usesBlockLight`, `transform`, and `render`. `isEmpty` is used to determine whether the stack should render at all. Then `isGui3d`, `usesBlockLight`, and `transform` are used in their associated contexts to properly position the stack to render. Finally, `render` takes in the pose stack, buffer source, packed light, and overlay texture to render the item in its appropriate location. + +`ItemModelResolver` is responsible for setting the information on the `ItemStackRenderState` needed to render. This is done through `updateForLiving` for items held by living entities, `updateForNonLiving` for items held by other kinds of entities, and `updateforTopItem`, for all other scenarios. `updateForItem`, which the previous two methods delegate to, take in the render state, the stack, the display context, if the stack is in the left hand, the level, the entity, and some seeded value. This will effectively clear the previous state via `ItemStackRenderState#clear` and then set up the new state via a delegate to `ItemModel#update`. The `ItemModelResolver` can always be obtained via `Minecraft#getItemModelResolver`, if you are not within a renderer context (e.g., block entity, entity). + +```java +// In its most simple form, assuming you are not doing any transformations (which you should as necessary) +public class ExampleRenderer { + private final ItemStackRenderState state = new ItemStackRenderState(); + + public void render(ItemStack stack, Level level, PoseStack pose, MultiBufferSource bufferSource) { + // First update the render state + Minecraft.getInstance().getItemModelResolver().updateForTopItem( + // The render state + this.state, + // The stack to update the state with + stack, + // The display context to render within + ItemDisplayContext.NONE, + // Whether it is in the left hand of the entity (use false when unknown) + false, + // The current level (can be null) + level, + // The holding entity (can be null) + null, + // An arbitrary seed value + 0 + ); + + // Perform any desired transformations here + + // Then render the state + this.state.render( + // The pose stack with the required transformations + pose, + // The buffer sources + bufferSource, + // The packed light value + LightTexture.FULL_BRIGHT, + // The overlay texture value + OverlayTexture.NO_OVERLAY + ); + } +} +``` + +### Custom Item Model Defintions + +To make a custom item model definition, we need to look at a few more methods in `ItemStackRenderState` which, although you won't typically use, is useful to understand: `ensureCapacity` and `newLayer`. Both of these are responsible for ensuring there are enough `ItemStackRenderState$LayerRenderState`s if you happen to be overlaying multiple models at once. Effectively, every time you are planning to render something in an unbaked model, `newLayer` should be called. If you plan on rendering multiple things on top of one another, then `ensureCapacity` should be set with the number of layers that you plan to render before calling `newLayer`. + +An item model definition is made up of the `ItemModel`, which functionally defines a 'baked model' and its `ItemModel$Unbaked`, used for serialization. + +The unbaked variant has two methods: `bake`, which is used to create the `ItemModel`, and `type`, which references the `MapCodec` to be registered to `ItemModels#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. `bake` takes in the `$BakingContext`, which contains the `ModelBaker` to get `BakedModel`s, the `EntityModelSet` for entity models, and the missing `ItemModel`. + +The baked variant only has one method `update`, which is responsible for setting up everything necessary on the `ItemStackRenderState`. The model does no rendering itself. + +```java +public record RenderTypeModelWrapper(BakedModel model, RenderType type) implements ItemModel { + + // Update the render state + @Override + public void update(ItemStackRenderState state, ItemStack stack, ItemModelResolver resolver, ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { + ItemStackRenderState.LayerRenderState layerState = state.newLayer(); + if (stack.hasFoil()) { + layerState.setFoilType(ItemStackRenderState.FoilType.STANDARD); + } + layerState.setupBlockModel(this.model, this.type); + } + + public static record Unbaked(ResourceLocation model, RenderType type) implements ItemModel.Unbaked { + // Create a render type map for the codec + private static final BiMap RENDER_TYPES = Util.make(HashBiMap.create(), map -> { + map.put("translucent_item", Sheets.translucentItemSheet()); + map.put("cutout_block", Sheets.cutoutBlockSheet()); + }); + private static final Codec RENDER_TYPE_CODEC = ExtraCodecs.idResolverCodec(Codec.STRING, RENDER_TYPES::get, RENDER_TYPES.inverse()::get); + + // The map codec to register + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + ResourceLocation.CODEC.fieldOf("model").forGetter(RenderTypeModelWrapper.Unbaked::model), + RENDER_TYPE_CODEC.fieldOf("render_type").forGetter(RenderTypeModelWrapper.Unbaked::type) + ) + .apply(instance, RenderTypeModelWrapper.Unbaked::new) + ); + + @Override + public void resolveDependencies(ResolvableModel.Resolver resolver) { + // Resolve model dependencies, so pass in all known resource locations + resolver.resolve(this.model); + } + + @Override + public ItemModel bake(ItemModel.BakingContext context) { + // Get the baked model and return + BakedModel baked = context.bake(this.model); + return new RenderTypeModelWrapper(baked, this.type); + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } + } +} + +// Then, in some initialization location where ItemModels#ID_MAPPER is exposed +ItemModels.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "render_type"), + // The map codec + RenderTypeModelWrapper.Unbaked.MAP_CODEC +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "examplemod:render_type", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item", + // Set the render type to use when rendering + "render_type": "cutout_block" + } +} +``` + +- `net.minecraft.client` + - `ClientBootstrap` - Registers the maps backing the client; currently used for item model definitions. + - `Minecraft` + - `getEquipmentModels` is removed, only directly accessible in the `EntityRendererProvider$Context#getEquipmentAssets` + - `getItemModelResolver` - Returns the updater for resolving the current model to be rendered in the `ItemStackRenderState$LayerRenderState`. + - `KeyMapping#get` - Gets a key mapping based on its translation key. +- `net.minecraft.client.color.item` + - `Constant` - A constant to tint the item texture. + - `CustomModelDataSource` - Gets the color to tint based on an index in the `DataComponent#CUSTOM_MODEL_DATA` data component. If no index is found or is out of bounds, then the default color is used. + - `Dye` - Gets the color to tint using the `DataComponent#DYED_COLOR` data component. + - `Firework` - Gets the color to tint using the `DataComponent#FIRE_EXPLOSION` data component. + - `GrassColorSource` - Gets the color to tint based on the provided temperature and downfall values. + - `ItemColor` -> `ItemTintSource`, not one-to-one as indexing is setup by providing multiple `ItemTintSource`s in the model list. + - `ItemColors` class is removed, now data generated as `ItemTintSource`s + - `ItemTintSources` - A registry of sources for tinting an item texture in a model. + - `MapColor` - Gets the color to tint using the `DataComponent#MAP_COLOR` data component. + - `Potion` - Gets the color to tint using the `DataComponent#POTION_CONTENTS` data component. + - `TeamColor` - Gets the color based on the holding entity's team color. +- `net.minecraft.client.data.Main` - The entrypoint for client data generation. +- `net.minecraft.client.particle.BreakingItemParticle` now takes in an `ItemStackRenderState` instead of an `ItemStack` + - `$ItemParticleProvider` - An abstract particle provide that provides a simple method to calculate the `ItemStackRenderState`. +- `net.minecraft.client.renderer` + - `BlockEntityWithoutLevelRenderer` class is removed, replaced by the `NoDataSpecialModelRenderer` datagen system + - `ItemInHandRenderer` now takes in an `ItemModelResolver` + - `ItemModelShaper` is removed, as the methods are available within the `ModelManager` + - `Sheets` + - `getBedMaterial` - Gets the bed material from the dye color. + - `colorToResourceMaterial` - Gets the resource location of the dye color. + - `createBedMaterial` - Creates the bed material from the dye color or resource location. + - `getShulkerBoxMaterial` - Gets the shulker box material from the dye color. + - `colorToShulkerMaterial` - Gets the resource location of the dye color for the shulker box. + - `createShulkerMaterial` - Creates the shulker box material from the dye color or resource location. + - `chestMaterial` - Creates a new material for a chest with the given resource location. + - `SpecialBlockModelRenderer` - A map of blocks to special renderers for item variants. +- `net.minecraft.client.renderer.block.BlockRenderDispatcher` now takes in a supplied `SpecialBlockModelRenderer` instead of a `BlockEntityWithoutLevelRenderer` +- `net.minecraft.client.renderer.block.model` + - `BakedOverrides` class is removed, replaced by the `RangeSelectItemModelProperty` datagen system + - `BlockModel` now takes in a `TextureSlots$Data` instead of just a material map, and no longer takes in a list of `ItemOverride`s + - `MISSING_MATERIAL` is removed, replaced by `minecraft:missingno` + - `textureMap` -> `textureSlots`, now private, not one-to-one + - `parent` is now private, not one-to-one + - `parentLocation` is now private + - `hasAmbientOcclusion` -> `getAmbientOcclusion` + - `isResolved` is removed + - `getOverrides` is removed + - `getParent` - Returns the unbaked parent model. + - `getTextureSlots` - Returns the texture data for the model. + - `getElements` is now package-private + - `$GuiLight` -> `UnbakedModel$GuiLight` + - `FaceBakery` + - `bakeQuad` is now static + - `calculateFacing` is now private + - `ItemModelGenerator` now implements `UnbakedModel` + - `ItemOverride` class is removed, replaced by the `RangeSelectItemModelProperty` datagen system + - `ItemTransforms` is now a record + - `hasTransform` is removed + - `TextureSlots` - A class which handles the texture mapping within a model. The data is read from `$Data` and stored as `$SlotContents` until it is resolved during the baking process into `Material`s. + - `UnbakedBlockStateModel` now extends `ResolvableModel` instead of `UnbakedModel` + - `bake` - Bakes the block state into its selectable models. + - `Variant` is now a record +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the banner. + - `BedRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the bed. + - `BlockEntityRenderDispatcher(Font, EntityModelSet, Supplier, Supplier, Supplier)` -> `BlockEntityRenderDispatcher(Font, Supplier, BlockRenderDispatcher, ItemModelResolver, ItemRenderer, EntityRenderDispatcher)` + - `renderItem` is removed, implemented in their specific classes + - `BlockEntityRendererProvider` now takes in an `ItemModelResolver` + - `getItemModelResolver` - Gets the resolver which returns the item models. + - `ChestRenderer#xmasTextures` - Returns whether christmas textures should render on a chest. + - `DecoratedPotRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the pot. + - `ShulkerBoxRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `render` - Renders the shulker box. + - `$ShulkerBoxModel#animate` no longer takes in the `ShulkerBoxBlockEntity` + - `SkullblockRenderer#createSkullRenderers` -> `createModel`, not one-to-one +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher` now takes in an `IteModelResolver`, a supplied `EntityModelSet` instead of the instance, and an `EquipmentAssetManager` instead of a `EquipmentModelSet` + - `EntityRendererProvider$Context` now takes in an `ItemModelResolver` instead of an `ItemRenderer`, and an `EquipmentAssetManager` instead of a `EquipmentModelSet` + - `getItemRenderer` -> `getItemModelResolver`, not one-to-one + - `getEquipmentModels` -> `getEquipmentAssets` + - `FishingHookRenderer` - Returns the holding arm of the fishing hook. + - `HumanoidMobRenderer` + - `getArmPose` - Returns the arm pose of the entity. + - `extractHumanoidRenderState` now takes in an `ItemModelResolver` + - `ItemEntityRenderer` + - `getSeedForItemStack` is removed + - `renderMultipleFromCount` now takes in the `ItemClusterRenderState`, and removes the `ItemRenderer`, `ItemStack`, `BakedModel`, and 3d boolean + - `ItemRenderer` no longer implements `ResourceManagerReloadListener` + - The constructor now only takes in the `ItemModelResolver` + - `render` -> `renderItem`, not one-to-one + - `renderBundleItem` is removed + - `getModel`, `resolveItemModel` is removed + - `LivingEntityRenderer#itemRenderer` -> `itemModelResolver`, not one-to-one + - `OminousItemSpawnerRenderer` now uses the `ItemClusterRenderState` + - `SkeletonRenderer#getArmPose` -> `AbstractSkeletonRenderer#getArmPose` + - `SnowGolemRenderer` now uses the `SnowGolemRenderState` +- `net.minecraft.client.renderer.entity.layers` + - `CrossArmsItemLayer` now uses the `HoldingEntityRenderState` + - `CustomHeadLayer` no longer takes in the `ItemRenderer` + - `DolphinCarryingItemLayer` no longer takes in the `ItemRenderer` + - `EquipmentLayerRenderer$TrimSpriteKey` now takes in a `ResourceKey` + - `textureId` - Gets the texture id for the trim. + - `FoxHeldItemLayer` no longer takes in the `ItemRenderer` + - `ItemInHandLayer` now uses the `ArmedEntityRenderState` + - The constructor no longer takes in the `ItemRenderer` + - `renderArmWithItem` no longer takes in the `BakedModel`, `ItemStack`, or `ItemDisplayContext` and instead the `ItemStackRenderState` + - `LivingEntityEmissiveLayer` now takes in a boolean which determines whether the layer is always visible + - `PandaHoldsItemLayer` no longer takes in the `ItemRenderer` + - `PlayerItemInHandLayer` no longer takes in the `ItemRenderer` + - `renderArmWithItem` no longer takes in the `BakedModel`, `ItemStack`, or `ItemDisplayContext` and instead the `ItemStackRenderState` + - `SnowGolemHeadLayer` now uses the `SnowGolemRenderState` + - `WitchItemLayer` no longer takes in the `ItemRenderer` +- `net.minecraft.client.renderer.entity.player.PlayerRenderer#getArmPose` is now private +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` - A render state for an entity that holds items in their right and left hands. + - `HoldingEntityRenderState` - A render state for an entity that holds a single item. + - `ItemClusterRenderState` - A render state for an item that should be rendered multiple times. + - `ItemDisplayEntityRenderState#itemRenderState`, `itemModel` -> `item`, not one-to-one + - `ItemEntityRenderState#itemModel`, `item` -> `ItemClusterRenderState#item`, not one-to-one + - `ItemFrameRenderState#itemStack`, `itemModel` -> `item`, not one-to-one + - `LivingEntityRenderState` + - `headItemModel`, `headItem` -> `headItem`, not one-to-one + - Arm and Hand methods moved to `ArmedEntityRenderState` + - `OminousItemSpawnerRenderState` -> `ItemClusterRenderState` + - `PlayerRenderState` + - `mainHandState`, `offHandState` -> `ArmedEntityRenderState` methods + - `heldOnHead` - Represents the item stack on the head of the player. + - `SkeletonRenderState#isHoldingBow` - Represents if the skeleton is holding a bow. + - `SnowGolemRenderState` - The render state for the snow golem. + - `ThrownItemRenderState#item`, `itemModel` -> `item`, not one-to-one + - `WitchRenderState#isHoldingPotion` - Whether the witch is holding a potion or not. +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` - The basic model definition that contains the model and its associated tints. + - `BundleSelectedItemSpecialRenderer`- A special renderer for a stack selected by a bundle. + - `ClampedItemPropertyFunction`, `ItemPropertyFunction` -> `.properties.numeric.*` classes depending on the situation and property + - `ClientItem` - The base item that represents the model definition in `assets//items`. + - `CompositeModel` - Overlays multiple models together. + - `ConditionalItemModel` - A model that shows a different model based on a boolean. + - `EmptyModel` - A model that renders nothing. + - `ItemModel` - The base item model that updates the stack render state as necessary. + - `ItemModelResolver` - The resolver that updates the stack render state. + - `ItemModels` - Contains all potential item models for a `ClientItem`. + - `ItemProperties` class is removed + - `ItemStackRenderState` - The render state representing the stack to render. + - `MissingItemModel` - A model that represents the missing model. + - `RangeSelectItemModel` - A model that contains some range of values that applies the associated model that meets the threshold. + - `SelectItemModel` - An item model that switches based on the provided property. + - `SpecialModelWrapper` - An item model for models that are rendered dynamically, such as chests. +- `net.minecraft.client.renderer.item.properties.conditional` + - `Broken` - If the item only has one durability left. + - `BundleHasSelectedItem` - If the bundle is holding the selected item. + - `ConditionalItemModelProperties` - Contains all potential conditional property types. + - `ConditionalItemModelProperty` - Represents a property that returns some boolean. + - `CustomModelDataProperty` - If the current index is set to true within `DataComponents#CUSTOM_MODEL_DATA`. + - `Damaged` - If the item is damaged. + - `ExtendedView` - If the display context is a gui and the shift key is down. + - `FishingRodCast` - If the fishing rod is being used. + - `HasComponent` - Whether it has the associated data component. + - `IsCarried` - If the item is being carried in the current menu. + - `IsKeybindDown` - If the key mapping is being pressed. + - `IsSelected` - If the item is selected in the hotbar. + - `IsUsingItem` - If the item is being used. + - `IsViewEntity` - Whether the holding entity is the current camera entity. +- `net.minecraft.client.renderer.item.properties.numeric` + - `BundleFullness` - A threshold based on the bundle contents. + - `CompassAngle` - A threshold on the currrent angle state. + - `CompassAngleState` - A threshold based on the current compass angle towards its target. + - `Cooldown` - A threshold based on the current cooldown percentage. + - `Count` - A threshold based on the stack count. + - `CrossbowPull` - A threshold based on the crossbow being pulled. + - `CustomModelDataProperty` - If the current index has set theshold value within `DataComponents#CUSTOM_MODEL_DATA`. + - `Damage` - A threshold based on the durability percentage remaining. + - `NeedleDirectionHelper` - An abstract class which help point the position needle in the correct direction. + - `RangeSelectItemModelProperties` - Contains all potential ranged property types. + - `RangeSelectItemModelProperty` - Represents a property that returns some threshold of a float. + - `Time` - A threshold based on the current time of day. + - `UseCycle` - A threshold based on the remaining time left normalized to some period modulo in the stack being used. + - `UseDuration` - A threshold based on the remaining time left in the stack being used. +- `net.minecraft.client.renderer.item.properties.select` + - `Charge` - A case based on the charge type of a crowssbow. + - `ContextDimension` - A case based on the dimension the item is currently within. + - `ContextEntityType` - A case based on the holding entity's type. + - `CustomModelDataProperty` - If the current index is set to the string within `DataComponents#CUSTOM_MODEL_DATA`. + - `DisplayContext` - A case based on the display context. + - `ItemBlockState` - A case based on getting a property value from an item holding the block state properties. + - `LocalTime` - A case based on a simple date format pattern. + - `MainHand` - A case based on the arm holding the item. + - `SelectItemModelProperties` - Contains all potential select-cased property types. + - `SelectItemModelProperty` - Represents a property that returns some cased selection. + - `TrimMaterialProperty` - A case based on the trim material on the item. +- `net.minecraft.client.renderer.special` + - `BannerSpecialRenderer` - An item renderer for a banner. + - `BedSpecialRenderer` - An item renderer for a bed. + - `ChestSpecialRenderer` - An item renderer for a chest. + - `ConduitSpecialRenderer` - An item renderer for a conduit. + - `DecoratedPotSpecialRenderer` - An item renderer for a decorated pot. + - `HangingSignSpecialRenderer` - An item renderer for a hanging sign. + - `NoDataSpecialModelRenderer` - An item renderer that does not need to read any data from the stack. + - `ShieldSpecialRenderer` - An item renderer for a shield. + - `ShulkerBoxSpecialRenderer` - An item renderer for a shulker box. + - `SkullSpecialRenderer` - An item renderer for a skull. + - `SpecialModelRenderer` - Represents a model that reads data from the stack and renders the object without needing the render state. + - `SpecialModelRenderers` - Contains all potential special renderers. + - `StandingSignSpecialRenderer` - An item renderer for a standing sign. + - `TridentSpecialRenderer` - An item renderer for a trident. +- `net.minecraft.client.resources.model` + - `BakedModel` + - `isCustomRenderer` is removed, replaced by the special renderer system + - `overrides` is removed, replaced by the properties renderer system + - `BlockStateModelLoader` no longer takes in the missing model + - `definitionLocationToBlockMapper` is now private + - `loadBlockStateDefinitionStack` is now private + - `loadBlockStates` - Gets the loaded models for the block state. + - `$LoadedBlockModelDefinition` is now package-private + - `$LoadedModel` now takes in an `UnbakedBlockStateModel` instead of a `UnbakedModel` + - `$LoadedModels` + - `forResolving` - Returns all models hat need to be resolved. + - `plainModels` - Returns a map from the model location to the unbaked model. + - `BuiltInModel` class is removed + - `ClientItemInfoLoader` - Loads all models for all item stacks. + - `EquipmentModelSet` -> `EquipmentAssetManager` + - `ItemModel` -> `net.minecraft.client.renderer.item.ItemModel` + - `MissingBlockModel#MISSING` is now private + - `ModelBaker` + - `sprites` - Returns the getter to get sprites. + - `rootName` - Gets the name of the model for debugging. + - `ModelBakery(Map, Map, UnbakedModel)` -> `ModelBakery(EntityModelSet, Map, Map, Map, UnbakedModel)` + - `bakeModels` now returns a `$BakingResult` + - `getBakedTopLevelModels` is removed + - `$BakingResult` - Holds all models that have been lodaded. + - `$TextureGetter` + - `get` now takes in the `ModelDebugName` instead of the `ModelResourceLocation` + - `reportingMissingReference` - Handles how a texture is reported when not set. + - `bind` - Creates a spriate getter bound to the current model. + - `ModelDebugName` - Returns the name of the model for debugging. + - `ModelDiscovery` + - `registerStandardModels` is removed + - `registerSpecialModels` - Adds the internal models loaded by the system. + - `addRoot` - Adds a new model that can be resolved. + - `getUnreferencedModels` - Returns the difference between the models loaded vs the models used. + - `getTopModels` is removed + - `ModelGroupCollector$GroupKey#create` now takes in an `UnbakedBlockStateModel` instead of a `UnbakedModel` + - `ModelManager` + - `specialBlockModelRenderer` - Returns the renderer for special block models. + - `entityModels` - Returns the model set for the entities. + - `getItemProeprties` - Returns the properties for the client item based on its resource location. + - `ModelResourceLocation#inventory` is removed + - `ResolvableModel` - The base model, usually unbaked, that have references to resolve. + - `SimpleBakedModel` fields are now all private + - `bakeElements` - Bakes a model given the block elements. + - `$Builder` no longer has an overload that takes in the `BlockModel` + - `SpecialModels` class is removed + - `SpriteGetter` - A getter for atlas sprites for the associated materials. + - `UnbakedModel` is now a `ResolvableModel` + - `bake(ModelBaker, Function, ModelState)` -> `bake(TextureSlots, ModelBaker, ModelState, boolean, boolean, ItemTransforms)` + - `getAmbientOcclusion`, `getTopAmbientOcclusion` - Returns whether ambient occlusion should be enabled on the item. + - `getGuiLight`, `getTopGuiLight` - Returns the lighting side within a gui. + - `getTransforms`, `getTopTransform`, `getTopTransforms` - Returns the transformations to apply based on the display context. + - `getTextureSlots`, `getTopTextureSlots` - Returns the texture data for the model. + - `getParent` - Returns the parent of this model. + - `bakeWithTopModelValues` - Bakes the model. +- `net.minecraft.data.models.*` -> `net.minecraft.client.data.models.*` +- `net.minecraft.world.item` + - `BundleItem` no longer takes in any `ResourceLocation`s + - `openFrontModel`, `openBackModel` is removed + - `CrossbowItem$ChargeType` - The item being charged by the crossbow. + - `DyeColor#getMixedColor` - Returns the dye most closely representing the mixed color. + - `Item$Properties#overrideModel` is removed + - `SpawnEggItem` no longer takes in its tint colors + - `getColor` is removed +- `net.minecraft.world.item.alchemy.PotionContents` + - `getColor(*)` is removed + - `getColorOr` - Gets a custom color fro the potion or the default if not present. +- `net.minecraft.world.item.component.CustomModelData` now takes in a list of floats, flags, strings, and colors to use in the custom model properties based on the provided index +- `net.minecraft.world.item.equipment` + - `ArmorMaterial` now takes in a `ResourceKey` instead of just the model id + - `EquipmentAsset` - A marker to represent the equipment client info key + - `EquipmentAssets` - All vanilla equipment assets. + - `EquipmentModel` -> `net.minecraft.client.resources.model.EquipmentClientInfo` + - `EquipmentModels` -> `net.minecraft.client.data.models.EquipmentAssetProvider`, not one-to-one + - `Equippable` now takes in a `ResourceKey` instead of just the model id + - `$Builder#setModel` -> `setAsset` +- `net.minecraft.world.item.equipment.trim` + - `ArmorTrim#getTexture` is removed + - `TrimMaterial` no longer takes in an item model index, and the key over the override armor materials points to `ResourceKey` +- `net.minecraft.world.level.FoliageColor` + - `getEvergreenColor` -> `FOLIAGE_EVERGREEN` + - `getBirchColor` -> `FOLIAGE_BIRCH` + - `getDefaultColor` -> `FOLIAGE_DEFAULT` + - `getMangroveColor` -> `FOLIAGE_MANGROVE` +- `net.minecraft.world.level.block.RenderShape#ENTITYBLOCK_ANIMATED` is removed +- `net.minecraft.world.level.block.entity` + - `BannerBlockEntity#fromItem` is removed + - `BedBlockEntitty#setColor` is removed + - `BlockEntity#saveToItem` is removed + - `DecoratedPotBlockEntity#setFromItem`, `getPotAsItem` is removed +- `net.minecraft.world.level.storage.loot.functions.SetCustomModelDataFunction` now takes in a list of floats, flags, strings, and colors to use in the custom model properties based on the provided index + +## Mob Replacing Current Items + +One of the last hardcoded instances relating to tools and armor being subtypes of `DiggerItem` and `ArmorItem`, respectively, have been reworked: `Mob#canReplaceCurrentItem`. Now, it reads the `EquipmentSlot` of the stack from the `DataComponents#EQUIPPABLE` data component. Then, using that, different logic occurs depending on the situation. + +For armor slots, it cannot be changed if the armor is enchanted with a `EnchantmentEffectComponents#PREVENT_ARMOR_CHANGE` effect component. Otherwise, it will attempt to compare the armor attributes first, then armor toughness if equal. + +For weapons (via hand slots), it will first check if the mob has a preferred weapon type tag. If so, it will switch the item to the weapon in the tag, provided one item is in the tag and the other is not. Otherwise, it will attempt to compare attack damage attributes. + +If all attributes are equal, then they will both default to the following logic. First, it will try to pick the item with the most enchantments. Then, it will attempt to pick the item with the most durability remaining (the raw value, not the percentage). Finally, it will check whether one of the items hsa a custom name via the `DataComponents#CUSTOM_NAME`. + +> As a small caveat, `BambooSaplingBlock` and `BambooStalkBLock` still hardcode a check for check if the mainhand item is a `SwordItem`, though this could probably be replaced with a change to `ToolMaterial#applySwordProperties` in the future. + +## Particles, rendered through Render Types + +Particles are now rendered using a `RenderType`, rather than setting a buffer builder themselves. The only special cases are `ParticleRenderType#CUSTOM`, which allows the modder to implement their own rendering via `Particle#renderCustom`; and `ParticleRenderType#NO_RENDER`, which renders nothing. + +To create a new `ParticleRenderType`, it can be created by passing in its name for logging and the `RenderType` to use. Then, the type is returned in `Particle#getRenderType`. + +```java +public static final ParticleRenderType TERRAIN_SHEET_OPAQUE = new ParticleRenderType( + "TERRAIN_SHEET_OPAQUE", // Typically something recognizable, like the name of the field + RenderType.opaqueParticle(TextureAtlas.LOCATION_BLOCKS) // The Render Type to use +); +``` + +- `net.minecraft.client.particle` + - `CherryParticle` -> `FallingLeavesParticle`, not one-to-one as the new class has greater configuration for its generalization + - `ItemPickupParticle` no longer takes in the `RenderBuffers` + - `Particle#renderCustom` - Renders particles with the `ParticleRenderType#CUSTOM` render type. + - `ParticleEngine#render(LightTexture, Camera, float)` -> `render(Camera, float, MutliBufferSource$BufferSource)` + - `ParticleRenderType` is now a record which takes in the name and the `RenderType` it uses. + +## 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. + +### `SimpleJsonResourceReloadListener` + +`SimpleJsonResourceReloadListener`s now take in a converter to map some key to a resource location. An abstract has been provided for registry keys. This is done through a `FileToIdConverter`, which essentially holds a prefix and extension to apply to some `ResourceLocation`. + +```java +// We will assume this is a server reload listener (meaning in the 'data' folder) +public class MyLoader extends SimpleJsonResourceReloadListener { + + public MyLoader() { + super( + // The codec to encode/decode the object + ExampleObject.CODEC, + // The file converter + // Will place files in data//example/object/.json + FileToIdConverter.json( + // The prefix + "example/object" + ) + ); + } + + // Below is the same +} +``` + +- `net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener` now takes in a resource key for a registry, or a file to id converter instead of just a string + - `scanDirectory` now takes in a resource key for a registry, or a file to id converter instead of just a string + +### MetadataSectionSerializer, replaced by Codecs + +`MetadataSectionSerializer` has been removed in favor of using `Codec`s to serialize the metadata sections. As such all `MetadataSectionSerializer`s have been replaced by its `MetadataSectionType` instead, which holds the name of the section and the codec for the metadata section. + +- `net.minecraft.client.renderer.texture` + - `HttpTexture` -> `SkinTextureDownloader`, not one-to-one as the new class is just a utility that returns the content to store + - `MissingTextureAtlasSprite` + - `getTexture` -> `generateMissingImage`, not one-to-one + - `getMissingImage(int, int)` is now public + - `SpriteLoader#loadAndStitch` now takes in a collection of `MetadataSectionType`s rather than `MetadataSectionSerializer`s +- `net.minecraft.client.resources.SkinManager` no longer takes in the `TextureManager` + - `getOrLoad` now returns an `Optional` future instead of just the `PlayerSkin` +- `net.minecraft.client.resources.metadata.animation` + - `AnimationFrame` is now a record + - `AnimationMetadataSection` is now a record + - `AnimationMetadataSectionSerializer` class is removed + - `VillagerMetaDataSection` -> `VillagerMetadataSection` + - `VillagerMetadataSectionSerializer` class is removed +- `net.minecraft.client.resources.metadata.texture` + - `TextureMetadataSection` is now a record + - `TextureMetadataSectionSerializer` class is removed +- `net.minecraft.server.packs.PackResources#getMetadataSection` now takes in a `MetadataSectionType` instead of a `MetadataSectionSerializer` +- `net.minecraft.server.packs.metadata` + - `MetadataSectionSerializer` is removed in favor of section codecs + - `MetadataSectionType` is a now a record instead of a `MetadataSectionSerializer` extension +- `net.minecraft.server.packs.resources.ResourceMetadata` + - `getSection` now takes in a `MetadataSectionType` instead of a `MetadataSectionSerializer` + - `copySections` now takes in a collection of `MetadataSectionType`s instead of a `MetadataSectionSerializer`s + +### Music, now with Volume Controls + +The background music is now handled through a `MusicInfo` class, which also stores the volume along with the associated `Music`. + +- `net.minecraft.client.Minecraft#getSituationalMusic` now returns a `MusicInfo` instead of a `Music` +- `net.minecraft.client.sounds` + - `MusicInfo` - A record that holds the currently playing `Music` and the volume its at. + - `MusicManager#startPlaying` now takes in a `MusicInfo` instead of a `Music` + - `SoundEngine#setVolume`, `SoundManager#setVolume` - Sets the volume of the associated sound instance. +- `net.minecraft.world.level.biome` + - `Biome` + - `getBackgroundMusic` now returns a optional `SimpleWeightedRandomList` of music. + - `getBackgroundMusicVolume` - Gets the volume of the background music. + - `BiomeSpecialEffects$Builder#silenceAllBackgroundMusic`, `backgroundMusic(SimpleWeightedRandomList)` - Handles setting the background music for the biome. + +### Tag Changes + +- `minecraft:block` + - `tall_flowers` -> `bee_attractive` +- `minecraft:item` + - `tall_flowers`, `flowers` is removed + - `trim_templates` is removed + - `skeleton_preferred_weapons` + - `drowned_preferred_weapons` + - `piglin_preferred_weapons` + - `pillager_preferred_weapons` + - `wither_skeleton_disliked_weapons` + +### List of Additions + +- `com.mojang.blaze3d.platform.Window#isMinimized` - Returns whether the application window is minimized. +- `com.mojang.blaze3d.vertex.VertexBuffer` + - `uploadStatic` - Immediately uploads the provided vertex data via the `Consumer` using the `Tesselator` with a `STATIC_WRITE` `VertexBuffer`. + - `drawWithRenderType` - Draws the current buffer to the screen with the given `RenderType`. +- `com.mojang.math.MatrixUtil#isIdentity` - Checks whether the current `Matrix4f` is an identity matrix. +- `net.minecraft` + - `SuppressForbidden` - An annotation that holds some reason, usually related to needing the sysout stream. + - `Util#maxAllowedExecutorThreads` - Returns the number of available processors clamped between one and the maximum number of threads. +- `net.minecraft.client.gui.components.events.GuiEventListener#getBorderForArrowNavigation` - Returns the `ScreenRectangle` bound to the current direction. +- `net.minecraft.client.gui.navigation.ScreenRectangle#transformAxisAligned` - Creates a new `ScreenRectangle` by transforming the position using the provided `Matrix4f`. +- `net.minecraft.client.gui.narration.NarratableEntry#getNarratables` - Returns the list of narratable objects within the current object. +- `net.minecraft.client.gui.screens.recipebook.RecipeCollection#EMPTY` - An empty collection of recipes. +- `net.minecraft.client.gui.screens.worldselection` + - `ExperimentsScreen$ScrollArea` - Represents a narratable scroll area of the currently available experiments. + - `SwitchGrid#layout` - Returns the layout of the grid to visit. +- `net.minecraft.client.model` + - `BannerFlagModel`, `BannerModel` - Models for the banner and hanging banner. + - `VillagerLikeModel#translateToArms` - Translates the pose stack such that the current relative position is at the entity's arms. +- `net.minecraft.client.model.geom.EntityModelSet#vanilla` - Creates a new model set with all vanilla models. +- `net.minecraft.client.multiplayer.PlayerInfo#setShowHat`, `showHat` - Handles showing the hat layer of the player in the tab overlay. +- `net.minecraft.client.renderer.blockentity` + - `AbstractSignRenderer` - How a sign should render as a block entity. + - `HangingSignRenderer` + - `createSignModel` - Creates a sign model given the wood and the attachment location. + - `renderInHand` - Renders the model in the entity's hand. + - `$AttachmentType` - An enum which represents where the model is attached to, given its properies. + - `$ModelKey` - A key for the model that combines the `WoodType` with its `$AttachmentType`. + - `SignRenderer` + - `renderInHand` - Renders the model in the entity's hand. +- `net.minecraft.client.renderer.entity.EntityRenderer#getShadowStrength` - Returns the raw opacity of the display's shadow. +- `net.minecraft.client.renderer.entity.layers.CrossedArmsItemLayer#applyTranslation` - Applies the translation to render the item in the model's arms. +- `net.minecraft.client.renderer.texture` + - `ReloadableTexture` - A texture that can be reloaded from its associated contents. + - `TextureContents` - Holds the image and metadata associated with a given texture. + - `TextureManager` + - `registerAndLoad` - Registers a reloadable texture with the given name. + - `registerForNextReload` - Registers a texture by its resource location to be loaded on next reload. +- `net.minecraft.commands.SharedSuggestionProvider#MATCH_SPLITTER` - Defines a matcher that matches a period, underscore, or forward slash. +- `net.minecraft.core.BlockPos$TraversalNodeStatus` - A marker indicating whether the `BlockPos` should be used, skipped, or stopped from any further traversal. +- `net.minecraft.core.component.PatchedDataComponentMap` + - `toImmutableMap` - Returns either the immutable patch or a copy of the current map. + - `hasNonDefault` - Returns whether there is a custom value for the data component instead of just the default. +- `net.minecraft.data.PackOutput$PathProvider#json` - Gets the JSON path from a resource key. +- `net.minecraft.data.loot.BlockLootSubProvider#createMultifaceBlockDrops` - Drops a block depending on the block face mined. +- `net.minecraft.data.worldgen.placement.PlacementUtils#HEIGHTMAP_NO_LEAVES` - Creates a y placement using the `Heightmap$Types#MOTION_BLOCKING_NO_LEAVES` heightmap. +- `net.minecraft.network.chat.Style#getShadowColor`, `withShadowColor` - Methods for handling the shadow color of a component. +- `net.minecraft.network.protocol.game.ServerboundPlayerLoadedPacket` - A packet for when the client player loads into a client world. +- `net.minecraft.resources.FileToIdConverter#registry` - Gets the file converter from a registry key. +- `net.minecraft.util.ExtraCodecs` + - `idResolverCodec` - Creates a codec that maps some key to some value. + - `compactListCodec` - Creates a codec that can either be an element of a list of elements. + - `floatRange` - Creates a codec that must be between two float values. + - `$LateBoundIdMapper` - A mapper that functionally acts like a registry with an associated codec. +- `net.minecraft.util.profiling.jfr.JvmProfiler#onStructureGenerate` - Returns the profiled duration on when a structure attempts to generate in the world. +- `net.minecraft.util.profiling.jfr.event.StructureGenerationEvent` - A profiler event when a structure is being generated. +- `net.minecraft.util.profiling.jfr.stats.StructureGenStat` - A result of a profiled structure generation. +- `net.minecraft.world.entity` + - `LivingEntity` + - `resolvePlayerResponsibleForDamage` - Gets the player responsible for hurting the current entity. + - `canBeNameTagged` - When true, the entity's can be set with a name tag. + - `Mob#getPreferredWeaponType` - Gets the tag that represents the weapons the entity wants to pick up. +- `net.minecraft.world.entity.ai.attributes.AttributeMap#resetBaseValue` - Resets the attribute instance to its default value. +- `net.minecraft.world.entity.monster.creaking` + - `Creaking` + - `activate`, `deactivate` - Handles the activateion of the brain logic for the creaking. + - `setTransient`, `isHeartBound`, `setHomePos`, `getHomePos` - Handles the home position. + - `blameSourceForDamage` - Finds the player responsible for the damage. + - `tearDown` - Handles when the creaking is destroyed. + - `creakingDeathEffects` - Handles the death of a creaking. + - `playerIsStuckInYou` - Checks whether there are at least four players stuck in a creaking. + - `setTearingDown`, `isTearingDown` - Handles the tearing down state. + - `hasGlowingEyes`, `checkEyeBlink` - Handles the eye state. +- `net.minecraft.world.entity.player.Player` + - `hasClientLoaded`, `setClientLoaded` - Whether the client player has been loaded. + - `tickClientLoadTimeout` - Ticks the timer on how long to wait before kicking out the client player if not loaded. +- `net.minecraft.world.item` + - `Item#shouldPrintOpWarning` - Whether a warning should be printed to the player based on stored block entity data and adminstrator permissions. + - `ItemStack` + - `getCustomName` - Returns the custom name of the item, or `null` if no component exists. + - `immutableComponents` - Returns either the immutable patch or a copy of the stack component map. + - `hasNonDefault` - Returns whether there is a custom value for the data component instead of just the default. +- `net.minecraft.world.item.component.CustomData` + - `parseEntityId` - Reads the entity id off of the component. + - `parseEntityType` - Reads the entity type from the id and maps it to its registry object. +- `net.minecraft.world.item.crafting.Ingredient#isEmpty` - Returns whether the ingredient has no values. +- `net.minecraft.world.item.trading.Merchant#stillValid` - Checks whether the merchant can still be accessed by the player. +- `net.minecraft.world.level` + - `Level#dragonParts` - Returns the list of entities that are the parts of the ender dragon. + - `ServerExplosion#getDamageSource` - Returns the damage source of the explosion. +- `net.minecraft.world.level.block` + - `EyeblossomBlock$Type` + - `block` - Gets the block for the current type. + - `state` - Gets the block state for the current type. + - `transform` - Returns the opposiate state of this type. + - `FlowerBlock#getBeeInteractionEffect` - Returns the effect that bees obtain when interacting with the flower. + - `FlowerPotBlock#opposite` - Returns the opposite state of the block, only for potted eyeblossoms. + - `MultifaceBlock#canAttachTo` - Returns whether this block can attach to another block. + - `MultifaceSpreadeableBlock` - A multiface block that can naturally spread. +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner#overrideEntityToSpawn` - Changes the entity to spawn in the trial. + - `TrialSpawnerConfig#withSpawning` - Sets the entity to spawn within the trial. + +### List of Changes + +- `com.mojang.blaze3d.platform.NativeImage#upload` no longer takes in three booleans that set the filter mode or texture wrap clamping for `TEXTURE_2D` + - This has been moved to `AbstractTexture#setClamp` and `#setFilter` +- `net.minecraft.client.gui` + - `Gui#clear` -> `clearTitles` + - `GuiGraphics#drawWordWrap` has a new overload that takes in whether a drop shadow should be applied to the text + - The default version enables drop shadows instead of disabling it +- `net.minecraft.client.gui.components` + - `AbstractContainerWidget` now implements `AbstractScrollArea` + - `AbstractScrollWidget` -> `AbstractScrollArea` or `AbstractTextAreaWidget` depending on use-case, not one-to-one + - `AbstractSelectionList` + - `setRenderHeader` is now bundled into a new constructor with an extra integer + - `getMaxScroll` -> `AbstractScrollArea#maxScrollAmount` + - `getScrollAmount` -> `AbstractScrollArea#scrollAmount` + - `scrollbarVisible` -> `AbstractScrollArea#scrollbarVisible` + - `setClampedScrollAmount`, `setScrollAmount` -> `AbstractScrollArea#setScrollAmount` + - `clampScrollAmount` -> `refreshScrollAmount` + - `updateScrollingState` -> `AbstractScrollArea#updateScrolling` + - `getScrollbarPosition`, `getDefaultScrollbarPosition` -> `scrollBarY`, not one-to-one + - `AbstractWidget#clicked` -> `isMouseOver`, already exists +- `net.minecraft.client.gui.components.toasts.TutorialToast` now requires a `Font` as the first argument in its constructor +- `net.minecraft.client.gui.font.glyphs.BakedGlyph$Effect` and `$GlyphInstance` now take in the color and offset of the text shadow +- `net.minecraft.client.gui.screens` + - `LoadingOverlay#registerTextures` now takes in a `TextureManager` instead of the `Minecraft` instance + - `TitleScreen#preloadResources` -> `registerTextures`, not one-to-one +- `net.minecraft.client.gui.screens.debug.GameModeSwitcherScreen$GameModeSlot` is now a static inner class +- `net.minecraft.client.gui.screens.reporting.ChatSelectionScreen$Entry`, `$PaddingEntry` are now static inner classes +- `net.minecraft.client.gui.screens.worldselection.SwitchGrid$Builder#build` no longer takes in a `Consumer` +- `net.minecraft.client.model` + - `DonkeyModel#createBodyLayer`, `createBabyLayer` now take in a scaling factor + - `VillagerHeadModel` -> `VillagerLikeModel` +- `net.minecraft.client.model.geom.EntityModelSet` is no longer a `ResourceManagerReloadListener` +- `net.minecraft.client.multiplayer.MultiPlayerGameMode#handlePickItem` -> `handlePickItemFromBlock` or `handlePickItemFromEntity`, providing both the actual object data to sync and a `boolean` about whether to include the data of the object being picked +- `net.minecraft.client.particle.CherryParticle` -> `FallingLeavesParticle`, not one-to-one as the new class has greater configuration for its generalization +- `net.minecraft.client.player.ClientInput#tick` no longer takes in any parameters +- `net.minecraft.client.renderer` + - `CubeMap#preload` -> `registerTextures`, not one-to-one + - `LevelRenderer` + - `renderLevel` no longer takes in the `LightTexture` + - `onChunkLoaded` -> `onChunkReadyToRender` + - `PostChainConfig$Pass#program` -> `programId` + - `program` now returns the `ShaderProgram` with the given `programId` + - `ScreenEffectRenderer#renderScreenEffect` now takes in a `MultiBufferSource` + - `SectionOcclusionGraph#onChunkLoaded` -> `onChunkReadyToRender` + - `Sheets#createSignMaterial`, `createHangingSignMaterial` now has an overload that takes in a `ResourceLocation` + - `SkyRenderer` + - `renderSunMoonAndStars`, `renderSunriseAndSunset` now takes in a `MultiBufferSource$BufferSource` instead of a `Tesselator` + - `renderEndSky` no longer takes in the `PoseStack` + - `WeatherEffectRenderer#render` now takes in a `MultiBufferSource$BufferSource` instead of a `LightTexture` +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#createBodyLayer` -> `BannerModel#createBodyLayer`, not one-to-one + - `HangingSignRenderer` + - `createHangingSignLayer` now takes in a `HangingSignRenderer$AttachmentType` + - `$HangingSignModel` is now replaced with a `Model$Simple`, though its fields can be obtained from the root + - `SkullBlockRenderer#getRenderType` now has an overload that takes in a `ResourceLocation` to override representing the player's texture +- `net.minecraft.client.renderer.entity.AbstractHorseRenderer`, `DonkeyRenderer` no longer takes in a float scale +- `net.minecraft.client.renderer.entity.layers.CrossedArmsItemLayer` now requires the generic `M` to be a `VillagerLikeModel` +- `net.minecraft.client.renderer.entity.state.CreakingRenderState#isActive` -> `eyesGlowing` + - The original parameter still exists on the `Creaking`, but is not necessary for rendering +- `net.minecraft.core.BlockPos#breadthFirstTraversal` now takes in a function that returns a `$TraversalNodeStatus` instead of a simple predicate to allow certain positions to be skipped +- `net.minecraft.core.particles.TargetColorParticleOption` -> `TrailParticleOption`, not one-to-one +- `net.minecraft.data.DataProvider#savelAll` now has overloads for maps with a key function to get the associated path +- `net.minecraft.network` + - `NoOpFrameEncoder` replaced by `LocalFrameEncoder`, not one-to-one + - `NoOpFrameDecoder` replaced by `LocalFrameDecoder`, not one-to-one + - `MonitorFrameDecoder` replaced by `MonitoredLocalFrameDecoder`, not one-to-one +- `net.minecraft.network.protocol.game` + - `ClientboundLevelParticlesPacket` now takes in a boolean that determines whether the particle should always render + - `ClientboundMoveVehiclePacket` is now a record + - `ClientboundPlayerInfoUpdatePacket$Entry` now takes in a boolean representing whether the hat should be shown + - `ClientboundSetHeldSlotPacket` is now a record + - `ServerboundMoveVehiclePacket` is now a record + - `ServerboundPickItemPacket` -> `ServerboundPickItemFromBlockPacket`, `ServerboundPickItemFromEntityPacket`; not one-to-one +- `net.minecraft.server.level + - `ServerLevel#sendParticles` now has an overload that takes in the override limiter distance and whether the particle should always be shown + - Other overloads that take in the override limiter now also take in the boolean for if the particle should always be shown + - `ServerPlayer#doCheckFallDamage` -> `Entity#doCheckFallDamage`, now final +- `net.minecraft.util` + - `ARGB#from8BitChannel` is now private, with individual float components obtained from `alphaFloat`, `redFloat`, `greenFloat`, and `blueFloat` + - `SpawnUtil#trySpawnMob` now takes in a boolean that, when false, allows the entity to spawn regardless of collision status with the surrounding area +- `net.minecraft.util.profiling.jfr.callback.ProfiledDuration#finish` now takes in a boolean that indicates whether the profiled event was successful +- `net.minecraft.util.profiling.jfr.parse.JfrStatsResults` now takes in a list of structure generation statistics +- `net.minecraft.world.effect.PoisonMobEffect`, `WitherMobEffect` is now public +- `net.minecraft.world.entity` + - `Entity` + - `setOnGroundWithMovement` has an overload that sets the horizontal collision to whatever the entity's current state is. + - `awardKillScore` no longer takes in an integer + - `makeBoundingBox()` is now final + - `makeBoundingBox(Vec3)` is now + - `onlyOpCanSetNbt` -> `EntityType#onlyOpCanSetNbt` + - `Leashable` + - `readLeashData` is now private, replaced by a method that returns nothing + - `dropLeash(boolean, boolean)` -> `dropLeash()`, `removeLeash`, `onLeashRemoved`; not one-to-one, as they all internally call the private `dropLeash` + - `LivingEntity` + - `isLookingAtMe` no longer takes in a `Predicate`, and array of `DoubleSupplier`s is now an array of `double`s + - `hasLineOfSight` takes in a double instead of a `DoubleSupplier` +- `net.minecraft.world.entity.ai.behavior.AcquirePoi#create` now has overloads which take in a `BiPredicate` for filtering POI locations +- `net.minecraft.world.entity.animal.Bee#attractsBees` is now public +- `net.minecraft.world.entity.monster.Shulker#getProgressAabb`, `getProgressDeltaAabb` now take in a movement `Vec3` +- `net.minecraft.world.entity.player` + - `Inventory` + - `setPickedItem` -> `addAndPickItem` + - `findSlotMatchingCraftingIngredient` now takes in an `ItemStack` to compare against + - `Player#getPermissionLevel` is now public + - `StackedContents$IngredientInfo` is now an interface that acts like a predicate for accepting some item +- `net.minecraft.world.entity.projectile.FishingHook` no longer takes in the `ItemStack` +- `net.minecraft.world.inventory.Slot#getNoItemIcon` now returns a single `ResourceLocation` rather than a pair of them +- `net.minecraft.world.item` + - `Item$TooltipContext#of` now takes in the `Player` viewing the item + - `MobBucketItem` now requires a `Mob` entity type + -` SpawnEggItem#spawnsEntity`, `getType` now takes in a `HolderLookup$Provider` +- `net.minecraft.world.item.crafting` + - `Ingredient` now implements `StackedContents$IngredientInfo>` + - `items` now returns a stream instead of a list + - `PlacementInfo#slotInfo` -> `slotsToIngredientIndex`, not one-to-one +- `net.minecraft.world.level.Level#addParticle` now takes in a boolean representing if the particle should always be shown +- `net.minecraft.world.level.block` + - `Block#getCloneItemStack` -> `state.BlockBehaviour#getCloneItemStack`, now protected + - `CherryLeavesBlock` -> `ParticleLeavesBlock` + - `CreakingHeartBlock#canSummonCreaking` -> `isNaturalNight` + - `MultifaceBlock` is no longer abstract and implements `SimpleWaterloggedBlock` + - `getSpreader` -> `MultifaceSpreadeableBlock#getSpreader` + - `SculkVeinBlock` is now an instance of `MultifaceSpreadeableBlock` + - `SnowyDirtBlock#isSnowySetting` is now protected +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity` + - `litTime` -> `litTimeRemaining` + - `litDuration` -> `litTotalTime` + - `cookingProgress` -> `cookingTimer` + - `BeehiveBlockEntity#addOccupant` now takes in a `Bee` rather than an `Entity` + - `CreakingHeartBlockEntity#setCreakingInfo` - Sets the creaking the block entity is attached to. +- `net.minecraft.world.level.block.state.BlockBehaviour#getCloneItemStack`, `$BlockStateBase#getCloneItemStack` now takes in a boolean representing if there is infinite materials and whether the current block data should be saved. +- `net.minecraft.world.level.chunk.ChunkGenerator#createStructures` now takes in the `Level` resource key, only used for profiling +- `net.minecraft.world.level.levelgen.feature.configurations` + - `MultifaceGrowthConfiguration` now takes in a `MultifaceSpreadableBlock` instead of a `MultifaceBlock` + - `SimpleBlockConfiguration` now takes in a boolean on whether to schedule a tick update +- `net.minecraft.world.level.levelgen.structure.Structure#generate` now takes in the `Structure` holder and a `Level` resource key, only used for profiling + +### List of Removals + +- `com.mojang.blaze3d.systems.RenderSystem#overlayBlendFunc` +- `net.minecraft.client.gui.components.AbstractSelectionList` + - `clickedHeader` + - `isValidMouseClick` +- `net.minecraft.client.gui.screens.recipebook.RecipeCollection#hasSingleResultItem` +- `net.minecraft.client.model` + - `DrownedModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `FelineModel#CAT_TRANSFORMER` + - `HumanoidModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `PlayerModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `SkeletonModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `VillagerModel#BABY_TRANSFORMER` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `load` + - `reset` + - `getDefaultBlur` + - `PreloadedTexture` + - `TextureManager` + - `getTexture(ResourceLocation, AbstractTexture)` + - `register(String, DynamicTexture)` + - `preload` +- `net.minecraft.server.level.TicketType#POST_TELEPORT` +- `net.minecraft.world.entity.LivingEntity#deathScore` +- `net.minecraft.world.entity.ai.navigation.FlyingPathNavigation`, `GroundPathNavigation` + - `canPassDoors`, `setCanPassDoors` + - `canOpenDoors` +- `net.minecraft.world.entity.monster.creaking.CreakingTransient` +- `net.minecraft.world.entity.player.StackedItemContents#convertIngredientContents` +- `net.minecraft.world.item` + - `CompassItem#getSpawnPosition` + - `ItemStack#clearComponents` +- `net.minecraft.world.item.crafting.PlacementInfo` + - `ingredientToContents` + - `unpackedIngredients` + - `$SlotInfo` +- `net.minecraft.world.level.block.CreakingHeartBlock$CreakingHeartState` +- `net.minecraft.world.level.block.entity.BlockEntity#onlyOpCanSetNbt` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData#setEntityId` diff --git a/src/detailed-primers/1.21.5-from-1.21.4.md b/src/detailed-primers/1.21.5-from-1.21.4.md new file mode 100644 index 0000000..963c822 --- /dev/null +++ b/src/detailed-primers/1.21.5-from-1.21.4.md @@ -0,0 +1,3069 @@ +# Minecraft 1.21.4 -> 1.21.5 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.4 to 1.21.5. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @TelepathicGrunt for the information within the 'Very Technical Changes' section +- @RogueLogix for their review and comments on the 'Render Pipeline Rework' section +- @Tslat for catching an error about `equipOnInteract` + +## 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](https://misode.github.io/versions/?id=1.21.5&tab=changelog). + +## Handling the Removal of Block Entities Properly + +Previously, `BlockEntity` would handle all of their removal logic within `BlockBehaviour#onRemove`, including both dropping any stored items and removing the block entity itself. However, depending on how the method is used, it can cause some strange behaviors due to the mutable state of the block entity. For this reason, the logic that makes up the removal process has been split between two methods: `BlockEntity#preRemoveSideEffects` and `BlockBehaviour#affectNeighborsAfterRemoval`. + +`BlockEntity#preRemoveSideEffects` is now responsible for removing anything from the block entity before it is removed from the level. By default, if the `BlockEntity` is a `Container` instance, it will drop the contents of the container into the level. Other logic can be handled within here, but it should generally avoid removing the `BlockEntity` itself, unless the position of the block entity tends to change dynamically, like for a piston. + +From there, the `LevelChunk` logic will call `removeBlockEntity` before calling `BlockBehaviour#affectNeighborsAfterRemoval`. This should only send the updates to other blocks indicating that this block has been removed from the level. For `BlockEntity` holders, this can be done easily by calling `Containers#updateNeighboursAfterDestroy`. Otherwise may want to call `Level#updateNeighborsAt` themselves, depending on the situation. + +- `net.minecraft.world.Containers` + - `updateNeighboursAfterDestroy` - Updates the neighbor state aftering destroying the block at the specified position. + - `dropContentsOnDestroy` is removed, handled within `BlockEntity#preRemoveSideEffects` for `Container` instances +- `net.minecraft.world.level.block.entity.BlockEntity#preRemoveSideEffects` - Handles logic on the block entity that should happen before being removed from the level. +- `net.minecraft.world.level.block.state.BlockBehaviour#onRemove`, `$BlockStateBase#onRemove` -> `affectNeighborsAfterRemoval`, should only handle logic to update the surrounding neighbors rather than dropping container data + +## Voxel Shape Helpers + +`VoxelShape`s have received numerous helpers for more common transformations of its base state. There are the `Block` methods for creating a centered (if desired) box and the `Shapes` methods for rotating a `VoxelShape` to its appropriate axis or direction. There is also a `Shapes#rotateAttachFace` method for rotating some `VoxelShape` that is attached to a face of a different block. The results are either stored in a `Map` of some key to a `VoxelShape`, or when using `Block#getShapeForEachState`, a `Function`. + +Most of the `Block` subclasses that had previous public or protected `VoxelShape`s are now private, renamed to a field typically called `SHAPE` or `SHAPES`. Stored `VoxelShape`s may also be in a `Function` instead of directly storing the map itself. + +- `com.mojang.math.OctahedralGroup` + - `permute` - Returns the axis that the given axis is permuted to within the specified group. + - `fromAngles` - Creates a group with the provided X and Y rotations. +- `net.minecraft.core.Direction$Axis#choose` now has an overload that takes in three booleans +- `net.minecraft.world.level.block.Block` + - `boxes` - Creates one more than the specified number of boxes, using the index as part of the function to create the `VoxelShape`s. + - `cube` - Creates a centered cube of the specified size. + - `column` - Creates a horizontally centered column of the specified size. + - `boxZ` - Creates a vertically centered (around the X axis) cube/column of the specified size. + - `getShapeForEachState` now returns a `Function` which wraps the `ImmutableMap`, there is also a method that only considers the specified properties instead of all possible states. +- `net.minecraft.world.phys.shapes` + - `DiscreteVoxelShape#rotate` - Rotates a voxel shape according to the permutation of the `OctahedralGroup`. + - `Shapes` + - `blockOccudes` -> `blockOccludes` + - `rotate` - Rotates a given voxel shape according to the permutation of the `OctahedralGroup` around the provided vector, or block center if not specified. + - `equal` - Checks if two voxel shapes are equivalent. + - `rotateHorizontalAxis` - Creates a map of axes to `VoxelShape`s of a block being rotated around the y axis. + - `rotateAllAxis` - Creates a map of axes to `VoxelShape`s of a block being rotated around any axis. + - `rotateHorizontal` - Creates a map of directions to `VoxelShape`s of a block being rotated around the y axis. + - `rotateAll` - Creates a map of directions to `VoxelShape`s of a block being rotated around the any axis. + - `rotateAttachFace` - Creates a map of faces to a map of directions to `VoxelShape`s of a block being rotated around the y axis when attaching to the faces of other blocks. + - `VoxelShape#move` now has an overload to take in a `Vec3i` + +## Weapons, Tools, and Armor: Removing the Redundancies + +There have been a lot of updates to weapons, tools, and armor that removes the reliance on the hardcoded base classes of `SwordItem`, `DiggerItem`, and `ArmorItem`, respectively. These have been replaced with their associated data components `WEAPON` for damage, `TOOL` for mining, `ARMOR` for protection, and `BLOCKS_ATTACKS` for shields. Additionally, the missing attributes are usually specified by setting the `ATTRIBUTE_MODIFIERS`, `MAX_DAMAGE`, `MAX_STACK_SIZE`, `DAMAGE`, `REPAIRABLE`, and `ENCHANTABLE`. Given that pretty much all of the non-specific logic has moved to a data component, these classes have now been completely removed. Use one of the available item property methods or call `Item$Properties#component` directly to set up each item as a weapon, tool, armor, or some combination of the three. + +Constructing a `BlockAttacks` component for a shield-like item: + +```java +var blocker = new BlocksAttacks( + // The number of seconds to wait when the item is being used + // before the blocking effect is applied. + 1.2f, + // A scalar to change how many ticks the blocker is disabled + // for. If negative, the blocker cannot normally be disabled. + 0.5f, + // A list of reductions for what type and how much of a damage type + // is blocked by this blocker. + List.of( + new DamageReduction( + // The horizontal blocking angle of the shield required to apply + // the reduction + 90f, + // A set of damage types this reduction should apply for. + // When empty, it applies for all damage types. + Optional.empty(), + // The base damage to reduce the attack by. + 1f, + // A scalar representing the fraction of the damage blocked. + 0.5f + ) + ), + // A function that determines how much durability to remove to the blocker. + new ItemDamageFunction( + // A threshold that specifies the minimum amount of damage required + // to remove durability from the blocker. + 4f, + // The base durability to remove from the blocker. + 1f, + // A scalar representing the fraction of the damage to convert into + // removed durability. + 0.5f + ), + // A tag key containing the items that can bypass the blocker and deal + // damage directly to the wielding entity. If empty, no item can bypass + // the blocker. + Optional.of(DamageTypeTags.BYPASSES_SHIELD), + // The sound to play when the blocker successfully mitigates some damage. + Optional.of(SoundEvents.SHIELD_BLOCK), + // The sound to play when the blocker is disabled by a weapon. + Optional.of(SoundEvents.SHIELD_BREAK) +); +``` + +Constructing a `Weapon` component for a sword-like item: + +```java +var weapon = new Weapon( + // The amount of durability to remove from the item. + 3, + // The number of seconds a `BlocksAttack`s component item should + // be disabled for when hit with this weapon. + 5f +); +``` + +- `net.minecraft.core.component.DataComponents` + - `UNBREAKABLE` is now a `Unit` instance + - `HIDE_ADDITIONAL_TOOLTIP`, `HIDE_TOOLTIP` have been bundled in `TOOLTIP_DISPLAY`, taking in a `TooltipDisplay` + - `BLOCKS_ATTACKS` - A component that determines whether a held item can block an attack from some damage source + - `INSTRUMENT` now takes in an `InstrumentComponent` + - `PROVIDES_TRIM_MATERIAL`, `PROVIDES_BANNER_PATTERNS` handles a provider for their associated types. + - `BEES` now takes in a `Bees` component + - `BREAK_SOUND` - The sound to play when the item breaks. +- `net.minecraft.data.recipes` + - `RecipeProvider#trimSmithing` now takes in the key for the `TrimPattern` + - `SmithingTrimRecipeBuilder` now takes in a holder for the `TrimPattern` +- `net.minecraft.world.entity.LivingEntity` + - `blockUsingShield` -> `blockUsingItem` + - `blockedByShield` -> `blockedByItem` + - `hurtCurrentlyUsedShield` is removed + - `canDisableBlocking` -> `getSecondsToDisableBlocking`, not one-to-one + - `applyItemBlocking` - Applies the damage reduction done when blocking an attack with an item. + - `isDamageSourceBlocked` is removed +- `net.minecraft.world.entity.player.Player#disableShield` -> `net.minecraft.world.item.component.BlocksAttacks#disable` +- `net.minecraft.world.item` + - `AnimalArmorItem` class is removed + - `ArmorItem` class is removed + - `AxeItem` now extends `Item` + - `BannerPatternItem` class is removed + - `DiggerItem` class is removed + - `FireworkStarItem` class is removed + - `HoeItem` now extends `Item` + - `InstrumentItem` no longer takes in the tag key + - `Item` + - `getBreakingSound` is removed + - `$Properties` + - `tool` - Sets the item as a tool. + - `pickaxe` - Sets the item as a pickaxe. + - `sword` - Sets the item as a sword. + - `axe` - Sets the item as an axe. + - `hoe` - Sets the item as a hoe. + - `shovel` - Sets the item as a shovel. + - `trimMaterial` - Sets the item as providing a trim material. + - `ItemStack#getBreakingSound` is removed + - `PickaxeItem` class is removed + - `ShovelItem` now extends `Item` + - `SwordItem` class is removed + - `ToolMaterial#applyToolProperties` now takes in a boolean of whether the weapon can disable a blocker (e.g., shield) +- `net.minecraft.world.item.component` + - `Bees` - A component that holds the occupants of a beehive. + - `BlocksAttacks` - A component for blocking an attack with a held item. + - `InstrumentComponent` - A component that holds the sound an instrument plays. + - `ProvidesTrimMaterial` - A component that provides a trim material to use on some armor. + - `Tool` now takes in a boolean representing if the tool can destroy blocks in creative + - `Unbreakable` class is removed + - `Weapon` - A data component that holds how much damage the item can do and for how long it disables blockers (e.g., shield). +- `net.minecraft.world.item.equipment` + - `AllowedEntitiesProvider` - A functional interface for getting the entities that are allowed to handle the associated logic. + - `ArmorMaterial` + - `humanoidProperties` -> `Item$Properties#humanoidArmor` + - `animalProperties` -> `Item$Properties#wolfArmor`, `horseArmor` + - `createAttributes` is now public + - `Equippable` + - `equipOnInteract` - When true, the item can be equipped to another entity when interacting with them. + - `saddle` - Creates an equippable for a saddle. + - `equipOnTarget` - Equips the item onto the target entity. + + +### Extrapolating the Saddles: Equipment Changes + +A new `EquipmentSlot` has been added for saddles, which brings with it new changes for genercizing slot logic. + +First, rendering an equipment slot for an entity can now be handled as an additional `RenderLayer` called `SimpleEquipmentLayer`. This takes in the entity renderer, the `EquipmentLayerRenderer`, the layer type to render, a function to get the `ItemStack` from the entity state, and the adult and baby models. The renderer will attempt to look up the client info from the associated equippable data component and use that to render the laters as necessary. + +Next, instead of having individual lists for each equipment slot on the entity, there is now a general `EntityEquipment` object that holds a delegate to a map of slots to `ItemStack`s. This simplifies the storage logic greatly. + +Finally, equippables can now specify whether an item should be equipped to a mob on interact (usually right-click) by setting `equipOnInteract`. + +- `net.minecraft.client.model` + - `CamelModel` + - `head` is now public + - `createBodyMesh` - Creates the mesh definition for a camel. + - `CamelSaddleModel` - A model for a camel with a saddle. + - `DonkeyModel#createSaddleLayer` - Creates the layer definition for a donkey with a saddle. + - `EquineSaddleModel` - A model for an equine animal with a saddle. + - `PolarBearModel#createBodyLayer` now takes in a boolean for if the entity is a baby +- `net.minecraft.client.renderer.entity.layers.HorseArmorLayer`, `SaddleLayer` -> `SimpleEquipmentLayer` +- `net.minecraft.client.renderer.entity.state` + - `CamelRenderState#isSaddled` -> `saddle`, not one-to-one + - `EquineRenderState#isSaddled` -> `saddle`, not one-to-one + - `PigRenderState#isSaddled` -> `saddle`, not one-to-one + - `SaddleableRenderState` class is removed + - `StriderRenderState#isSaddled` -> `saddle`, not one-to-one + - `CamelRenderState#isSaddled` -> `saddle`, not one-to-one +- `net.minecraft.client.resources.model.EquipmentClientInfo$LayerType` now has: + - `PIG_SADDLE` + - `STRIDER_SADDLE` + - `CAMEL_SADDLE` + - `HORSE_SADDLE` + - `DONKEY_SADDLE` + - `MULE_SADDLE` + - `ZOMBIE_HORSE_SADDLE` + - `SKELETON_HORSE_SADDLE` + - `trimAssetPrefix` - Returns the prefix applied to the texture containing the armor trims for the associated type. +- `net.minecraft.world.entity` + - `EntityEquipment` - A map of slots to item stacks representing the equipment of the entity. + - `EquipmentSlot` + - `SADDLE`, `$Type#SADDLE` + - `canIncreaseExperience` - Whether the slot can increase the amount of experience earned when killing a mob. + - `EquipmentSlotGroup` is now an iterable + - `SADDLE` + - `slots` - Returns the slots within the group. + - `LivingEntity` + - `getEquipSound` - Gets the sound to play when equipping an item into a slot. + - `getArmorSlots`, `getHandSlots`, `getArmorAndBodyArmorSlots`, `getAllSlots` are removed + - `equipment` - The equipment worn by the entity. + - `createEquipment` - Sets the default equipment worn by the entity. + - `drop` - Drops the specified stack. + - `getItemBySlot`, `setItemBySlot` are no longer abstract. + - `verfiyEquippedItem` is removed + - `Mob` + - `isSaddled` - Checks if an item is in the saddle slot. + - `createEquipmentSlotContainer` - Creates a single item container for the equipment slot. + - `OwnableEntity#getRootOwner` - Gets the highest level owner of the entity. + - `Saddleable` interface is removed +- `net.minecraft.world.entity.animal.horse.AbstractHorse` + - `syncSaddletoClients` is removed + - `getBodyArmorAccess` is removed +- `net.minecraft.world.entity.player` + - `Inventory` + - `armor`, `offhand` -> `EQUIPMENT_SLOT_MAPPING`, not one-to-one + - `selected` is now private + - `setSelectedHotbarSlot` -> `setSelectedSlot` + - Getter also exists `getSelectedSlot` + - `getSelected` -> `getSelectedItem` + - Setter also exists `setSelectedItem` + - `getNonEquipmentItems` - Returns the list of non-equipment items in the inventory. + - `getDestroySpeed` is removed + - `getArmor` is removed + - `PlayerEquipment` - Equipment that is worn by the player. +- `net.minecraft.world.item` + - `Item#inventoryTick(ItemStack, Level, Entity, int, boolean)` -> `inventoryTick(ItemStack, ServerLevel, Entity, EquipmentSlot)` + - `SaddleItem` class is removed + +## Weighted List Rework + +The weighted random lists have been redesigned into a basic class that hold weighted entries, and a helper class that can obtain weights from the objects themselves. + +First there is `WeightedList`. It is effectively the replacement for `SimpleWeightedRandomList`, working the exact same way by storing `Weighted` (replacement for `WeightedEntry`) entries in the list itself. Internally, the list is either stored as a flat array of object entries, or the compact weighted list if the total weight is greater than 64. Then, to get a random element, either `getRandom` or `getRandomOrThrow` can be called to obtain an entry. Both of these methods will either return some form of an empty object or exception if there are no elements in the list. + +Then there are the static helpers within `WeightedRandom`. These take in raw lists and some `ToIntFunction` that gets the weight from the list's object. Some methods also take in an integer either representing the largest index to choose from or the entry associated with the weighted index. + +- `net.minecraft.client.resources.model.WeightedBakedModel` now takes in a `WeightedList` instead of a `SimpleWeightedRandomList` +- `net.minecraft.util.random` + - `SimpleWeightedRandomList`, `WeightedRandomList` -> `WeightedList`, now final and not one-to-one + - `contains` - Checks if the list contains this element. + - `Weight` class is removed + - `WeightedEntry` -> `Weighted` + - All `WeightedRandom` static methods now take in a `ToIntFunction` to get the weight of some entry within the provided list +- `net.minecraft.util.valueproviders.WeightedListInt` now takes in a `WeightedList` +- `net.minecraft.world.level.SpawnData#LIST_CODEC` is now a `WeightedList` of `SpawnData` +- `net.minecraft.world.level.biome` + - `Biome#getBackgroundMusic` is now a `WeightedList` of `Music` + - `BiomeSpecialEffects#getBackgroundMusic`, `$Builder#backgroundMusic` is now a `WeightedList` of `Music` + - `MobSpawnSettings#EMPTY_MOB_LIST`, `getMobs` is now a `WeightedList` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig#spawnPotentialsDefinition`, `lootTablesToEject` now takes in a `WeightedList` +- `net.minecraft.world.level.chunk.ChunkGenerator#getMobsAt` now returns a `WeightedList` +- `net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider` now works with `WeightedList`s +- `net.minecraft.world.level.levelgen.heightproviders.WeightedListHeight` now works with `WeightedList`s +- `net.minecraft.world.level.levelgen.structure.StructureSpawnOverride` now takes in a `WeightedList` +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `PoolAliasBinding#random`, `randomGroup` now takes in a `WeightedList` + - `Random` now takes in a `WeightedList` + - `RandomGroup` now takes in a `WeightedList` +- `net.minecraft.world.level.levelgen.structure.structures.NetherFortressStructure#FORTRESS_ENEMIES` is now a `WeightedList` + +## Tickets + +Tickets have been reimplemented into a half type registry-like, half hardcoded system. The underlying logic of keeping a chunk loaded or simulated for a certain period of time still exists; however, the logic associated with each ticket is hardcoded into their appropriate locations, such as the forced or player loading tickets. + +Tickets begin with their registered `TicketType`, which contains information about how many ticks should the ticket should last for (or `0` when permanent), whether the ticket should be saved to disk, and what the ticket is used for. A ticket has two potential uses: one for loading the chunk and keeping it loaded, and one for simulating the chunk based on the expected movement of the ticket creator. Most ticks specify that they are for both loading and simulation. + +There are two special types that have additional behavior associated with them. `TicketType#FORCED` has some logic for immediately loading the chunk and keeping it loaded. `TicketType#UNKNOWN` cannot be automatically timed out, meaning they are never removed unless explicitly specified. + +```java +// You need to register the ticket type to `BuiltInRegistries#TICKET_TYPE` +public static final TicketType EXAMPLE = new TicketType( + // The amount of ticks before the ticket is removed + // Set to 0 if it should not be removed + 0L, + // Whether the ticket should be saved to disk + true, + // What the ticket will be used for + TicketType.TicketUse.LOADING_AND_SIMULATION +); +``` + +Then there is the `Ticket` class, which are actually stored and handled within the `TicketStorage`. The `Ticket` class takes in the type of the ticket and uses it to automatically populate how long until it expires. It also takes in the ticket level, which is a generally a value of 31 (for entity ticking and block ticking), 32 (for block ticking), or 33 (only can access static or modify, not naturally update) minus the radius of chunks that can be loaded. A ticket is then added to the process by calling `TicketStorage#addTicketWithRadius` or its delegate `ServerChunkCache#addTicketWithRadius`. There is also `addTicket` if you wish to specify the ticket manually rather than having it computed based on its radius. + +- `net.minecraft.server.level` + - `ChunkMap` now takes in a `TicketStorage` + - `$TrackedEntity#broadcastIgnorePlayers` - Broadcasts the packet to all player but those within the UUID list. + - `DistanceManager` + - `chunksToUpdateFutures` is now protected and takes in a `TicketStorage` + - `purgeStaleTickets` -> `net.minecraft.world.level.TicketStorage#purgeStaleTickets` + - `getTicketDebugString` -> `net.minecraft.world.level.TicketStorage#getTicketDebugString` + - `getChunkLevel` - Returns the current chunk level or the simulated level when the provided boolean is true. + - `getTickingChunks` is removed + - `removeTicketsOnClosing` is removed + - `$ChunkTicketTracker` -> `LoadingChunkTracker`, or `SimulationChunkTracker` + - `ServerChunkCache` + - `addRegionTicket` -> `addTicketWithRadius`, or `addTicket` + - `removeRegionTicket` -> `removeTicketWithRadius` + - `removeTicketsOnClosing` -> `deactivateTicketsOnClosing` + - `Ticket` is no longer final or implements `Comparable` + - The constructor no longer takes in a key + - `CODEC` + - `setCreatedTick`, `timedOut` -> `resetTicksLeft`, `decreaseTicksLeft`, `isTimedOut`; not one-to-one + - `TicketType` is now a record and no longer has a generic + - `getComparator` is removed + - `doesLoad`, `doesSimulate` - Checks whether the ticket use is for their particular instance. + - `$TicketUse` - What a ticket can be used for. + - `TickingTracker` -> `SimulationChunkTracker` +- `net.minecraft.world.level.ForcedChunksSavedData` -> `TicketStorage` +- `net.minecraft.world.level.chunk.ChunkSource` + - `updateChunkForced` now returns a boolean indicating if the chunk has been forcefully loaded + - `getForceLoadedChunks` - Returns all chunks that have been forcefully loaded. + +## The Game Test Overhaul + +Game tests have been completely overhauled into a registry based system, completely revamped from the previous automatic annotation-driven system. However, most implementations required to use the system must be implemented yourself rather than provided by vanilla. As such, this explanation will go over the entire system, including which parts need substantial work to use it similarly to the annotation-driven system of the previous version. + +### The Environment + +All game tests happen within some environment. Most of the time, a test can occur independent of the area, but sometimes, the environment needs to be curated in some fashion, such as checking whether an entity or block does something at a given time or whether. To facilitate the setup and teardown of the environment for a given test instance, a `TestEnvironmentDefinition` is created. + +A `TestEnvironmentDefinition` works similarly to the `BeforeBatch` and `AfterBatch` annotations. The environment contains two methods `setup` and `teardown` that manage the `ServerLevel` for the test. The environments are structured in a type-based registry system, meaning that every environment registers a `MapCodec` to built-in registry `minecraft:test_environment_definition_type` that is then consumed via the `TestEnvironmentDefinition` in a datapack registry `minecraft:test_environment`. + +Vanilla, by default, provides the `minecraft:default` test environment which does not do anything. However, additional test environments can be created using the available test definition types. + +#### Game Rules + +This environment type sets the game rules to use for the test. During teardown, the game rules are set back to their default value. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:game_rules", + + // A list of game rules with boolean values to set + "bool_rules": [ + { + // The name of the rule + "rule": "doFireTick", + "value": false + } + // ... + ], + + // A list of game rules with integer values to set + "int_rules": [ + { + "rule": "playersSleepingPercentage", + "value": 50 + } + // ... + ] +} +``` + +#### Time of Day + +This environment type sets the time to some non-negative integer, similar to how the `/time set ` command is used. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:time_of_day", + + // Sets the time of day in the world + // Common values: + // - Day -> 1000 + // - Noon -> 6000 + // - Night -> 13000 + // - Midnight -> 18000 + "time": 13000 +} +``` + +#### Weather + +This environment type sets the weather, similar to how the `/weather` command is used. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:weather", + + // Can be one of three values: + // - clear (No weather) + // - rain (Rain) + // - thunder (Rain and thunder) + "weather": "thunder" +} +``` + +#### Function + +This environment type provides two `ResourceLocation`s to mcfunctions to setup and teardown the level, respectively. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:function", + + // The setup mcfunction to use + // If not specified, nothing will be ran + // Points to 'data/examplemod/function/example/setup.mcfunction' + "setup": "examplemod:example/setup", + + // The teardown mcfunction to use + // If not specified, nothing will be ran + // Points to 'data/examplemod/function/example/teardown.mcfunction' + "teardown": "examplemod:example/teardown" +} +``` + +#### Composite + +If multiple combinations are required, then the composite environment type (aptly named `all_of`) can be used to string multiple of the above environment types together. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:all_of", + + // A list of test environments to use + // Can either specified the registry name or the environment itself + "definitions": [ + // Points to 'data/minecraft/test_environment/default.json' + "minecraft:default", + { + // A raw environment definition + "type": "..." + } + // ... + ] +} +``` + +### Custom Types + +If none of the types above work, then a custom definition can be created by implementing `TestEnvironmentDefinition` and creating an associated `MapCodec`: + +```java +public record ExampleEnvironmentType(int value1, boolean value2) implements TestEnvironmentDefinition { + + // Construct the map codec to register + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(ExampleEnvironmentType::value1), + Codec.BOOL.fieldOf("value2").forGetter(ExampleEnvironmentType::value2) + ).apply(instance, ExampleEnvironmentType::new) + ); + + @Override + public void setup(ServerLevel level) { + // Setup whatever is necessary here + } + + @Override + public void teardown(ServerLevel level) { + // Undo whatever was changed within the setup method + // This should either return to default or the previous value + } + + @Override + public MapCodec codec() { + return CODEC; + } +} +``` + +Then register the `MapCodec` using whatever registry method is required by your mod loader: + +```java +Registry.register( + BuiltInRegistries.TEST_ENVIRONMENT_DEFINITION_TYPE, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_environment_type"), + ExampleEnvironmentType.CODEC +); +``` + +Finally, you can use it in your environment definition: + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "examplemod:example_environment_type", + + "value1": 0, + "value2": true +} +``` + +### Test Functions + +The initial concept of game tests were structured around running functions from `GameTestHelper` determining whether the test succeeds or fails. Test functions are the registry-driven representation of those. Essentially, every test function is a method that takes in a `GameTestHelper`. + +At the moment, vanilla only provides `minecraft:always_pass`, which just calls `GameTestHelper#succeed`. Test functions are also not generated, meaning it simply runs the value with whatever is provided. As such, a test function should generally represent a single old game test: + +```java +Registry.register( + BuiltInRegistries.TEST_FUNCTION, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_function"), + (GameTestHelper helper) -> { + // Run whatever game test commands you want + helper.assertBlockPresent(...); + + // Make sure you have some way to succeed + helper.succeedIf(() -> ...); + } +); +``` + +### Test Data + +Now that we have environments and test functions, we can get into defining our game test. This is done through `TestData`, which is the equivalent of the `GameTest` annotation. The only things changed are that structures are now referenced by their `ResourceLocation` via `structure`, `GameTest#timeoutTicks` is now renamed to `TestData#maxTicks`, and instead of specifying `GameTest#rotationSteps`, you simply provide the `Rotation` via `TestData#rotation`. Everything else remains the same, just represented in a different format. + +### The Game Test Instance + +With the `TestData` in hand, we can now link everything together through the `GameTestInstance`. This instance is what actually represents a single test. Once again, vanilla only provides the default `minecraft:always_pass`, so we will need to construct the instance ourselves. + +#### The Original Instance + +The previous game tests are implemented using `minecraft:function`, which links a test function to the test data. + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "minecraft:function", + + // Points to a 'Consumer' in the test function registry + "function": "examplemod:example_function", + + // The 'TestData' information + + // The environment to run the test in + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // The structure used for the game test + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + // The number of ticks that the game test will run until it automatically fails + "max_ticks": 400, + // The number of ticks that are used to setup everying required for the game test + // This is not counted towards the maximum number of ticks the test can take + // If not specified, defaults to 0 + "setup_ticks": 50, + // Whether the test is required to succeed to mark the batch run as successful + // If not specified, defaults to true + "required": true, + // Specifies how the structure and all subsequent helper methods should be rotated for the test + // If not specified, nothing is rotated + "rotation": "clockwise_90", + // When true, the test can only be ran through the `/test` command + // If not specified, defaults to false + "manual_only": true, + // Specifies the maximum number of times that the test can be reran + // If not specified, defaults to 1 + "max_attempts": 3, + // Specifies the minimum number of successes that must occur for a test to be marked as successful + // This must be less than or equal to the maximum number of attempts allowed + // If not specified, defaults to 1 + "required_successes": 1, + // Returns whether the structure boundary should keep the top empty + // This is currently only used in block-based test instances + // If not specified, defaults to false + "sky_access": false +} +``` + +#### Block-Based Instances + +Vanilla also provides a block-based test instance via `minecraft:block_based`. This is handled through via structures with test blocks receiving signals via `Level#hasNeighborSignal`. To start, a structure must have one test block which is set to its start mode. This block is then triggered, sending a fifteen signal pulse for one tick. Structures may then have as many test blocks with either a log, accept, or fail mode set. Log test blocks also send a fifteen signal pulse when activated. Accept and fail test blocks either succeed or fail the game test if any of them are activated (success takes precedent over failure). + +As this test relies on test blocks in the structure, no additional information is required other than the test data: + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "minecraft:block_based", + + // The 'TestData' information + + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + "max_ticks": 400, + "setup_ticks": 50, + "required": true, + "rotation": "clockwise_90", + "manual_only": true, + "max_attempts": 3, + "required_successes": 1, + "sky_access": false +} +``` + +#### Custom Tests + +If you need to implement your own test-based logic, whether using a more dynamic feature ~~or because you can't be bothered to migrated all of your data logic to the new systems~~, you can create your own custom test instance by extending `GameTestInstance` and creating an associated `MapCodec`: + +```java +public class ExampleTestInstance extends GameTestInstance { + + // Construct the map codec to register + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(test -> test.value1), + Codec.BOOL.fieldOf("value2").forGetter(test -> test.value2), + TestData.CODEC.forGetter(ExampleTestInstance::info) + ).apply(instance, ExampleTestInstance::new) + ); + + public ExampleTestInstance(int value1, boolean value2, TestData> info) { + super(info); + } + + @Override + public void run(GameTestHelper helper) { + // Run whatever game test commands you want + helper.assertBlockPresent(...); + + // Make sure you have some way to succeed + helper.succeedIf(() -> ...); + } + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + protected MutableComponent typeDescription() { + // Provides a description about what this test is supposed to be + // Should use a translatable component + return Component.literal("Example Test Instance"); + } +} +``` + +Then register the `MapCodec` using whatever registry method is required by your mod loader: + +```java +Registry.register( + BuiltInRegistries.TEST_INSTANCE_TYPE, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_test_instance"), + ExampleTestInstance.CODEC +); +``` + +Finally, you can use it in your test instance: + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "examplemod:example_test_instance", + + "value1": 0, + "value2": true, + + // The 'TestData' information + + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + "max_ticks": 400, + "setup_ticks": 50, + "required": true, + "rotation": "clockwise_90", + "manual_only": true, + "max_attempts": 3, + "required_successes": 1, + "sky_access": false +} +``` + +- `net.minecraft.client.renderer.blockentity` + - `BeaconRenderer` now has a generic that takes in a subtype of `BlockEntity` and `BeaconBeamOwner` + - `StructureBlockRenderer` -> `BlockEntityWithBoundingBoxRenderer`, not one-to-one +- `net.minecraft.core.registries.Registries#TEST_FUNCTION`, `TEST_ENVIRONMENT_DEFINITION_TYPE`, `TEST_INSTANCE_TYPE` +- `net.minecraft.gametest.Main` - The entrypoint for the game test server. +- `net.minecraft.gametest.framework` + - `AfterBatch`, `BeforeBatch` annotations are removed + - `BlockBasedTestInstance` - A test instance for testing the test block. + - `BuiltinTestFunctions` - Contains all registered test functions. + - `FailedTestTracker` - An object for holding all game tests that failed. + - `FunctionGameTestInstance` - A test instance for running a test function. + - `GameTest` annotation is removed + - `GameTestAssertException` now extends `GameTestException` + - `GameTestException` - An exception thrown during the execution of a game test. + - `GameTestBatch` now takes in an index and environment definition instead of a name and batch setups + - `GameTestBatchFactory` + - `fromTestFunction` -> `divideIntoBatches`, not one-to-one + - `toGameTestInfo` is removed + - `toGameTestBatch` now takes in an environment definition and an index + - `$TestDecorator` - Creates a list of test infos from a test instance and level. + - `GameTestEnvironments` - Contains all environments used for batching game test instances. + - `GameTestGenerator` annotation is removed + - `GameTestHelper` + - `tickBlock` - Ticks the block at the specific position. + - `assertionException` - Returns a new exception to throw on error. + - `getBlockEntity` now takes in a `Class` to cast the block entity to + - `assertBlockTag` - Checks whether the block at the position is within the provided tag. + - `assertBlock` now takes in a block -> component function for the error message. + - `assertBlockProperty` now takes in a `Component` instead of a string + - `assertBlockState` now takes in either nothing, a blockstate -> component function, or a supplied component + - `assertRedstoneSignal` now takes in a supplied component + - `assertContainerSingle` - Asserts that a container contains exactly one of the item specified. + - `assertEntityPosition`, `assertEntityProperty` now takes in a component + - `fail` now takes in a `Component` for the error message + - `assertTrue`, `assertValueEqual`, `assertFalse` now takes in a component + - `GameTestInfo` now takes in a holder-wrapped `GameTestInstance` instead of a `TestFunction` + - `setStructureBlockPos` -> `setTestBlockPos` + - `placeStructure` now returns nothing + - `getTestName` - `id`, not one-to-one + - `getStructureBlockPos` -> `getTestBlockPos` + - `getStructureBlockEntity` -> `getTestInstanceBlockEntity` + - `getStructureName` -> `getStructure` + - `getTestFunction` -> `getTest`, `getTestHolder`, not one-to-one + - `getOrCalculateNorthwestCorner`, `setNorthwestCorner` are removed + - `fail` now takes in a `Component` or `GameTestException` instead of a `Throwable` + - `getError` now returns a `GameTestException` instead of a `Throwable` + - `GameTestInstance` - Defines a test to run. + - `GameTestInstances` - Contains all registered tests. + - `GameTestMainUtil` - A utility for running the game test server. + - `GameTestRegistry` class is removed + - `GameTestSequence` + - `tickAndContinue`, `tickAndFailIfNotComplete` now take in an integer for the tick instead of a long + - `thenFail` now takes in a supplied `GameTestException` instead of a `Throwable` + - `GameTestServer#create` now takes in an optional string and boolean instead of the collection of test functions and the starting position + - `GeneratedTest` - A object holding the test to run for the given environment and the function to apply + - `GameTestTicker$State` - An enum containing what state the game test ticker is currently executing. + - `GameTestTimeoutException` now extends `GameTestException` + - `ReportGameListener#spawnBeacon` is removed + - `StructureBlockPosFinder` -> `TestPosFinder` + - `StructureUtils` + - `testStructuresDir` is now a path + - `getStructureBounds`, `getStructureBoundingBox`, `getStructureOrigin`, `addCommandBlockAndButtonToStartTest` are removed + - `createNewEmptyStructureBlock` -> `createNewEmptyTest`, not one-to-one + - `getStartCorner`, `prepareTestStructure`, `encaseStructure`, `removeBarriers` are removed + - `findStructureBlockContainingPos` -> `findTestContainingPos` + - `findNearestStructureBlock` -> `findNearestTest` + - `findStructureByTestFunction`, `createStructureBlock` are removed + - `findStructureBlocks` -> `findTestBlocks` + - `lookedAtStructureBlockPos` -> `lookedAtTestPos` + - `TestClassNameArgument` is removed + - `TestEnvironmentDefinition` - Defines the environment that the test is run on by setting the data on the level appropriately. + - `TestFinder` no longer contains a generic for the context + - `$Builder#allTests`, `allTestsInClass`, `locateByName` are removed + - `$Builder#byArgument` -> `byResourceSelection` + - `TestFunction` -> `TestData`, not one-to-one + - `TestFunctionArgument` -> `net.minecraft.commands.arguments.ResourceSelectorArgument` + - `TestFunctionFinder` -> `TestInstanceFinder` + - `TestFunctionLoader` - Holds the list of test functions to load and run. + - `UnknownGameTestException` - An exception that is thrown when the error of the game test is unknown. +- `net.minecraft.network.protocol.game` + - `ClientboundTestInstanceBlockState` - A packet sent to the client containing the status of a test along with its size. + - `ServerboundSetTestBlockPacket` - A packet sent to the server to set the information within the test block to run. + - `ServerboundTestInstanceBlockActionPacket` - A packet sent to the server to set up the test instance within the test block. +- `net.minecraft.world.entity.player.Player` + - `openTestBlock` - Opens a test block. + - `openTestInstanceBlock` - Opens a test block for a game test instance. +- `net.minecraft.world.level.block` + - `TestBlock` - A block used for running game tests. + - `TestInstanceBlock` - A block used for managing a single game test. +- `net.minecraft.world.level.block.entity` + - `BeaconBeamOwner` - An interface that represents a block entity with a beacon beam. + - `BeaconBlockEntity` now implements `BeaconBeamOwner` + - `BeaconBeamSection` -> `BeaconBeamOwner$Section` + - `BoundingBoxRenderable` - An interface that represents a block entity that can render an arbitrarily-sized bounding box. + - `StructureBlockEntity` now implements `BoundingBoxRenderable` + - `TestBlockEntity` - A block entity used for running game tests. + - `TestInstanceBlockEntity` - A block entity used for managing a single game test. +- `net.minecraft.world.level.block.state.properties.TestBlockMode` - A property for representing the current state of the game tests associated with a test block. + +## Data Component Getters + +The data component system can now be represented on arbitrary objects through the use of the `DataComponentGetter`. As the name implies, the getter is responsible for getting the component from the associated type key. Both block entities and entities use the `DataComponentGetter` to allow querying the internal data, such as variant information or custom names. They both also have methods for collecting the data components from another holder (via `applyImplicitComponents` or `applyImplicitComponent`). Block entities also contain a method for collection to another holder via `collectImplicitComponents`. + +### Items + +`ItemSubPredicate`s have been completely replaced with `DataComponentPredicate`s. Each sub predicate has its appropriate analog within the system. + +- `net.minecraft.advancements.critereon.*` -> `net.minecraft.core.component.predicates.*` + - `ItemAttributeModifiersPredicate` -> `AttributeModifiersPredicate` + - `ItemBundlePredicate` -> `BundlePredicate` + - `ItemContainerPredicate` -> `ContainerPredicate` + - `ItemCustomDataPredicate` -> `CustomDataPredicate` + - `ItemDamagePredicate` -> `DamagePredicate` + - `ItemEnchantmentsPredicate` -> `EnchantmentsPredicate` + - `ItemFireworkExplosionPredicate` -> `FireworkExplosionPredicate` + - `ItemFireworksPredicate` -> `FireworksPredicate` + - `ItemJukeboxPlayablePredicate` -> `JukeboxPlayablePredicate` + - `ItemPotionsPredicate` -> `PotionsPredicate` + - `ItemSubPredicate` -> `DataComponentPredicate`, not one-to-one + - `SINGLE_STREAM_CODEC` + - `ItemSubPredicates` -> `DataComponentPredicates`, not one-to-one + - `ItemTrimPredicate` -> `TrimPredicate` + - `ItemWritableBookPredicate` -> `WritableBookPredicate` + - `ItemWrittenBookPredicate` -> `WrittenBookPredicate` +- `net.minecraft.advancements.critereon` + - `BlockPredicate` now takes in a `DataComponentMatchers` for matching any delegated component data + - `DataComponentMatchers` - A predicate that operates on a `DataComponentGetter`, matching any exact and partial component data on the provider. + - `EntityPredicate` now takes in a `DataComponentMatchers` instead of a `Optional` + - `ItemPredicate` now takes in a `DataComponentMatchers` for matching any delegated component data + - `NbtPredicate#matches` now takes in a `DataComponentGetter` instead of an `ItemStack` + - `SingleComponentItemPredicate` now implements `DataComponentPredicate` instead of `ItemSubPredicate` + - `matches(ItemStack, T)` -> `matches(T)` +- `net.minecraft.core.component` + - `DataComponentPatch` + - `DELIMITED_STREAM_CODEC` + - `$CodecGetter` - Gets the codec for a given component type. + - `DataComponentPredicate` -> `DataComponentExactPredicate` + - `isEmpty` - Checks if the expected components list within the predicate is empty. +- `net.minecraft.core.registries.Registries#ITEM_SUB_PREDICATE_TYPE` -> `DATA_COMPONENT_PREDICATE_TYPE`, not one-to-one +- `net.minecraft.world.item.AdventureModePredicate` no longer takes in a boolean to show in tooltip +- `net.minecraft.world.item` + - `BannerItem#appendHoverTextFromBannerBlockEntityTag` is removed + - `Item#appendHoverText(ItemStack, Item.TooltipContext, List, TooltipFlag)` -> `appendHoverText(ItemStack, Item.TooltipContext, TooltipDisplay, Consumer, TooltipFlag)`, now deprecated + - `ItemStack` + - `addToTooltip` is now public + - `addDetailsToTooltip` - Appends the component details of an item to the tooltip. + - `JukeboxPlayable#showInTooltip` is removed +- `net.minecraft.world.item.component` + - `BlockItemStateProperties` now implements `TooltipProvider` + - `ChargedProjectiles` now implements `TooltipProvider` + - `CustomData#itemMatcher` is removed + - `DyedItemColor#showInTooltip` is removed + - `FireworkExplosion#addShapeNameTooltip` is removed + - `ItemAttributeModifiers#showInTooltip` is removed + - `ItemContainerContents` now implements `TooltipProvider` + - `SeededContainerLoot` now implements `TooltipProvider` + - `TooltipDisplay` - A component that handles what should be hidden within an item's tooltip. + - `TooltipProvider#addToTooltip` now takes in a `DataComponentGetter` +- `net.minecraft.world.item.enchantment.ItemEnchantments#showInTooltip` is removed +- `net.minecraft.world.item.equipment.trim.ArmorTrim#showInTooltip` is removed +- `net.minecraft.world.item.trading.ItemCost` now takes in a `DataComponentExactPredicate` instead of a `DataComponentPredicate` +- `net.minecraft.world.level.block.Block#appendHoverText` is removed +- `net.minecraft.world.level.block.entity` + - `BannerPatternLayers` now implements `TooltipProvider` + - `PotDecorations` now implements `TooltipProvider` +- `net.minecraft.world.level.saveddata.maps.MapId` now implements `TooltipProvider` + +### Entities + +Some `EntitySubPredicate`s for entity variants have been transformed into data components stored on the held item due to a recent change on `EntityPredicate` now taking in a `DataComponentExactPredicate` for matching the slots on an entity. + +- `net.minecraft.advancements.critereon` + - `EntityPredicate` now takes in a `DataComponentExactPredicate` to match the equipment slots checked + - `EntitySubPredicate` + - `AXOLTOL` -> `DataComponents#AXOLOTL_VARIANT` + - `FOX` -> `DataComponents#FOX_VARIANT` + - `MOOSHROOM` -> `DataComponents#MOOSHROOM_VARIANT` + - `RABBIT` -> `DataComponents#RABBIT_VARIANT` + - `HORSE` -> `DataComponents#HORSE_VARIANT` + - `LLAMA` -> `DataComponents#LLAMA_VARIANT` + - `VILLAGER` -> `DataComponents#VILLAGER_VARIANT` + - `PARROT` -> `DataComponents#PARROT_VARIANT` + - `SALMON` -> `DataComponents#SALMON_SIZE` + - `TROPICAL_FISH` -> `DataComponents#TROPICAL_FISH_PATTERN`, `TROPICAL_FISH_BASE_COLOR`, `TROPICAL_FISH_PATTERN_COLOR` + - `PAINTING` -> `DataComponents#PAINTING_VARIANT` + - `CAT` -> `DataComponents#CAT_VARIANT`, `CAT_COLLAR` + - `FROG` -> `DataComponents#FROG_VARIANT` + - `WOLF` -> `DataComponents#WOLF_VARIANT`, `WOLF_COLLAR` + - `PIG` -> `DataComponents#PIG_VARIANT` + - `register` with variant subpredicates have been removed + - `catVariant`, `frogVariant`, `wolfVariant` are removed + - `$EntityHolderVariantPredicateType`, `$EntityVariantPredicateType` are removed + - `SheepPredicate` no longer takes in the `DyeColor` +- `net.minecraft.client.renderer.entity.state.TropicalFishRenderState#variant` -> `pattern` +- `net.minecraft.core.component` + - `DataComponentGetter` - A getter that obtains data components from some object. + - `DataComponentHolder`, `DataComponentMap` now extends `DataComponentGetter` + - `DataComponentExactPredicate` is now a predicate of a `DataComponentGetter` + - `expect` - A predicate that expects a certain value for a data component. + - `test(DataComponentHolder)` is removed + - `DataComponents` + - `SHEEP_COLOR` - The dye color of a sheep. + - `SHULKER_COLOR` - The dye color of a shulker (box). + - `COW_VARIANT` - The variant of a cow. + - `CHICKEN_VARIANT` - The variant of a chicken. + - `WOLF_SOUND_VARIANT` - The sounds played by a wolf. +- `net.minecraft.world.entity` + - `Entity` now implements `DataComponentGetter` + - `applyImplicitComponents` - Applies the components from the getter onto the entity. This should be overriden by the modder. + - `applyComponentsFromItemStack` - Applies the components from the stack onto the entity. + - `castComponentValue` - Casts the type of the object to the component type. + - `setComponent` - Sets the component data onto the entity. + - `applyImplicitComponent` - Applies the component data to the entity. This should be overriden by the modder. + - `applyImplicitComponentIfPresent` - Applies the component if it is present on the getter. + - `EntityType#appendCustomNameConfig` -> `appendComponentsConfig` + - `VariantHolder` interface is removed + - As such, all `setVariant` methods on relevant entities are private while the associated data can also be obtained from the `DataComponentGetter` +- `net.minecraft.world.entity.animal` + - `CatVariant#CODEC` + - `Fox$Variant#STREAM_CODEC` + - `FrogVariant#CODEC` + - `MushroomCow$Variant#STREAM_CODEC` + - `Parrot$Variant#STREAM_CODEC` + - `Rabbit$Variant#STREAM_CODEC` + - `Salmon$Variant#STREAM_CODEC` + - `TropicalFish` + - `getVariant` -> `getPattern` + - `$Pattern` now implements `TooltipProvider` + - `Wolf` -> `.wolf.Wolf` + - `WolfVariant` -> `.wolf.WolfVariant`, now a record, taking in an `$AssetInfo` and a `SpawnPrioritySelectors` + - `WolfVariants` -> `.wolf.WolfVariants` +- `net.minecraft.world.entity.animal.axolotl.Axolotl$Variant#STREAM_CODEC` +- `net.minecraft.world.entity.animal.horse` + - `Llama$Variant#STREAM_CODEC` + - `Variant#STREAM_CODEC` +- `net.minecraft.world.entity.animal.wolf` + - `WolfSoundVariant` - The sounds played by a wolf. + - `WolfSoundVariants` - All vanilla wolf sound variants. +- `net.minecraft.world.entity.decoration.Painting` + - `VARIANT_MAP_CODEC` is removed + - `VARIANT_CODEC` is now private +- `net.minecraft.world.entity.npc.VillagerDataHolder#getVariant`, `setVariant` are removed +- `net.minecraft.world.entity.variant.VariantUtils`- A utility for getting the variant info of an entity. +- `net.minecraft.world.item` + - `ItemStack#copyFrom` - Copies the component from the getter. + - `MobBucketItem#VARIANT_FIELD_CODEC` -> `TropicalFish$Pattern#STREAM_CODEC` +- `net.minecraft.world.level.block.entity.BlockEntity#applyImplicitComponents` now takes in a `DataComponentGetter` + - `$DataComponentInput` -> `DataComponentGetter` +- `net.minecraft.world.level.Spawner` methods now takes in a `CustomData` instead of the `ItemStack` itself + +#### Spawn Conditions + +To allow entities to spawn variants randomly but within given conditions, a new registry called `SPAWN_CONDITION_TYPE` was added. These take in `SpawnCondition`s: a selector that acts like a predicate to take in the context to see whether the given variant can spawn there. All of the variants are thrown into a list and then ordered based on the selected priorty stored in the `SpawnProritySelectors`. Those with a higher priority will be checked first, with multiple of the same priority selected in the order they are provided. Then, all variants on the same priority level where a condition has been met is selected at random. + +```json5 +// For some object where there are spawn conditions +[ + { + // The spawn condition being checked + "condition": { + "type": "minecraft:biome", + // Will check that the biome the variant is attempting to spawn in is in the forest + "biomes": "#minecraft:is_forest" + }, + // Will check this condition first + "priority": 1 + }, + { + // States that the condition will always be true + "priority": 0 + } +] +``` + +- `net.minecraft.core.registries.Registries#SPAWN_CONDITION_TYPE` +- `net.minecraft.world.entity.variant` + - `BiomeCheck` - A spawn condition that checks whether the entity is in one of the given biomes. + - `MoonBrightnessCheck` - A spawn condition that checks the brightness of the moon. + - `PriorityProvider` - An interface which orders the condition selectors based on some priority integer. + - `SpawnCondition` - Checks whether an entity can spawn at this location. + - `SpawnConditions` - The available spawn conditions to choose from. + - `SpawnContext` - An object holding the current position, level, and biome the entity is being spawned within. + - `SpawnPrioritySelectors` - A list of spawn conditions to check against the entity. Used to select a random variant to spawn in a given location. + - `StructureCheck` - A spawn condition that checks whether the entity is within a structure. + +#### Variant Datapack Registries + +Frog, cat, cow, chicken, pig, and wolf, and wolf sound variants are datapack registry objects, meaning that most references now need to be referred to through the `RegistryAccess` or `HolderLookup$Provider` instance. + +For a frog, cat, or wolf: + +```json5 +// A file located at: +// - `data/examplemod/frog_variant/example_frog.json` +// - `data/examplemod/cat_variant/example_cat.json` +// - `data/examplemod/wolf_variant/example_wolf.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/cat/example_cat.png` + "asset_id": "examplemod:entity/cat/example_cat", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +For a pig, cow, or chicken: +```json5 +// A file located at: +// - `data/examplemod/pig_variant/example_pig.json` +// - `data/examplemod/cow_variant/example_cow.json` +// - `data/examplemod/chicken_variant/example_chicken.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/pig/example_pig.png` + "asset_id": "examplemod:entity/pig/example_pig", + // Defines the `PigVariant$ModelType` that's used to select what entity model to render the pig variant with + "model": "cold", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +For a wolf sound variant: +```json5 +// A file located at: +// - `data/examplemod/wolf_sound_variant/example_wolf_sound.json`` +{ + // The registry name of the sound event to play randomly on idle + "ambient_sound": "minecraft:entity.wolf.ambient", + // The registry name of the sound event to play when killed + "death_sound": "minecraft:entity.wolf.death", + // The registry name of the sound event to play randomly when angry on idle + "growl_sound": "minecraft:entity.wolf.growl", + // The registry name of the sound event to play when hurt + "hurt_sound": "minecraft:entity.wolf.hurt", + // The registry name of the sound event to play randomly + // 1/3 of the time on idle when health is max + "pant_sound": "minecraft:entity.wolf.pant", + // The registry name of the sound event to play randomly + // 1/3 of the time on idle when health is below max + "whine_sound": "minecraft:entity.wolf.whine" +} +``` + +#### Client Assets + +Raw `ResourceLocation`s within client-facing files for identifiers or textures are being replaced with objects defining an idenfitier along with a potential texture path. There are three main objects to be aware of: `ClientAsset`, `ModelAndTexture`, and `MaterialAssetGroup`. + +`ClientAsset` is an id/texture pair used to point to a texture location. By default, the texture path is contructed from the id, with the path prefixed with `textures` and suffixed with the PNG extension. + +`ModelAndTexture` is a object/client asset pair used when a renderer should select between multiple models. Usually, the renderer creates a map of the object type to the model, and the object provided to the `ModelAndTexture` is used as a lookup into the map. + +`MaterialAssetGroup` is a handler for rendering an equipment asset with some trim material. It takes in the base texture used to overlay onto the armor along with any overrides for a given equipment asset. + +- `net.minecraft.advancements.DisplayInfo` now takes in a `ClientAsset` instead of only a `ResourceLocation` for the background texture +- `net.minecraft.client.model` + - `AdultAndBabyModelPair` - Holds two `Model` instances that represents the adult and baby of some entity. + - `ChickenModel#createBaseChickenModel` - Creates the default chicken model. + - `ColdChickenModel` - A variant model for a chicken in cold temperatures. + - `ColdCowModel` - A variant model for a cow in cold temperatures. + - `ColdPigModel` - A variant model for a big in cold temperatures. + - `CowModel#createBaseCowModel` - Creates the base model for a cow. + - `PigModel#createBasePigModel` - Creates the default pig model. + - `WarmCowModel` - A variant model for a cow in warm temperatures. +- `net.minecraft.client.renderer.entity` + - `ChickenRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` + - `CowRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` + - `PigRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` +- `net.minecraft.client.renderer.entity.layers.SheepWoolUndercoatLayer` - A layer that renders the wool undercoat of a sheep. +- `net.minecraft.client.renderer.entity.state` + - `CowRenderState` - A render state for a cow entity. + - `SheepRenderState` + - `getWoolColor` - Returns the integer color of the sheep wool. + - `isJebSheep` - Returns whether the sheep's name contains the `jeb_` prefix. +- `net.minecraft.core.ClientAsset` - An object that holds an identifier and a path to some texture. +- `net.minecraft.data.loot.EntityLootSubProvider#killedByFrogVariant` now takes in a `HolderGetter` for the `FrogVariant` +- `net.minecraft.data.tags.CatVariantTagsProvider` class is removed +- `net.minecraft.tags.CatVariantTags` class is removed +- `net.minecraft.world.entity.animal` + - `AbstractCow` - An abstract animal that represents a cow. + - `Chicken#setVariant`, `getVariant` - Handles the variant information of the chicken. + - `ChickenVariant` - A class which defines the common-sideable rendering information and biome spawns of a given chicken. + - `ChickenVariants` - Holds the keys for all vanilla chicken variants. + - `Cow` now extends `AbstractCow`. + - `CowVariant` - A class which defines the common-sideable rendering information and biome spawns of a given cow. + - `CowVariants` - Holds the keys for all vanilla cow variants. + - `CatVariant(ResourceLocation)` -> `CatVariant(ClientAsset, SpawnPrioritySelectors)` + - `CatVariants` - Holds the keys for all vanilla cat variants. + - `FrogVariant` -> `.frog.FrogVariant` + - `FrogVariant(ResourceLocation)` -> `FrogVariant(ClientAsset, SpawnPrioritySelectors)` + - `MushroomCow` now extends `AbstractCow` + - `PigVariant` - A class which defines the common-sideable rendering information and biome spawns of a given pig. + - `TemperatureVariants` - An interface which holds the `ResourceLocation`s that indicate an entity within a different temperature. +- `net.minecraft.world.entity.variant.ModelAndTexture` - Defines a model with its associated texture. +- `net.minecraft.world.item.equipment.trim` + - `MaterialAssetGroup` - An asset defines some base and the permutations based on the equipment worn. + - `TrimMaterial` now takes in a `MaterialAssetGroup` instead of the raw base and overrides + +## Tags and Parsing + +Tags have received a rewrite, removing any direct references to types while also sealing and finalizing related classes. Getting a value from the tag now returns an `Optional`-wrapped entry, unless you call one of the `get*Or`, where you specify the default value. Objects, on the other hand, do not take in a default, instead returning an empty variant of the desired tag. + +```java +// For some `CompoundTag` tag + +// Read a value +Optional value1 = tag.getInt("value1"); +int value1Raw = tag.getIntOr("value1", 0); + +// Reading another object +Optional childTag = tag.getCompound("childTag"); +CompoundTag childTagRaw = tag.getCopmoundOrEmpty("childTag"); +``` + +### Writing with Codecs + +`CompoundTag`s now have methods to write and read using a `Codec` or `MapCodec`. For a `Codec`, it will store the serialized data inside the key specified. For a `MapCodec`, it will merge the fields onto the top level tag. + +```java +// For some Codec CODEC and MapCodec MAP_CODEC +// We will also have ExampleObject example +CompoundTag tag = new CompoundTag(); + +// For a codec +tag.store("example_key", CODEC, example); +Optional fromCodec = tag.read("example_key", CODEC); + +// For a map codec +tag.store(MAP_CODEC, example); +Optional fromMapCodec = tag.read(MAP_CODEC); +``` + +### Command Parsers + +The packrat parser has been updated with new rules and systems, allowing commands to have parser-based arguments. This comes from the `CommandArgumentParser`, which parses some grammar to return the desired object. The parser is then consumed by the `ParserBasedArgument`, where it attempts to parse a string and build any suggestions based on what you're currently typing. These are both handled through the `Grammar` class, which implements `CommandArgumentParser`, constructed using a combination of atoms, dictionaries, rules, and terms. + +- `net.minecraft.commands.ParserUtils#parseJson` +- `net.minecraft.commands.arguments` + - `ComponentArgument` now extends `ParserBasedArgument` + - `NbtTagArgument` now extends `ParserBasedArgument` + - `StyleArgument` now extends `ParserBasedArgument` +- `net.minecraft.commands.arguments.item.ItemPredicateArgument` now extends `ParserBasedArgument` +- `net.minecraft.nbt` + - `ByteArrayTag`, now final, no longer takes in a list object + - `ByteTag` is now a record + - `CollectionTag` is now a sealed interface, no longer extending `AbstractList` or has a generic + - `set`, `add` is removed + - `remove` now returns a `Tag` + - `get` - Returns the tag at the specified index. + - `getElementType` is removed + - `size` - Returns the size of the collection. + - `isEmpty` - Returns whether the collection has no elements. + - `stream` - Streams the elements of the collection. + - `CompoundTag` is now final + - `store` - Writes a codec or map codec to the tag. + - `read` - Reads the codec or map codec-encoded value from the tag. + - `getFloatOrDefault`, `getIntOrDefault`, `getLongOrDefault` - Gets the value with the associated key, or the default if not present or an exception is thrown. + - `storeNullable` - When not null, uses the codec to write the value to the tag. + - `putUUID`, `getUUID`, `hasUUID` is removed + - `getAllKeys` -> `keySet` + - `values`, `forEach` - Implements the standard map operations. + - `putByteArray`, `putIntArray` with list objects are removed + - `getTagType` is removed + - `contains` is removed + - `get*`, `get*Or` - Returns an optional wrapped object for the key, or the default value specified is using the `Or` methods. + - `DoubleTag` is now a record + - `EndTag` is now a record + - `FloatTag` is now a record + - `IntArrayTag`, now final, no longer takes in a list object + - `IntTag` is now a record + - `ListTag`, now final, extends `AbstractList` + - `addAndUnwrap` - Adds the tag to the list where, if a compound with one element, adds the inner tag instead. + - `get*`, `get*Or` - Returns an optional wrapped object for the key, or the default value specified is using the `Or` methods. + - `compoundStream` - Returns a flat map of all `CompoundTag`s within the list. + - `LongArrayTag`, now final, no longer takes in a list object + - `LongTag` is now a record + - `NbtIo#readUnnamedTag` is now public, visible for testing + - `NbtOps` now has a private constructor + - `NbtUtils` + - `getDataVersion` now has an overload that takes in a `Dynamic` + - `createUUID`, `loadUUID` is removed + - `readBlockPos`, `writeBlockPos` is removed + - `NumericTag` is now a sealed interface that implements `PrimitiveTag` + - `getAsLong` -> `longValue` + - `getAsInt` -> `intValue` + - `getAsShort` -> `shortValue` + - `getAsByte` -> `byteValue` + - `getAsDouble` -> `doubleValue` + - `getAsFloat` -> `floatValue` + - `getAsNumber` -> `box` + - `as*` - Returns an optional wrapped of the numeric value. + - `PrimitiveTag` - A sealed interface that represents the tag data as being a primitive object. + - `ShortTag` is now a record + - `SnbtGrammar` - A parser creater for stringified NBTs. + - `SnbtOperations` - A helper that contains the built in operations for parsing some value. + - `StringTag` is now a record + - `StringTagVisitor` + - `visit` -> `build`, not one-to-one + - `handleEscape` -> `handleKeyEscape`, now private + - `Tag` is now a sealed interface + - `as*` -> Attempts to cast the tag as one of its subtypes, returning an empty optional on failure. + - `getAsString` -> `asString`, not one-to-one + - `TagParser` now holds a generic referncing the type of the intermediate object to parse to + - The constructor now takes in a grammar, or `create` constructs the grammar from a `DynamicOps` + - `AS_CODEC` -> `FLATTENED_CODEC` + - `parseTag` -> `parseCompoundFully` or `parseCompoundAsArgument` + - Additional methods such as `parseFully`, `parseAsArgument` parse to some intermediary object + - These are all instance methods + - `readKey`, `readTypedValue` is removed + - `TagType#isValue` is removed +- `net.minecraft.util.parsing.packrat` + - `CachedParseState` - A parse state that caches the parsed positions and controls when reading. + - `Control#hasCut` - Returns whether the control flow for the grammar has a cut for the reading object. + - `DelayedException` - An interface that creates an exception to throw. + - `Dictionary` + - `put` now returns a `NamedRule` + - `put(Atom, Term, Rule.RuleAction)` -> `putComplex` + - `get` -> `getOtThrow`, not one-to-one + - `forward` - Gets or writes the term to the dictionary. + - `namedWithAlias` - Creates a new reference to the named atom or its alias. + - `ErrorCollector$Nop` - A error collector that does nothing. + - `NamedRule` - A rule that has an associated name. + - `ParseState` is now an interface + - Caching logic has moved to `CachedParseState` + - `scope` - Returns the current scope being analyzed within the parsing object. + - `parse` now takes in a `NamedRule` instead of an `Atom` + - `acquireControl`, `releaseControl` - Handles obtaining the `Control` used during parsing. + - `silent` - Returns a `ParseState` that does not collect any errors. + - `Rule` + - `parse`, `$RuleAction#run` now returns a nullable value rather than an optional + - `SimpleRuleAction` now implements `$RuleAction` + - `Scope#pushFrame`, `popFrame`, `splitFrame`, `clearFrameValues`, `mergeFrame` - Handles the management of parsing terms into sections called frames. + - `Term` + - `named` -> `Dictionary#named`, not one-to-one + - `repeated`, `repeatedWithTrailingSeparator`, `repeatedWithoutTrailingSeparator` - Handles terms similar to varargs that are repeated and sticks them into a list. + - `positiveLookahead`, `negativeLookahead` - Handles a term that matches information based on what is following. + - `fail` - Mark a term as having failed during parsing. +- `net.minecraft.util.parsing.packrat.commands` + - `CommandArgumentParser` - Parses a string into an argument for use with a command. + - `Grammar` now takes in a `NamedRule` for the top rather than an `Atom` + - `GreedyPatternParseRule` - A rule that attempts to match the provided pattern greedily, assuming that if a region matches, that the matched group can be obtained. + - `GreedyPredicateParseRule` - A rule that attempts to match the accepted characters greedily, making sure that the string reaches a minimum size. + - `NumberRunParseRule` - A rule that attempts to parse a number from the string. + - `ParserBasedArgument` - A command argument that uses a parser to extract the value. + - `ResourceLookupRule` now takes in a `NamedRule` for the id parser rather than an `Atom` + - `StringReaderParserState` now extends `CachedParsedState` + - The `Dictoionary` is no longer taken in + - `StringReaderTerms#characters` - Matches multiple characters in a string, usually for catching both the lowercase and uppercase variant. + - `UnquotedStringParseRule` - A rule that reads part of the sequence as an unquoted string, making sure it reaches a minimum size. + +## Saved Data, now with Types + +`SavedData` has been reworked to abstract most of its save and loading logic into a separate `SavedDataType`. This means that the `save` override and additional `load` and `factory` methods are now handled within the `SavedDataType` itself. + +To construct a `SavedDataType`, you need to pass in four paramters. First is the string identifier, used to resolve the `.dat` file holding your information. This must be a vaild path. Then there is the constructor, which takes in the `SavedData$Context` to return an instance of your data object when no information is present. Following that is the codec, which takes in the `SavedData$Context` and returns a `Codec` to read and write your saved data. Finally, there is the `DataFixTypes` used for data fixers. As this is a static enum, you will either need to inject into the enum itself, if you plan on using vanilla data fixers, or patch out the `update` call within `DimensionDataStorage#readTagFromDisk` to pass in a null value. + +```java +// Our saved data instance +public class ExampleSavedData extends SavedData { + + // The saved data type + public static final SavedDataType TYPE = new SavedDataType<>( + // Best to preface the identifier with your mod id followed by an underscore + // Slashes will throw an error as the folders are not present + // Will resolve to `saves//data/examplemod_example.dat` + "examplemod_example", + // Constructor for the new instance + ExampleSavedData::new, + // Codec factory to encode and decode the data + ctx -> RecordCodecBuilder.create(instance -> instance.group( + RecordCodecBuilder.point(ctx.levelOrThrow()), + Codec.INT.fieldOf("value1").forGetter(data -> data.value1), + Codec.BOOL.fieldOf("value2").forGetter(data -> data.value2) + ).apply(instance, ExampleSavedData::new)); + ); + + private final ServerLevel level; + private final int value1; + private final boolean value2; + + + // For the new instance + private ExampleSavedData(ServerLevel.Context ctx) { + this(ctx.levelOrThrow(), 0, false); + } + + // For the codec + // The constructors don't need to be public if not using `DimensionDataStorage#set` + private ExampleSavedData(ServerLevel level, int value1, boolean value2) { + this.level = level; + this.value1 = value1; + this.value2 = value2; + } + + // Other methods here +} + +// With access to the DimensionDataStorage storage +ExampleSavedData data = storage.computeIfAbsent(ExampleSavedData.TYPE); +``` + +- `net.minecraft.server.ServerScoreboard` + - `dataFactory` is removed + - `createData` now takes in a `$Packed` instance +- `net.minecraft.world.RandomSequences` + - `factory`, `load` is removed + - `codec` - Constructs a codec for the random sequence given the current world seed. +- `net.minecraft.world.entity.raid.Raids` no longer takes in anything + - `getType` - Returns the saved data type based on the current dimension. + - `factory` is removed + - `tick` now takes in the `ServerLevel` + - `getId` - Gets the identifier for the raid instance. + - `canJoinRaid` no longer takes in the raid instance + - `load` no longer takes in the `ServerLevel` +- `net.minecraft.world.level.levelgen.structure.structures.StructureFeatureIndexSavedData` + - `factory`, `load` is removed + - `type` - Returns the feature saved data type with its specified id. +- `net.minecraft.world.level.saveddata` + - `SavedData` + - `save` is removed + - `$Factory` record is removed + - `$Context` - Holds the current context that the saved data is being written to. + - `SavedDataType` - A record that represents the type of the saved data, including information on how to construct, save, and load the data. +- `net.minecraft.world.level.saveddata.maps` + - `MapIndex` now has a constructor to take in the last map id + - `factory`, `load` is removed + - `getFreeAuxValueForMap` -> `getNextMapId` + - `MapItemSavedData` + - `factory`, `load` is removed + - `type` - Returns the saved data type using the map id's key. +- `net.minecraft.world.level.storage.DimensionDataStorage` now takes in a `SavedData$Context` + - `computeIfAbsent`, `get` now take in only the `SavedDataType` + - `set` now takes in the `SavedDataType` along with the data instance +- `net.minecraft.world.scores.ScoreboardSaveData` + - `load` -> `loadFrom` + - `pack` - Packs the data into its saved data format. + - `$Packed` - Represents the serializable packed data. + +## Render Pipeline Rework + +Rendering an object to the screen, whether through a shader or a `RenderType`, has been fully or partially reworked, depending on what systems you were using previously. As such, a lot of things need to be reexplained, which a more in-depth look will be below. However, for the people who don't care, here's the TL;DR. + +First, shader JSONs no longer exist. This is replaced by a `RenderPipeline`, which is effectively an in-code substitute. Second, the `RenderPipeline`s forcibly make most abtrarily values into objects. For example, instead of storing the blend function mode id, you store a `BlendFunction` object. Similarly, you no longer store or setup the direct texture objects, but instead manage it through a `GpuTexture`. Finally, the `VertexBuffer` can either draw to the framebuffer by directly passing in the `RenderPipeline`, updating any necessary uniforms in the consumer, or by passing in the `RenderType`. + +Now, for those who need the details, let's jump into them. + +### Abstracting Open GL + +As many are aware, Minecraft has been abstracting away their OpenGL calls and constants, and this release is no different. All of the calls to GL codes, except `BufferUsage`, have been moved out of object references, to be obtained typically by calling `GlConst$toGl`. However, with all of the other rendering reworks, there are numerous changes and complexities that require learning an entirely new system, assuming you're not using `RenderType`s. + +Starting from the top, all calls to the underlying render system goes through `GpuDevice`, an interface that acts like a general implementation of a render library like OpenGL or Vulkan. The device is responsible for creating buffers and textures, executing whatever commands are desired. Getting the current `GpuDevice` can be accessed through the `RenderSystem` via `getDevice` like so: + +```java +GpuDevice device = RenderSystem.getDevice(); +``` + +The `GpuDevice` can the create either buffers with the desired data or a texture containing information on what to render using `createBuffer` and `createTexture`, respectively. Just for redundancy, buffers hold the vertex data while textures hold the texture (color and depth) data. You should generally cache the buffer or texture object for later use with any additional data updated as needed. For reference, buffers are typically created by using a `BufferBuilder` with a `ByteBufferBuilder` to build the `MeshData` first, before passing that into `createBuffer`. + +With the desired buffers and textures set up, how do we actually modify render them to the screen? Well, this is handled through the `CommandEncoder`, which can also be optained from the device via `GpuDevice#createCommandEncoder`. The encoder contain the familiar read and write methods along with a few extra to clear texture to a given color or simply blit the the texture immediately to the screen (`presentTexture`). However, the most important method here is `createRenderPass`. This takes in the `GpuTexture` to draw to the screen along with a default ARGB color for the background. Additionally, it can take in a depth texture as well. This should be created using a try with resources block like so: + +```java +// We will assume you have constructed a `GpuTexture` texture for the color data +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(this.texture, OptionalInt.of(0xFFFFFFFF))) { + // Setup things here + +} +``` + +Within the `RenderPass`, you can set the `RenderPipeline` to use, which defines the associated shaders, bind any samplers from other targets or set uniforms, scissor a part of a screen to render, and set the vertex and index buffers used to define the vertices to render. Finally, everything can be drawn to the screen using one of the `draw` methods, providing the starting index and the vertex count. + +```java +// If the buffers/textures are not created or cached, create them here +// Any methods ran from `CommandEncoder` cannot be run while a render pass is open +RenderSystem.AutoStorageIndexBuffer indices = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); +GpuBuffer vertexBuffer = RenderSystem.getQuadVertexBuffer(); +GpuBuffer indexBuffer = indices.getBuffer(6); + +// We will assume you have constructed a `GpuTexture` texture for the color data +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(this.texture, OptionalInt.of(0xFFFFFFFF))) { + + // Set pipeline information along with any samplers and uniforms + pass.setPipeline(EXAMPLE_PIPELINE); + pass.setVertexBuffer(0, vertexBuffer); + pass.setIndexBuffer(indexBuffer, indices.type()); + pass.bindSampler("Sampler0", RenderSystem.getShaderTexture(0)); + + // Then, draw everything to the screen + // In this example, the buffer just contains a single quad + // For those unaware, the vertex count is 6 as a quad is made up of 2 triangles, so 2 vertices overlap + pass.drawIndexed(0, 6); +} +``` + +However, unless you need such fine control, it is recommended to use a `RenderType` with the `MultiBufferSource` when necessary as that sets up most things for you. + +### Object References + +Most raw references to GL codes used for determining the mode and handling the texture have been replaced with objects. As the TL;DR previously mentioned, these are stored typically as some sort of enum or object that can then be resolved to their GL counterparts. Some objects contain their reference identifier directly, like `BlendFunction`. Others are simply placeholders that are resolved in their appropriate location, like `DepthTestFunction` whose enum values are converted via `RenderPipeline#toGl`. + +However, the biggest change is the addition of the `GpuTexture`. This is responsible for managing anything to do with creating, writing, and releasing a texture written to some buffer. At initialization, the texture is created and bound, with any necessary parameters set for mipmaps and texture formats. These `GpuTexture`s are stored and referenced everywhere, from the depth and color targets for a `RenderTarget` to the texture backing a `TextureAtlas`. Then, once no longer need, the texture is released by calling `#close`. Note that although technically `#bind` can be called again, the texture is already considered deleted and should not be used. + +If, for some reason, you need to use a `GpuTexture`, it's actually quite simple to use. First, you just construct the `GpuTexture` via `GpuDevice#createTexture`. Then, if you need to change any of the addressing or texture mipmap filters, you can apply them whenever before writing. + +```java +public class MyTextureManager { + + private final GpuTexture texture; + + public MyTextureManager() { + this.texture = RenderSystem.getDevice().createTexture( + // The texture name, used for logging and debugging + "Example Texture", + // The format of the texture pixels, can be one of three values that + // Values: (texture internal format, texel data format, texel data type, pixel size) + // - RGBA8 (GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4) + // - RED8 (GL_R8, GL_RED, GL_UNSIGNED_BYTE, 1) + // - DEPTH32 (GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, 4) + TextureFormat.RGBA8, + // Width of the texture + 16, + // Height of the texture + 16, + // The mipmap level and maximum level-of-detail (minimum of 1) + 1 + ); + + // Set the texture mode for the UV component + // Values: + // - REPEAT (GL_REPEAT) + // - CLAMP_TO_EDGE (GL_CLAMP_TO_EDGE) + this.texture.setAddressMode( + // The mode to use for the U component (GL_TEXTURE_WRAP_S) + AddressMode.CLAMP_TO_EDGE, + // The mode to use for the V component (GL_TEXTURE_WRAP_R) + AddressMode.REPEAT + ); + + // Sets the filter functions used for scaling the texture on the screen + // Values (default, for mipmaps): + // - NEAREST (GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR) + // - LINEAR (GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR) + this.texture.setTextureFilter( + // The mode to use for the texture minifying function (GL_TEXTURE_MIN_FILTER) + FilterMode.LINEAR, + // The mode to use for the texture magnifying function (GL_TEXTURE_MAG_FILTER) + FilterMode.NEAREST, + // Whether mipmaps should be used for the minifying function (should have a higher mipmap level than 1 when true) + false + ); + } +} +``` + +Then, whenever you want to upload something to the texture, you call `CommandEncoder#writeToTexture` or `CommandEncoder#copyTextureToTexture`. This either takes in the `NativeImage` to write from or an `IntBuffer` with the texture data and a `NativeImage$Format` to use. + +```java +// Like other buffer/texture modification methods, this must be done outside of a render pass +// We will assume you have some `NativeImage` image to load into the texture +RenderSystem.getDevice().createCommandEncoder().writeToTexture( + // The texture (destination) being written to + this.texture, + // The image (source) being read from + image, + // The mipmap level + 0, + // The starting destination x offset + 0, + // The starting destination y offset + 0, + // The destination width (x size) + 16, + // The desintation height (y size) + 16, + // The starting source x offset + 0, + // The starting source y offset + 0 +) +``` + +Finally, once you're done with the texture, don't forget to release it via `#close` if it's not already handled for you. + +### Render Pipelines + +Previously, a pipeline was constructed using a JSON that contained all metadata from the vertex and fragement shader to their defined values, samplers, and uniforms. However, this has all been replaced with an in-code solution that more localizes some parts of the JSON and some parts that were relegated to the `RenderType`. This is known as a `RenderPipeline`. + +A `RenderPipeline` can be constructed using its builder via `RenderPipeline#builder`. A pipeline can then be built by calling `build`. If you want the shader to be pre-compiled without any additional work, the final pipeline can be passed to `RenderPipeline#register`. However, you can also handle the compilation yourself if more graceful fail states are desired. If you have snippets that are used across multiple pipelines, then a partial pipeline can be built via `$Builder#buildSnippet` and then passed to the constructing pipelines in the `builder` method. + +> The following enums described in the examples have their GL codes provided with them as they have been abstracted away. + +```java +// This assumes that RenderPipeline#register has been made public through some form +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipelines.register( + RenderPipeline.builder() + // The name of the pipeline (required) + .withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example")) + // The location of the vertex shader, relative to 'shaders' (required) + // Points to 'assets/examplemod/shaders/example.vsh' + .withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + // The location of the fragment shader, relative to 'shaders' (required) + // Points to 'assets/examplemod/shaders/example.fsh' + .withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + // The format of the vertices within the shader (required) + .withVertexFormat( + // The vertex format + DefaultVertexFormat.POSITION_TEX_COLOR, + // The mode of the format + VertexFormat.Mode.QUADS + ) + // Adds constants that can be referenced within the shaders + // Can specify a name in addition to an int / float to represent its value + // If no value is specified, then it should be gated with a #ifdef / #endif block + .withShaderDefines("ALPHA_CUTOUT", 0.5) + // Adds the texture sampler2Ds that can be referenced within the shaders + // Typically, the shader textures stored in the `RenderSystem` is referenced via `Sampler0` - `Sampler11` + // - `Sampler0` is usually always present, but these should be set up beforehand + // Additionally, for render targets, `InSampler` is typically present, along with any defined in a postpass + .withSampler("Sampler0") + // Adds uniforms that can be referenced within the shaders + // These are just definitions which are then populated by default or by the caller depending on the scenario + // Defaults can be found in `CompiledShaderProgram#setupUniforms` + .withUniform("ModelOffset", UniformType.VEC3) + // Custom uniforms must be set manually as the vanilla batching system does not support such an operation + .withUniform("CustomUniform", UniformType.INT) + // Sets the depth test functions used rendering objects at varying distances from the camera + // Values: + // - NO_DEPTH_TEST (GL_ALWAYS) + // - EQUAL_DEPTH_TEST (GL_EQUAL) + // - LEQUAL_DEPTH_TEST (GL_LEQUAL) + // - LESS_DEPTH_TEST (GL_LESS) + // - GREATER_DEPTH_TEST (GL_GREATER) + .withDepthTestFunction(DepthTestFunction.LEQUAL_DEPTH_TEST) + // Sets how the polygons should render + // Values: + // - FILL (GL_FILL) + // - WIREFRAME (GL_LINE) + .withPolygonMode(PolygonMode.FILL) + // When true, can cull front or back-facing polygons + .withCull(false) + // Specifies the functions to use when blending two colors with alphas together + // Made up of the `GlStateManager$SourceFactor` and `GlStateManager$DestFactor` + // First two are for RGB, the last two are for alphas + // If nothing is specified, then blending is disabled + .withBlend(BlendFunction.TRANSLUCENT) + // Determines whether to mask writing colors and alpha to the draw buffer + .withColorWrite( + // Mask RGB + false, + // Mask alpha + false + ) + // Determines whether to mask writing values to the depth buffer + .withDepthWrite(false) + // Determines the logical operation to apply when applying an RGBA color to the framebuffer + .withColorLogic(LogicOp.NONE) + // Sets the scale and units used to calculate the depth values for the polygon. + // This takes the place of the polygon offset. + .withDepthBias(0f, 0f) + .build() +); +``` + +From there, the pipeline can either be used directly or through some `RenderType`: + +```java +// This will assume that RenderType#create is made public +public static final RenderType EXAMPLE_RENDER_TYPE = RenderType.create( + // The name of the render type + "examplemod:example", + // The size of the buffer + // Or 4MB + 4194304, + // Whether it effects crumbling that is applied to block entities + false, + // Whether the vertices should be sorted before upload + true, + // The pipeline to use + EXAMPLE_PIPIELINE, + // Any additional composite state settings to apply + RenderType.CompositeState.builder().createCompositeState(RenderType.OutlineProperty.NONE) +); +``` + +The pipeline can then be drawn by creating the `RenderPass` and setting the `RenderPipeline` to use your pipeline. As for the `RenderType`, the associated buffer can be obtained using `MultiBufferSource#getBuffer`. Note that custom uniforms should not be used within `RenderType`s as they cannot be set easily. + +```java +// Since we are using a custom uniform, we must handle it ourselves +// We will assume we have some `GpuTexture` texture to write to + +// Create the render pass to use +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass( + // The GPU color texture to write to + this.texture, + // The clear color in ARGB format + OptionalInt.of(0xFFFFFFFF), + // The depth texture and the clear depth value can also be constructed here + ) +) { + // Add the pipeline and our uniform + pass.setPipeline(EXAMPLE_PIPELINE); + pass.setUniform("CustomUniform", 1); + + // Set any additional sampler and the vertex/index buffers to use + + // Finally, call one of the draw functions + // Takes in the first index and the index count to draw for the vertices + pass.draw(...); +} +``` + +### Post Effects + +Given that the pipeline JSONs have been stripped, this also effects the post effects. The `program` is replaced with directly specifying the `vertex_shader` and the `fragment_shader`. Additionally, uniforms must specify their `type`. + +```json5 +// Before 1.21.5 (for some pass in 'passes') +{ + // Same as before + "inputs": [ /*...*/ ], + "output": "swap", + + // Replaced by 'vertex_shader', 'fragement_shader' + "program": "minecraft:post/box_blur", + + "uniforms": [ + { + "name": "BlurDir", + // Required + "values": [ 1.0, 0.0 ] + }, + { + "name": "Radius", + // Required + "values": [ 0.0 ] + } + ] +} + +// 1.21.1 (for some pass in 'passes') +{ + // Same as before + "inputs": [ /*...*/ ], + "output": "swap", + + // Relative to 'shaders' + // Points to 'assets/minecraft/shaders/post/blur.vsh' + "vertex_shader": "minecraft:post/blur", + // Points to 'assets/minecraft/shaders/post/box_blur.fsh' + "fragment_shader": "minecraft:post/box_blur", + + + "uniforms": [ + { + "name": "BlurDir", + // Specifies the type to use for this uniform + // One of `Uniform$Type`: + // - int + // - ivec3 + // - float + // - vec2 + // - vec3 + // - vec4 + // - matrix4x4 + "type": "vec2", + "values": [ 1.0, 0.0 ] + }, + { + "name": "Radius", + "type": "float" + // Values are no longer required + } + ] +} +``` + +Note that if you do not define a value for a uniform, they still must be specified before processing the `PostChain` by calling `#setUniform` within the `RenderPass` consumer of `PostChain#process`. + +```java +// Assume we already got the `PostChain` post +post.process(Minecraft.getInstance().getMainRenderTarget(), GraphicsResourceAllocator.UNPOOLED, pass -> { + pass.setUniform("Radius", 0.4f); +}); +``` + +- `com.mojang.blaze3d.GpuOutOfMemoryException` - An exception thrown when a texture could not be allocated on the GPU. +- `com.mojang.blaze3d.buffers` + - `BufferType` no longer stores the GL codes, now in `GlConst#toGl` + - `BufferUsage` no longer stores the GL codes, now in `GlConst#toGl` + - `isReadable`, `isWritable` - Returns whether the buffer can be read from or written to. + - `GpuBuffer` is now abstract + - Constructor with `ByteBuffer` is removed + - `size` - Returns the size of the buffer. + - `type` - Returns the type of the buffer. + - `resize`, `write`, `read`, `bind` is removed + - `usage` - Returns the usage of the buffer. + - `close` is now abstract + - `isClosed` - Returns whether the buffer has been closed. + - `$ReadView` is now an interface that defines the buffer data and how to close the view +- `com.mojang.blaze3d.font.SheetGlyphInfo#upload` now takes in a `GpuTexture` +- `com.mojang.blaze3d.opengl` + - `DirectStateAccess` - An interface that creates and binds data to some framebuffer. + - `$Core` - An implementation of DSA that modifies the framebuffer without binding them to the context. + - `$Emulated` - An abstraction over DSA that still binds the context. + - `GlBuffer` - An implementation of the `GpuBuffer` for OpenGL. + - `GlCommandEncoder` - An implementation of the `CommandEncoder` for OpenGL. + - `GlDebugLabel` - A labeler for handling debug references to GL-specified data structures. + - `GlDevice` - An implementation of `GpuDevice` for OpenGL. + - `GlRenderPass` - An implementation of `RenderPass` for OpenGL. + - `GlRenderPipeline` - An implementation of `CompiledRenderPipeline` for OpenGL. + - `GlTexture` - An implementation of `GpuTexture` for OpenGL. + - `VertexArrayCache` - A cache for binding and uploading a vertex array to the OpenGL pipeline. +- `com.mojang.blaze3d.pipeline` + - `BlendFunction` - A class that holds the source and destination colors and alphas to apply when overlaying pixels in a target. This also holds all vanilla blend functions. + - `CompiledRenderPipeline` - An interface that holds the pipeline with all necessary information to render to the screen. + - `RenderPipeline` - A class that contains everything required to render some object to the screen. It acts similarly to a render state before being applied. + - `RenderTarget` now takes in a string representing the name of the target + - `colorTextureId` -> `colorTexture`, now a `GpuTexture` + - Same with `getColorTextureId` -> `getColorTexture` + - `depthBufferId` -> `depthTexture`, now a `GpuTexture` + - Same with `getDepthTextureId` -> `getDepthTexture` + - `filterMode` is now a `FilterMode` + - Same with `setFilterMode` for the int parameter + - `blitAndBlendToScreen` no longer takes in the viewport size parameters + - `framebufferId` is removed + - `checkStatus` is removed + - `bindWrite`, `unbindWrite`, `setClearColor` is removed + - `blitToScreen` no longer takes in any parameters + - `blitAndBlendToScreen` -> `blitAndBlendToTexture`, not one-to-one + - `clear` is removed + - `unbindRead` is removed +- `com.mojang.blaze3d.platform` + - `DepthTestFunction` - An enum representing the supported depth tests to apply when rendering a sample to the framebuffer. + - `DisplayData` is now a record + - `withSize` - Creates a new instance with the specified width/height. + - `withFullscreen` - Creates a new instance with the specified fullscreen flag. + - `FramerateLimitTracker` + - `getThrottleReason` - Returns the reason that the framerate of the game was throttled. + - `isHeavilyThrottled` - Returns whether the current throttle significantly impacts the game speed. + - `$FramerateThrottleReason` - The reason the framerate is throttled. + - `GlConst` -> `com.mojang.blaze3d.opengl.GlConst` + - `#toGl` - Maps some reference object to its associated OpenGL code. + - `GlDebug` -> `com.mojang.blaze3d.opengl.GlDebug` + - `enableDebugCallback` now takes in a set of the enabled extensions. + - `GlStateManager` -> `com.mojang.blaze3d.opengl.GlStateManager` + - `_blendFunc`, `_blendEquation` is removed + - `_glUniform2(int, IntBuffer)`, `_glUniform4(int, IntBuffer)` is removed + - `_glUniformMatrix2(int, boolean, FloatBuffer)`, `_glUniformMatrix3(int, boolean, FloatBuffer)` is removed + - `_glUniformMatrix4(int, boolean, FloatBuffer)` -> `_glUniformMatrix4(int, FloatBuffer)`, transpose is now always false + - `_glGetAttribLocation` is removed + - `_glMapBuffer` is removed + - `_glCopyTexSubImage2D` is removed + - `_glBindRenderbuffer`, `_glDeleteRenderbuffers` is removed + - `glGenRenderbuffers`, `_glRenderbufferStorage`, `_glFramebufferRenderbuffer` is removed + - `_texParameter(int, int, float)` is removed + - `_genTextures`, `_deleteTextures` is removed + - `_texSubImage2D` now has an overload that takes in an `IntBuffer` instead of a `long` for the pixel data + - `upload` is removed + - `_stencilFunc`, `_stencilMask`, `_stencilOp`, `_clearStencil` is removed + - `_getTexImage` is removed + - `_glDrawPixels`, `_readPixels` is removed + - `$CullState#mode` is removed + - `$DestFactor` -> `DestFactor`, codes are removed to be called through `GlConst#toGl` + - `$FramebufferState` enum is removed + - `$LogicOp` -> `LogicOp`, codes are removed to be called through `GlConst#toGl` + - All but `OR_REVERSE` is removed + - `NONE` - Performs no logic operation. + - `$PolygonOffsetState#line` is removed + - `$SourceFactor` -> `SourceFactor`, codes are removed to be called through `GlConst#toGl` + - `$StencilFunc`, `$StencilState` class is removed + - `$Viewport` enum is removed + - `GlUtil` class is removed + - `getVendor`, `getRenderer`, `getOpenGlVersion` (now `getVersion`) have been moved to instance abstract methods on `GpuDevice` + - `getCpuInfo` -> `GLX#_getCpuInfo` + - `GLX` + - `getOpenGLVersionString` is removed + - `_init` -> `_getCpuInfo`, not one-to-one + - `_renderCrosshair`, `com.mojang.blaze3d.systems.RenderSystem#renderCrosshair` -> `net.minecraft.client.gui.components.DebugScreenOverlay#render3dCrosshair`, not one-to-one + - `PolygonMode` - A enum that defines how the polygons will render in the buffer. + - `NativeImage` constructor is now public + - `upload` is removed + - `getPointer` - Returns the pointer to the image data. + - `setPixelABGR` is now public + - `applyToAllPixels` is removed + - `downloadTexture`, `downloadDepthBuffer` is removed + - `flipY` is removed + - `setPackPixelStoreState`, `setUnpackPixelStoreState` is removed + - `$InternalGlFormat` enum is removed + - `$Format` no longer contains the GL codes, now in `GlConst#toGl` + - `TextureUtil` + - `generateTextureId`, `releaseTextureId` is removed + - `prepareImage` is removed + - `writeAsPNG` now takes in a `GpuTexture` instead of the direct three integers + - The overload without the `IntUnaryOperator` is removed +- `com.mojang.blaze3d.resource` + - `RenderTargetDescriptor` now takes in an integer representing the color to clear to + - `ResourceDescriptor` + - `prepare` - Prepares the resource for use after allocation. + - `canUsePhysicalResource` - Typically returns whether a descriptor is already allocated with the same information. +- `com.mojang.blaze3d.shaders` + - `AbstractUniform` -> `com.mojang.blaze3d.opengl.AbstractUniform` + - `setSafe` methods are removed + - `setMat*` methods are removed + - `set(Matrix3f)` is removed + - `CompiledShader` -> `com.mojang.blaze3d.opengl.GlShaderModule` + - `$Type` -> `com.mojang.blaze3d.shaders.ShaderType` + - `Uniform` -> `com.mojang.blaze3d.opengl.Uniform` + - Constructor now takes in a `$Type` instead of the count and an integer representing the type + - `UT_*` fields are removed + - `setFromConfig(ShaderProgramConfig.Uniform)` is removed + - `getTypeFromString` is removed + - `getType` now returns a `$Type` + - `set(int, float)` is removed + - `setSafe` is now private + - `$Type` - Holds the type name as well as how many values it holds. + - `getLocation` is removed + - `getCount` -> `$Type#count` + - `getIntBuffer`, `getFloatBuffer` is removed + - `$Type` -> `com.mojang.blaze3d.shaders.UniformType` +- `com.mojang.blaze3d.systems` + - `CommandEncoder` - An interface that defines how to encode various commands to the underlying render system, such as creating a pass, clearing and writing textures, or reading from the buffer. + - `GpuDevice` - An interface that defines the device or underlying render system used to draw to the screen. This is responsible for creating the buffers and textures while compiling any pipelines. + - `RenderPass` - An interface that defines how a given pass is rendered to some buffer using the underlying render system. This allows binding any samplers and setting the required uniforms. + - `RenderSystem` + - `isOnRenderThreadOrInit`, `assertOnRenderThreadOrInit` is removed + - `recordRenderCall`, `replayQueue` is removed + - `blendFunc`, `blendFuncSeparate`, `blendEquation` is removed + - `texParameter`, `deleteTexture`, `bindTextureForSetup` is removed + - `stencilFunc`, `stencilMask`, `stencilOp` is removed + - `clearDepth` is removed + - `glBindBuffer`, `glBindVertexArray`, `glBufferData`, `glDeleteBuffers` is removed + - `glUniform1i` is removed + - `glUniform1`, `glUniform2`, `glUniform3`, `glUniform4` is removed + - `glUniformMatrix2`, `glUniformMatrix3`, `glUniformMatrix4` is removed + - `setupOverlayColor` now takes in a `GpuTexture` instead of two ints + - `beginInitialization`, `finishInitialization` is removed + - `renderThreadTesselator` is removed + - `setShader`, `clearShader`, `getShader` is removed + - `setShaderTexture` now takes in a `GpuTexture` instead of a bind address + - `getShaderTexture` now returns a `GpuTexture` or null if not present + - `pixelStore`, `readPixels` is removed + - `queueFencedTask`, `executePendingTasks` - Handles sending tasks that run on the GPU asyncronously. + - `SCISSOR_STATE` - Holds the main scissor state. + - `disableDepthTest`, `enableDepthTest` is removed + - `depthFunc`, `depthMask` is removed + - `enableBlend`, `disableBlend` is removed + - `neableCull`, `disableCull` is removed + - `polygonMode`, `enablePolygonOffset`, `disablePolygonOffset`, `polygonOffset` is removed + - `enableColorLogicOp`, `disableColorLogicOp`, `logicOp` is removed + - `bindTexture`, `viewport` is removed + - `colorMask`, `clearColor`, `clear` is removed + - `setupShaderLights(CompiledShaderProgram)` is removed + - `getShaderLights` - Returns the vectors representing the block and sky lights. + - `drawElements`, `getString` is removed + - `initRenderer` now takes in the window pointer, the default shader source, and a boolean of whether to use debug labels + - `setupDefaultState` no longer takes in any parameters + - `maxSupportTextureSize` is removed + - `glDeleteVertexArrays` is removed + - `defaultBlendFunc` is removed + - `setShaderTexture` is removed + - `getQuadVertexBuffer` - Returns a vertex buffer with a quad bound to it. + - `getDevice`, `tryGetDevice` - Returns the `GpuDevice` representing the underlying render system to use. + - `getCapsString` is removed + - `activeTexture` is removed + - `setModelOffset`, `resetModelOffset`, `getModelOffset` - Handles the offset to apply to a model when rendering for the uniform `ModelOffset`. Typically for clouds and world borders. + - `$AutoStorageIndexBuffer#bind` -> `getBuffer`, not one-to-one + - `$GpuAsyncTask` - A record that holds the callback and fence object used to sync information to the GPU. + - `ScissorState` - A class which holds the part of the screen to render. +- `com.mojang.blaze3d.textures` + - `AddressMode` - The mode set for how to render a texture to a specific location. + - `FilterMode` - The mode set for how to render a texture whenever the level-of-detail function determines how the texture should be maximized or minimized. + - `GpuTexture` - A texture that is bound and written to the GPU as required. + - `TextureFormat` - Specifies the format that the texture should be allocated with. +- `com.mojang.blaze3d.vertex` + - `PoseStack` + - `mulPose(Quaternionf)`, `rotateAround` now takes in a `Quaternionfc` instead of a `Quaternionf` + - `clear` -> `isEmpty` + - `mulPose(Matrix4f)` -> `mulPose(Matrix4fc)` + - `$Pose` + - `computeNormalMatrix` is now private + - `transformNormal` now takes in a `Vector3fc` as its first parameter + - `translate`, `scale`, `rotate`, `rotateAround`, `setIdentity`, `mulPose` are now available on the pose itself in addition to the stack + - `VertexBuffer` -> `com.mojang.blaze3d.buffers.GpuBuffer`, not one-to-one + - Some logic is also moved to `VertexFormat` + - `VertexFormat` + - `bindAttributes` is removed + - `setupBufferState`, `clearBufferState`, `getImmediateDrawVertexBuffer` -> `uploadImmediateVertexBuffer`, `uploadImmediateIndexBuffer`; not one-to-one + - `$IndexType` no longer stores the GL codes, now in `GlConst#toGl` + - `$Mode` no longer stores the GL codes, now in `GlConst#toGl` + - `VertexFormatElement` + - `setupBufferState` is removed + - `$Type` no longer stores the GL codes, now in `GlConst#toGl` + - `$Usage` no longer stores the GL function calls, now in `VertexArrayCache#setupCombinedAttributes` +- `com.mojang.math` + - `MatrixUtil` + - `isIdentity`, `isPureTranslation`, `isOrthonormal` now take in a `Matrix4fc` + - `checkProperty` - Checks if the provided property is represented within the matrix. + - `OctahedralGroup` + - `transformation` now returns a `Matrix3fc` + - `fromAnges` -> `fromXYAngles`, not one-to-one + - `Quadrant` - An enum that contains rotations in 90 degree increments. + - `SymmetricGroup3#transformation` now returns a `Matrix3fc` + - `Transformation` now takes in a `Matrix4fc` + - `getMatrix` now returns a `Matrix4fc` + - `getMatrixCopy` - Returns a deep copy of the current matrix. +- `net.minecraft.client.gui.font.FontTexture` now takes in a supplied label string +- `net.minecraft.client.main.GameConfig` now takes in a boolean representing whether to render debug labels +- `net.minecraft.client.renderer` + - `CloudRenderer#render` no longer takes in the `Matrix4f`s used for projection or posing + - `CompiledShaderProgram` -> `com.mojang.blaze3d.opengl.GlProgram` + - `link` now takes in a string for the shader name + - `setupUniforms` now take in the list of `$UniformDescription`s along with a list of names used by the samplers + - `getUniformConfig` is removed + - `bindSampler` now takes in a `GpuTexture` instead of the integer bind identifier + - `parseUniformNode` is removed + - `CoreShaders` -> `RenderPipelines`, not one-to-one + - `LightTexture#getTarget` - Returns the `GpuTexture` that contains the light texture for the current level based on the player. + - `PostChain` + - `load` no longer takes in the `ShaderManager`, now taking in a `ResourceLocation` representing the name of the chain + - `addToFrame`, `process` now takes in a `RenderPass` consumer to apply any additional settings to the pass to render + - `setUniform` is removed + - `setOnRenderPass` - Sets the uniform within the post chain on the `RenderPass` for use in the shaders. + - `PostChainConfig` + - `$Pass` now takes in the ids of the vertex and fragment shader instead of the program id + - `referencedTargets` - Returns the targets referenced in the pass to apply. + - `program` is removed + - `$Uniform` now takes in the type of the uniform along with an optional list of floats if the value does not need to be overridden + - `PostPass` no longer takes in the `CompiledShaderProgram`, now taking in the `RenderPipeline` instead of a string representing the name of the pass + - `addToFrame` now takes in a `RenderPass` consumer to apply any additional settings to the pass to render + - `getShader` is removed + - `$Input#bindTo` now takes in a `RenderPass` instead of the `CompiledShaderProgram` + - `RenderStateShard` + - `$LayerStateShard`s using polygon offsets have been removed + - `getName` - Returns the name of the shard. + - `$TransparencyStateShard` class is removed + - Now handled through `BlendFunction` + - `$ShaderStateShard` class is removed + - Directly referred to by the `VertexBuffer` + - `$CullStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$DepthTestStateShard` class is removed + - Now handled through `DepthTestFunction` + - `$WriteMaskStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$ColorLogicStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$OutputStateShard` now takes in a supplied `RenderTarget` instead of the runnables for the startup and teardown states + - `RenderType` no longer takes in the `VertexFormat` or `VertexFormat$Mode` + - `SKY`, `END_SKY`, `sky`, `endSky`, `stars` is removed + - `ENTITY_OUTLINE_BLIT`, `entityOutlineBlit` is removed + - `PANORAMA`, `panorama` is removed + - `CREATE_LIGHTMAP`, `createLightmap` is removed + - `createClouds`, `flatClouds`, `clouds`, `cloudsDepthOnly` is removed + - `worldBorder` is removed + - `debugLine` - Returns the `RenderType` associated with the debug line. + - `entityOutlineBlit` - Returns the `RenderType` used for rendering an entity outline. + - `panorama` - Returns the `RenderType` used for rendering panorama mode. + - `createLightmap` - Returns the `RenderType` used for rendering the lightmap texture. + - `create` no longer takes in the `VertexFormat` or `VertexFormat$Mode`, instead the `RenderPipeline` + - `getRenderTarget`, `getRenderPipeline` - Returns the target and pipeline used for rendering. + - `format`, `mode`, `draw` are now abstract + - `$CompositeStateBuilder` methods are now protected + - `$OutlineProperty` is now protected + - `ShaderDefines$Builder#define` now has an overload that takes in an integer + - `ShaderManager` + - `SHADER_INCLUDE_PATH` is now private + - `MAX_LOG_LENGTH` is removed + - `preloadForStartup` is removed, replaced by `GpuDevice#precompilePipeline` + - `getProgram`, `getProgramForLoading` -> `getShader`, not one-to-one + - `linkProgram` now takes in a `RenderPipeline` instead of a `ShaderProgram` and `ShaderProgramConfig` + - `$CompilationCache#getOrCompileProgram`, `getOrCompileShader` -> `getShaderSource`, not one-to-one + - `$Configs` no longer takes in the map of programs + - `$ShaderCompilationKey` record is removed + - `ShaderProgram`, `ShaderProgramConfig` -> `RenderPipeline`, not one-to-one + - `SkyRenderer#renderDarkDisc` no longer takes in the `PoseStack` +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` + - `uploadSectionLayer`, `uploadSectionIndexBuffer` -> `$RenderSection#uploadSectionLayer`, `uploadSectionIndexBuffer` + - `$SectionBuffers` - A class that holds the buffers used to render the sections. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `NOT_ASSIGNED` is removed + - `texture`, `getTexture` - Holds the reference to the texture to render. + - `getId`, `releaseId` is removed + - `bind` is removed + - `DynamicTexture` now takes in the label of the texture + - `SpriteContents#uploadFirstFrame`, `$AnimatedTexture#uploadFirstFrame` now takes in a `GpuTexture` + - `SpriteTicker#tickAndUpload` now takes in the `GpuTexture` + - `TextureAtlasSprite#uploadFirstFrame`, `$Ticker#tickAndUpload` now takes in the `GpuTexture` + +## Model Rework + +The model system has been further separated into models for block states, blocks, and items. As such, the unifying `BakedModel` has been completely removed and separated into their own sections, loaded in three steps: from JSON, resolving dependencies, and then baking for use with the associated block state model or item model. For reference, everything discussed below is what's happenening within `ModelManager#reload` in parallel. + +First, let's start from the base model JSON used between blocks and items. These are loaded into an `UnbakedModel` (specifically `BlockModel`) which contains the familiar properties such as gui light and texture slots. However, one change is the splitting of the elements from their render settings. These elements that hold the render quads are stored in an `UnbakedGeometry`. The `UnbakedGeometry` is responsible for baking the model into a `QuadCollection`, which effectively holds the list of `BakedQuad`s to render. Currently, vanilla only has the `SimpleUnbakedGeometry`, which holds the familiar list of `BlockElement`s. These `UnbakedModel`, once loaded, are then passed to the `ModelDiscovery` for resolving the block state and item models. + +Next we have the `ResolvableModel`s, which is the base of both block state and item models. These models essentially function as markers requesting the `UnbakedModel`s that they will be using. From there, we have their subtypes `BlockStateModel$UnbakedRoot` for the block state JSON and `ItemModel$Unbaked` for the model referenced in the client item JSON. Each of these implement `resolveDependencies` in some way to call `ResolvableModel$Resolver#markDependency` with the model location they would like to use. + +> Technically, `BlockStateModel`s are a bit more complex as variants use `BlockStateModel$Unbaked` during loading which are then transformed into an `$UnbakedRoot` during initialization. + +Now that we know what models that should be loaded, they now have to be put into a usable state for baking. This is the job of the `ModelDiscovery`, which takes in a `ResolvableModel` and loads the `UnbakedModel`s into a `ResolvedModel` on first reference. `ResolvedModel`s are functionally wrappers around `UnbakedModel`s used to resolve all dependency chains, as the name implies. + +From there, model groups are built for `BlockState`s and the textures are loaded, leading to the final step of actually baking the `BlockStateModel` and the `ItemModel`. This is handled through the `bake` methods provided on the `$UnbakedRoot` (or `$Unbaked`) and the `ModelBakery`. In a nutshell, `bake` constructs the list of `BakedQuad`s stored with whatever additional information is desired by the block state or item model itself. The `ResolvedModel`s are obtained from the baker, from which the instance methods are called. For `BlockStateModel`s, this is resolved via `SimpleModelWrapper#bake`, from which the `ModelState` is obtained from the `Variant` data. They stored the baked quads in a `BlockModelPart`. For `ItemModel`s, it just consumes the `BakedQuad`s list directly along with information provided by `ModelRenderProperties#fromResolvedModel`. This does mean that each `BlockStateModel` and `ItemModel` may contain duplicated (but unique) `BakedQuad`s if the same model is referenced in multiple locations. + +### Block Generators: The Variant Mutator + +Given all the changes that separated out the block state JSON loading, there have also been a number of changes to the `BlockModelGenerators`. While most of them are simply renames (e.g., `BlockStateGenerator` -> `BlockModelDefinitionGenerator`), the major change is the addition of the `VariantMutator`. The `VariantMutator` is functionally a `UnaryOperator` on a `Variant` used to set some setting. This addition has simplified (or more like codec construction) the use of the `PropertyDispatch` for more quickly dispatching blocks with variants based on their properties. + +```java +// Creates a property dispatch on the horizontal facing property +// Applies the associated variants, though if desired, a functional interface can be provided instead +public static final PropertyDispatch ROTATION_HORIZONTAL_FACING = PropertyDispatch.modify(BlockStateProperties.HORIZONTAL_FACING) + .select(Direction.EAST, BlockModelGenerators.Y_ROT_90) + .select(Direction.SOUTH, BlockModelGenerators.Y_ROT_180) + .select(Direction.WEST, BlockModelGenerators.Y_ROT_270) + .select(Direction.NORTH, BlockModelGenerators.NOP); + +// Then, with access to the `Consumer` blockStateOutput +this.blockStateOutput.accept( + MultiVariantGenerator.dispatch(EXAMPLE_BLOCK).with(ROTATION_HORIZONTAL_FACING) +); +``` + +- `net.minecraft.client.data.models` + - `BlockModelGenerators` + - `nonOrientableTrapdoor` -> `NON_ORIENTABLE_TRAPDOOR`, now static + - Constants are now available for common `VariantMutator`s, like rotating the block model some number of degrees + - `texturedModels` -> `TEXTURED_MODELS`, now static + - `MULTIFACE_GENERATOR` is now private + - `plainModel` - Creates a variant from the model location. + - `variant`, `variants` - Creates a regular `MultiVariant` from some number of `Variant`s + - `plainVariant` - Creates a `MultiVariant` with only one model from its location. + - `condition` - Creates a new condition builder for multipart models + - `or` - ORs multiple conditions together. + - Most generator methods now return the `BlockModelDefinitionGenerator`, `Variant`, or `MultiVariant` and take in a `Variant` or `MultiVariant` instead of a `ResourceLocation` pointing to the desired model + - `VariantProperties` have been replaced with `VariantMutator`s + - `Condition$TerminalCondition` is replaced with `Condition` + - `createHorizontalFacingDispatch`, `createHorizontalFacingDispatchAlt`, `createTorchHorizontalDispatch` is removed + - `createFacingDispatch` is removed + - `createRotatedVariant(Block, ResourceLocation)` is removed + - `selectMultifaceProperties` - Creates a map of properties to `VariantMutator`s based on the provided `BlockState` and direction to property function. + - `applyRotation` no longer takes in the `Variant` and returns a `VariantMutator` + - `ItemModelGenerators#generateSpawnEgg` is removed + - `ModelProvider#saveAll` is removed +- `net.minecraft.client.data.models.blockstates` + - `BlockStateGenerator` -> `BlockModelDefinitionGenerator`, not one-to-one + - `Condition` -> `net.minecraft.client.renderer.block.model.multipart.Condition`, not one-to-one + - `validate` -> `instantiate`, not one-to-one + - `ConditionBuilder` - Builds a condition using property values + - `MultiPartGenerator` now implements `BlockModelDefinitionGenerator` + - `with(List)` -> `with(MultiVariant)` + - `with(Variant)` is removed + - `with(Condition, ...)` -> `with(Condition, MultiVariant)` + - Overload taking in `ConditionBuilder` + - `$ConditionalEntry`, `$Entry` is removed + - `MultiVariantGenerator` now implements `BlockModelDefinitionGenerator` + - `multiVariant` -> `dispatch` + - `multiVariant(Block, ...)` -> `dispatch(Block, MultiVariant)` + - `$Empty` - A multi variant entry that matches every block state. + - `PropertyDispatch` has a generic containing the value of the dispatch + - The generic `V` replaces all values of `List` + - `property`, `properties` -> `initial` or `modify` + - `$C*#generateList` methods are removed + - `$*Function` are removed + - `Selector` -> `PropertyValueList`, not one-to-one + - `Variant` -> `net.minecraft.client.renderer.block.model.Variant`, not one-to-one + - `VariantProperties` -> `net.minecraft.client.renderer.block.model.VariantMutator`, not one-to-one + - `VariantProperty` -> `net.minecraft.client.renderer.block.model.VariantMutator$VariantProperty`, not one-to-one +- `net.minecraft.client.renderer.ItemInHandRenderer#renderItem` no longer takes in the boolean representing if the item is held in the left hand +- `net.minecraft.client.renderer.block` + - `BlockModelShaper#stateToModelLocation`, `statePropertiesToString` is removed + - `BlockRenderDispatcher#renderBatched` now takes in a list of `BlockModelPart`s instead of a `RandomSource` + - `ModelBlockRenderer` + - `tesselateBlock`, `tesselateWithAO`, `tesselateWithoutAO` no longer takes in a `RandomSource` and replaces `BlockStateModel` with a list of `BlockModelPart`s + - `renderModel` is now static and no longer takes in the `BlockState` + - `$AmbientOcclusionFace` -> `$AmbientOcclusionRenderStorage` + - `$CommonRenderStorage` - A class that holds some metadata used to render a block at its given position. + - `$SizeInfo` now takes in the direct index rather than computing the info from its direction and a flipped boolean +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` is now a record + - `BlockElement` is now a record + - `from`, `to` are now `Vector3fc` + - `BlockElementFace` now takes in a `Quadrant` for the face rotation + - `getU`, `getV` - Returns the texture coordinate after rotation. + - `$Deserializer#getTintIndex` is now private and static + - `BlockFaceUV` -> `BlockElementFace$UVs`, not one-to-one + - `BlockModel` is now a record, taking in an `UnbakedGeometry` instead of the direct list of `BlockElement`s + - `$Deserializer#getElements` now returns an `UnbakedGeometry` + - `BlockModelDefinition` is now a record, taking in `$SimpleModelSelectors` and `$MultiPartDefinition`s + - `GSON`, `fromStream`, `fromJsonElement` -> `CODEC`, not one-to-one + - `instantiate` now takes in a supplied string instead of the string directly + - `$Deserializer` is removed + - `$MultiPartDefinition` - A record that holds a list of selectors to get for the multi part model. + - `$SimpleModelSelectors` - A record that holds a map of variants to their unbaked model instances. + - `BlockModelPart` - A baked model representation of a block. + - `BlockStateModel` - A baked representation of a block state. + - `collectParts` - Obtains the list of baked models used to render this state. + - `$SimpleCachedUnbakedRoot` - A class that represents a delegate of some `$Unbaked` model. + - `$Unbaked` - An extension over `$UnbakedRoot` that can create a `$SimpleCachedUnbakedRoot` + - `FaceBakery` + - `bakeQuad` now takes in `Vector3fc`s instead of `Vector3f`s + - `recomputeUVs` is removed + - `extractPositions` - Extracts the face positions and passes them to a consumer for use. + - `ItemTransform` is now a record, vectors are `Vector3fc`s + - `MultiVariant` -> `net.minecraft.client.data.models.MultiVariant` + - `CODEC` + - `with` - Creates a `MultiVariant` with the specified mutators. + - `$Deserializer` class is removed + - `SimpleModelWrapper` now implements `BlockModelPart` + - `SimpleUnbakedGeometry` - An unbaked geometry that holds a list of `BlockElement`s to bake. + - `SingleVariant` - A `BlockStateModel` implementation with only one model for its state. + - `UnbakedBlockStateModel` -> `BlockStateModel$UnbakedRoot` + - `Variant` no longer implements `ModelState`, now taking in a `$SimpleModelState` instead of the direct rotation and uv lock + - The constructor now has an overload for only providing the `ResourceLocation` and no longer takes in the weight, leaving that to the `MultiVariant` + - `CODEC` + - `withXRot`, `withYRot`, `withUvLock`, `withModel`, `withState`, `with` - Mutates the variant into a new object with the given setting applied. + - `$Deserializer` class is removed + - `$SimpleModelState` - A record that holds the x/y rotations and uv lock. + - `VariantMutator` - A unary operator on a variant that applies the specified setting to the variant. Used during state generation. +- `net.minecraft.client.renderer.block.model.multipart` + - `AndCondition`, `OrCondition` -> `CombinedCondition`, not one-to-one + - `KeyValueCondition` is now a record that takes in a map of keys to terms to test + - `MultiPart` -> `MultiPartModel$Unbaked` + - `$Definition` + - `CODEC` + - `getMultiVariants` is removed + - `$Deserializer` class is removed + - `Selector` is now a record, taking in a `BlockStateModel$Unbaked` instead of a `MultiVariant` + - `$Deserializer` class is removed +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `renderItem` now takes in a `List` instead of a `BakedModel` + - `renderStatic` no longer takes in a boolean indicating what hand the item was held in +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` now has a public constructor that takes in the list of tint sources, the list of quads, and the `ModelRenderProperties` + - The list of quads and `ModelRenderProperties` replaces the direct `BakedModel`, or now `BlockStateModel` + - `computeExtents` - Extracts the vertices of the baked quads into an array. + - `ItemModel$BakingContext#bake` is removed + - `ItemModelResolver#updateForLiving`, `updateForTopItem` no longer takes in a boolean representing if the item is in the left hand + - `ItemStackReenderState` + - `isGui3d` is removed + - `transform` is removed + - `visitExtents` - Visits all vertices of the model to render and passes them into the provided consumer. + - `$LayerRenderState` + - `NO_EXTENTS_SUPPLIER` - An empty list of vertices. + - `setupBlockModel` has been broken into `prepareQuadList`, `setRenderType`, `setUsesBlockLight`, `setExtents`, `setParticleIcon`, `setTransform` + - `setupSpecialModel` no longer takes in the base `BakedModel` + - `MissingItemModel` now takes in a list of `BakedQuad`s and `ModelRenderProperties` instead of the direct `BakedModel` + - `ModelRenderProperties` - The properties used to render a model, typically retrieved from the `ResolvedModel`. + - `SpecialModelRenderer` now takes in the `ModelRenderProperties` insetad of the base `BakedModel` +- `net.minecraft.client.resources.model` + - `BakedModel` -> `net.minecraft.client.resources.model.QuadCollection`, not one-to-one + - `BlockModelRotation` + - `by` now takes in `Quadrant`s instead of integers + - `withUvLock` - Returns the model state with the rotation and a mention that it locks the UV for the rotation. + - `BlockStateDefinitions` - A manager for creating the mapper of block names to their state defintions. + - `BlockStateModelLoader` + - `ModelResourceLocation` fields are removed + - `loadBlockState` no longer takes in the missing model + - `$LoadedModel` class is removed + - `$LoadedModels` now takes in a `BlockStateModel$UnbakedRoot` instead of an `$Unbaked` + - `forResolving`, `plainModels` is removed + - `DelegateBakedModel` -> `net.minecraft.client.renderer.block.model.SimpleModelWrapper`, not one-to-one + - `MissingBlockModel#VARIANT` is removed + - `ModelBaker` + - `bake` -> `getModel`, not one-to-one + - The baker is simply retrieving the `ResolvedModel` + - `rootName` is removed + - `compute` - Computes the provided key that contains the `ModelBaker`. Typically used for baking `BlockStateModel`s + - `$SharedOperationKey` - An interface which typically computes some baking process for an unbaked model. + - `ModelBakery` now takes in a `Map` for the unbaked block state models, a `Map` for the loaded models, and a `ResolvedModel` for the missing model + - `bakeModels` now takes in a `SpriteGetter` and an `Executor` while returning a `CompletableFuture` for parallel loading and baking + - `$BakingResult` now takes in a `$MissingModels` for the missing block state and item model and a `Map` for the baked block state models; the missing item model is stored within `$MissingModels` + - `$MissingModels` - Holds the missing models for a block state and item. + - `$TextureGetter` interface is removed + - `ModelDebugName` no longer extends `Supplier`, instead using `debugName` + - `ModelDiscovery` + - `registerSpecialModels` is removed + - `discoverDependencies` is now private + - `getReferencedModels`, `getUnreferencedModels` is removed + - `addSpecialModel` - Adds a root model to the list of arbitrarily loaded models. + - `missingModel` - Returns the missing model + - `resolve` - Resolves all model dependencies, returning a map of model names to their models. + - `ModelGroupCollector$GroupKey#create` now takes in a `BlockStateModel$UnbakedRoot` instead of an `$Unbaked` + - `ModelManager` + - `getModel` is removed + - `getMissingModel` -> `getMissingBlockStateModel` + - `$ResolvedModels` - A map of models with their dependencies resolved. + - `ModelResourceLocation` record is removed + - `ModelState` + - `getRotation` -> `transformation` + - `isUvLocked` is removed + - `faceTransfomration`, `inverseFaceTransformation` - Handles returning the transformed `Matrix4fc` for baking the face vertices. + - `MultiPartBakedModel` -> `net.minecraft.client.renderer.block.model.multipart.MultiPartModel` + - Now implements `BlockStateModel` instead of extending `DelegateBakedModel` + - `$SharedBlockState` - A holder that contains the `BlockStateModel`s mapped to their `$Selector`s. + - `QuadCollection` - A data object containing the list of quads to render based on the associated direction and culling. + - `ResolvableModel$Resolver#resolve` -> `markDependency`, not one-to-one + - Instead of directly resolving, the dependency is marked for a later post processing step + - `ResolvedModel` - An `UnbakedModel` whose model and texture dependencies have been completely resolved. + - `SimpleBakedModel` -> `net.minecraft.client.renderer.block.model.SimpleModelWrapper` or `net.minecraft.client.renderer.block.model.SimpleUnbakedGeometry`, not one-to-one + - `SpriteGetter` + - `get`, `reportMissingReference` now take in the `ModelDebugName` + - `resolveSlot` - Resolves the key from the `TextureSlot`s into its `TextureAtlasSprite`. + - `UnbakedGeometry` - An interface that constructs a collection of quads the render when baked. + - `UnbakedModel` no longer implements `ResolvableModel` + - `DEFAULT_AMBIENT_OCCLUSION`, `DEFAULT_GUI_LIGHT` is removed + - `PARTICLE_TEXTURE_REFERENCE` - Holds the key representing the particle texture. + - `bake` is removed + - `getAmbientOcclusion` -> `ambientOcclusion` + - `getGuiLight` -> `guiLight` + - `getTransforms` - `transforms` + - `getTextureSlots` - `textureSlots` + - `geometry` - Holds the unbaked geometry representing the model elements. + - `getParent` -> `parent`, not one-to-one + - `bakeWithTopModelValues` is removed + - `getTopTextureSlots`, `getTopAmbientOcclusion`, `getTopGuiLight`, `getTopTransform`, `getTopTransforms` is removed + - `WeightedBakedModel` -> `WeightedVariants` + - Now implements `BlockStateModel` instead of extending `DelegateBakedModel` +- `net.minecraft.world.item.ItemDisplayContext#leftHand` - Returns whether the display context is rendering with the entity's left hand. + +## 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. + +### Entity References + +Generally, the point of storing the UUID of another entity was to later grab that entity to perform some logic. However, storing the raw entity could lead to issues if the entity was removed at some point in time. As such, the `EntityReference` was added to handle resolving the entity from its UUID while also making sure it still existed at the time of query. + +An `EntityReference` is simply a wrapped `Either` which either holds the entity instance or the UUID. When resolving via `getEntity`, it will attempt to verify that the stored entity, when present, isn't removed. If it is, it grabs the UUID to perform another lookup for the entity itself. If that entity does exist, it will be return, or otherwise null. + +Most references to a UUID within an entity have been replaced with an `EntityReference` to facilitate this change. + +- `net.minecraft.network.syncher.EntityDataSerializers#OPTIONAL_UUID` -> `OPTIONAL_LIVING_ENTITY_REFERENCE`, not one to one as it can hold the entity reference +- `net.minecraft.server.level.ServerLevel#getEntity(UUID)` -> `Level#getEntity(UUID)` +- `net.minecraft.world.entity` + - `EntityReference` - A reference to an entity either by its entity instance when present in the world, or a UUID. + - `LivingEntity#lastHurtByPlayer`, `lastHurtByMob` are now `EntityReference`s + - `OwnableEntity` + - `getOwnerUUID` -> `getOwnerReference`, not one-to-one + - `level` now returns a `Level` instead of an `EntityGetter` + - `TamableAnimal#setOwnerUUID` -> `setOwner`, or `setOwnerReference`; not one-to-one +- `net.minecraft.world.entity.animal.horse.AbstractHorse#setOwnerUUID` -> `setOwner`, not one-to-one +- `net.minecraft.world.level.Level` now implements `UUIDLookup` +- `net.minecraft.world.level.entity` + - `EntityAccess` now implements `UniquelyIdentifyable` + - `UniquelyIdentifyable` - An interface that claims the object as a UUID and keeps tracks of whether the object is removed or not. + - `UUIDLookup` - An interface that looks up a type by its UUID. + +### Descoping Player Arguments + +Many methods that take in the `Player` has been descoped to take in a `LivingEntity` or `Entity` depending on the usecase. The following methods below are a non-exhaustive list of this. + +- `net.minecraft.world.entity.EntityType` + - `spawn` + - `createDefaultStackConfig`, `appendDefaultStackConfig` + - `appendCustomEntityStackConfig`, `updateCustomEntityTag` +- `net.minecraft.world.item` + - `BucketItem#playEmptySound` + - `DispensibleContainerItem#checkExtraContent`, `emptyContents` +- `net.minecraft.world.level` + - `Level` + - `playSeededSound` + - `mayInteract` + - `LevelAccessor` + - `playSound` + - `levelEvent` +- `net.minecraft.world.level.block` + - `BucketPickup#pickupBlock` + - `LiquidBlockContainer#canPlaceLiquid` +- `net.minecraft.world.level.block.entity.BrushableBlockEntity#brush` + +### Component Interaction Events + +Click and hover events on a `MutableComponent` have been reworked into `MapCodec` registry-like system. They are both now interfaces that register their codecs to an `$Action` enum. The implementation then creates a codec that references the `$Action` type and stores any necessary information that is needed for the logic to apply. However, there is no direct 'action' logic associated with the component interactions. Instead, they are hardcoded into their use locations. For click events, this is within `Screen#handleComponentClicked`. For hover events, this is in `GuiGraphics#renderComponentHoverEffect`. As such, any additional events added will need to inject into both the enum and one or both of these locations. + +- `net.minecraft.network.chat` + - `ClickEvent` is now an interface + - `getAction` -> `action` + - `getValue` is now on the subclasses as necessary for their individual types + - `HoverEvent` is now an interface + - `getAction` -> `action` + - `$EntityTooltipInfo` + - `CODEC` is now a `MapCodec` + - `legacyCreate` is removed + - `$ItemStackInfo` is removed, replaced by `$ShowItem` + - `$LegacyConverter` interface is removed + +### Texture Atlas Reworks + +The texture atlas logic has been finalized into a registry codec system; however, the querying of the atlas data has changed. First, all atlas identifiers are stored within `AtlasIds` while the corresponding texture location is stored within `Sheets`. To get a material from an atlas, a `MaterialMapper` is used as a wrapper around the texture location and the associated prefix to append to the material. The `Material` can then be obtained using `apply` by passing in the id of the material you would like to use. + +For example: + +```java +// Found in sheets +public static final MaterialMapper ITEMS_MAPPER = new MaterialMapper(TextureAtlas.LOCATION_BLOCKS, "item"); +public static final MaterialMapper BLOCKS_MAPPER = new MaterialMapper(TextureAtlas.LOCATION_BLOCKS, "block"); + +// Finds the texture for the material at `assets/examplemod/textures/item/example_item.png` +public static final Material EXAMPLE_ITEM = ITEMS_MAPPER.apply(ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")); + +// Finds the texture for the material at `assets/examplemod/textures/block/example/block.png` +public static final Material EXAMPLE_BLOCK = ITEMS_MAPPER.apply(ResourceLocation.fromNamespaceAndPath("examplemod", "example/block")); +``` + +- `net.minecraft.client.data.AtlasProvider` - A data provider for generating the providers of a texture atlas. +- `net.minecraft.client.data.models.ItemModelGenerators` + - `SLOT_*` -> `TRIM_PREFIX_*`, now public and `ResourceLocation`s + - `TRIM_MATERIAL_MODELS` is now public + - `generateTrimmableItem` now takes in a `ResourceLocation` instead of a `String` + - `$TrimMaterialData` is now public, taking in a `MaterialAssetGroup` instead of the name and override materials +- `net.minecraft.client.renderer` + - `MaterialMapper` - An object that stores the location of the atlas texture and the prefix applied to the ids within the texture. + - `Sheets` + - `*_MAPPER` - `MaterialMapper`s for each texture atlas texture. + - `createBedMaterial(ResourceLocation)` is removed + - `createShulkerMaterial(ResourceLocation)` is removed + - `createSignMaterial(ResourceLocation)` is removed + - `chestMaterial(String)`, `chestMaterial(ResourceLocation)` are removed + - `createDecoratedPotMaterial(ResourceLocation)` is removed +- `net.minecraft.client.renderer.blockentity.ConduitRenderer#MAPPER` - A mapper to get the conduit textures from the block atlas. +- `net.minecraft.client.renderer.texture.atlas` + - `SpriteSource#type` -> `codec`, not one-to-one + - `SpriteSources` now contains logic similar to client registries via their id mapper + - `SpriteSourceType` record is removed +- `net.minecraft.client.renderer.texture.atlas.sources` + - `DirectoryLister` is now a record + - `PalettedPermutations` is now a record + - `SingleFile` is now a record + - `SourceFilter` is now a record + - `Unstitcher` is now a record + - `$Region` is now public +- `net.minecraft.client.resources.model.AtlasIds` - A class which holds the `ResourceLocation`s of all vanilla texture atlases. + +### Registry Context Swapper + +Client items now store a `RegistryContextSwapper`, which is used to properly check client item information that accesses registry objects. Before level load, this is provided a placeholder to avoid crashing and populated with the correct value during rendering. + +- `net.minecraft.client.multiplayer` + - `CacheSlot` - An object that contains a value computed from some context. When updated, the previous value is overwritten and the context registers the slot to be cleaned. + - `ClientLevel` now implements `CacheSlot$Cleaner` +- `net.minecraft.client.renderer.item` + - `ClientItem` can now take in a nullable `RegistryContextSwapper` + - `withRegistrySwapper` - Sets the `RegistryContextSwapper` within a `ClientItem` + - `ItemModel$BakingContext` now takes in a `RegistryContextSwapper` +- `net.minecraft.util` + - `PlaceholderLookupProvider` - A provider that contains placeholders for referenced objects. Used within client items as they will be loaded before the `RegistyAccess` is populated. + - `RegistryContextSwapper` - An interface used to swap out some object for a different one. Used by client items to swap the placeholders for the loaded `RegistryAccess`. + +### Reload Instance Creation + +Reload instances have been slightly rearranged. The `SimpleReloadInstance` base now only takes in the `List`, where the other fields are passed into the `of` function such that `#startTasks` can be called immediately. + +- `net.minecraft.server.packs.resources` + - `ProfiledReloadInstance` construct is now private, accessed through `of` + - `SimpleReloadInstance` only takes in the `List` + - `of` now returns a `ReloadInstance`, not one-to-one + - `allPreparations` is now package private + - `allDone` is now private + - `startTasks` - Begins the reload of the listener. + - `prepareTasks` - Runs the executor and sets up the futures needed to read and load all desired data. + - `StateFactory$SIMPLE` - A factory that calls `PreparableReloadListener#reload` + +### Block Effect Appliers + +Effects that are applied to entities when inside a block are now handled through the `InsideBlockEffectApplier` and `InsideBlockEffectType`. The `InsideBlockEffectType` is an enum that contains a consumer on what to apply to an entity when called. `InsideBlockEffectApplier`, on the other hand, is stored on the entity has a way to apply an effect in a ordered manner based on the enum ordinals. + +To call one of the effect types, you must override `BlockBehaviour#entityInside` or `Fluid#entityInside` and call `InsideBlockEffectApplier#apply`. If something should apply before the effect type, like entinguishing fire before freezing in powder snow, then `InsideBlockEffectApplier#runBefore` should be called before `apply`. Similarly, if something should run afterward, like hurting an enemy after being placed in lava, then `runAfter` should be called. + +```java +// In some block or fluid subclass +@Override +protected void entityInside(Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier applier) { + applier.runBefore(InsideBlockEffectType.EXTINGUISH, entity -> { + // Modify entity here. + }); + + // Do the base application logic stored on the type + applier.apply(InsideBlockEffectType.FIRE_IGNITE); + + applier.runAfter(InsideBlockEffectType.FIRE_IGNITE, entity -> { + // Perform any final checks that are as a result of the effect being applied + entity.hurt(...); + }); +} +``` + +- `net.minecraft.world.entity` + - `InsideBlockEffectApplier` - An interface that defines how an entity should interact when within a given block. + - `InsideBlockEffectType` - An enum that defines what behavior to perform when side the specific block that references the type. +- `net.minecraft.world.level.block.state.BlockBehaviour#entityInside`, `$BlockStateBase#entityInside` now takes in an `InsideBlockEffectApplier` +- `net.minecraft.world.level.material.Fluid#entityInside`, `FluidState#entityInside` - A method called whenever the entity is considered inside the bounding box of the fluid. + +### Timer Callbacks, joining the codec club! + +`TimerCallback`s, used in the server schedule for executing events, typically mcfunctions in datapacks, have now been reworked into a codec form. This means that a callback can be registered to the list of available callbacks by passing in the `MapCodec` to `TimerCallbacks#register` (via `TimerCallbacks#SERVER_CALLBACKS`) instead of the serializer. + +- `net.minecraft.world.level.timers` + - `FunctionCallback` is now a record + - `FunctionTagCallback` is now a record + - `TimerCallback` + - `codec` - Returns the codec used for serialization. + - `$Serializer` class is removed + - `TimerCallbacks` + - `serialize`, `deserialize` -> `codec`, not one-to-one + +### The JOML Backing Interfaces + +Mojang has opted to lessen the restriction on JOML objects by passing around the implementing interface of their logic objects (usually implemented with a tacked on `c`). For example, `Vector3f` becomes `Vector3fc` or `Matrix4f` becomes `Matrix4fc`. This does not change any logic itself as the `c` interfaces are implemented by the class components. + +### Tag Changes + +- `minecraft:worldgen/biome` + - `spawns_cold_variant_farm_animals` + - `spawns_warm_variant_farm_animals` +- `minecraft:block` + - `sword_instantly_mines` + - `replaceable_by_mushrooms` + - `plays_ambient_desert_block_sounds` + - `edible_for_sheep` + - `dead_bush_may_place_on` -> `dry_vegetation_may_place_on` + - `camels_spawnable_on` +- `minecraft:cat_variant` are removed +- `minecraft:entity_type` + - `can_equip_saddle` + - `can_wear_horse_armor` +- `minecraft:item` + - `book_cloning_target` + - `eggs` + - `flowers` + +### Mob Effects Field Renames + +Some mob effects have been renamed to their in-game name, rather than some internal descriptor. + +- `MOVEMENT_SPEED` -> `SPEED` +- `MOVEMENT_SLOWDOWN` -> `SLOWNESS` +- `DIG_SPEED` -> `HASTE` +- `DIG_SLOWDOWN` -> `MINING_FATIGUE` +- `DAMAGE_BOOST` -> `STRENGTH` +- `HEAL` -> `INSTANT_HEALTH` +- `HARM` -> `INSTANT_DAMAGE` +- `JUMP` -> `JUMP_BOOST` +- `CONFUSION` -> `NAUSEA` +- `DAMAGE_RESISTANCE` -> `RESISTANCE` + +### Very Technical Changes + +This is a list of technical changes that could cause highly specific errors depending on your specific setup. + +- The order of the `minecraft:patch_sugar_cane` feature and `minecraft:patch_pumpkin` feature have swapped orders (first pumpkin, then sugar cane), meaning modded biomes that generate both of these features will need to update their JSONs to the new ordering. + +- Serveral vanilla oak tree and tree selector features now have `_leaf_litter` appended at the end. + - For example: `trees_birch_and_oak` -> `trees_birch_and_oak_leaf_litter` + +### List of Additions + +- `net.minecraft` + - `ChatFormatting#COLOR_CODEC` + - `CrashReportCategory#populateBlockLocationDetails` - Adds the block location details to a crash report. +- `net.minecraft.advancements.critereon.MinMaxBounds#createStreamCodec` - Constructs a stream codec for a `MinMaxBounds` implementation. +- `net.minecraft.client.Options#startedCleanly` - Sets whether the game started cleanly on last startup. +- `net.minecraft.client.data.models` + - `BlockModelGenerators#createSegmentedBlock` - Generates a multipart blockstate definition with horizontal rotation that displays up to four models based on some integer property. + - `ItemModelGenerators#prefixForSlotTrim` - Generates a vanilla `ResourceLocation` for a trim in some slot. +- `net.minecraft.client.MouseHandler` + - `fillMousePositionDetails` - Adds details about the current mouse location and screen size to a crash report. + - `getScaledXPos` - Gets the current x position scaled by the gui scaling option. + - `getScaledYPos` - Gets the current y position scaled by the gui scaling option. + - `drawDebugMouseInfo` - Draws information about the scaled position of the mouse to the screen. +- `net.minecraft.client.gui.components.toasts.Toast#getSoundEvent` - Returns the sound to play when the toast is displayed. +- `net.minecraft.client.gui.screens.options.VideoSettingsScreen#updateFullscreenButton` - Sets the fullscreen option to the specified boolean. +- `net.minecraft.client.model.geom.builders` + - `MeshDefinition#apply` - Applies the given transformer to the mesh before returning a new instance. + - `MeshTransformer#IDENTITY`- Performs the identity transformation. +- `net.minecraft.client.multiplayer.ClientPacketListener#decoratedHashOpsGenenerator` - Returns the generator used to create a hash of a data component and its value. +- `net.minecraft.client.particle` + - `FallingLeavesParticle$TintedLeavesProvider` - A provider for a `FallingLeavesParticle` that uses the color specified by the block above the particle the spawn location. + - `FireflyParticle` - A particle that spawns fireflies around a given non-air block position. +- `net.minecraft.client.renderer` + - `BiomeColors#getAverageDryFoliageColor` - Returns the average foliage color for dry biomes. + - `LevelRenderer$BrightnessGetter` - An interfaces which obtains the packed brightness at a given block position. + - `WorldBorderRenderer#invalidate` - Invalidates the current render of the world border to be rerendered. +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher#getRenderer` - Gets the renderer to use from the data stored on the render state. + - `EntityRenderer#extractAdditionalHitboxes` - Gets any additional hitboxes to render when the 'show hitboxes' debug state is enabled. +- `net.minecraft.client.renderer.entity.state` + - `EntityRenderState` + - `entityType` - The type of the entity. + - `hitboxesRenderState` - The hitbox information of the entity relative to the entity's position. + - `serverHitboxesRenderState` - The hitbox information of the entity synced from the server. + - `fillCrashReportCategory` - Sets the details for any crashes related to the render state. + - `HitboxesRenderState` - The render state of the hitboxes for the entity relative to the entity's position. + - `HitboxRenderState` - The render state of a single hitbox to render along with its color, such as the eye height of an entity. + - `ServerHitboxesRenderState` - The render state containing the last synced information from the related server entity. + - `PigRenderState#variant` - The variant of the pig. +- `net.minecraft.client.renderer.item.SelectItemModel$ModelSelector` - A functional interface that selects the item model based on the switch case and level. +- `net.minecraft.client.renderer.item.properties.conditional.ComponentMatches` - A conditional property that checks whether the given predicate matches the component data. +- `net.minecraft.client.renderer.item.properties.select` + - `ComponentContents` - A switch case property that operates on the contents within a data component. + - `SelectItemModelProperty#valueCodec` - Returns the `Codec` for the property type. +- `net.minecraft.client.resources.DryFoliageColorReloadListener` - A reload listener that loads the colormap for dry foliage. +- `net.minecraft.commands.arguments.ComponentArgument#getResolvedComponent` - Constructs a component with the resolved information of its contents. +- `net.minecraft.core` + - `Direction#getUnitVec3f` - Returns the float unit vector of the direction. + - `HolderGetter$Provider#getOrThrow` - Gets a holder reference from a resource key. + - `SectionPos#sectionToChunk` - Converts a compressed section position to a compressed chunk position. + - `Vec3i#STREAM_CODEC` +- `net.minecraft.network` + - `HashedPatchMap` - A record containing a map of components to their hashed type/value along with a set of removed components. + - `HashedStack` - An `ItemStack` representation that hashes the stored components. + - `ProtocolInfo$DetailsProvider` - Provides the details for a given protocol. + - `SkipPacketDecoderException` - An exception thrown when an error occurs during decoding before having its data ignored. + - `SkipPacketEncoderException` - An exception thrown when an error occurs during encoding before having its data ignored. +- `net.minecraft.network.chat` + - `LastSeenMessages` + - `computeChecksum` - Computes a byte representing the merged checksums of all message signatures. + - `$Update#verifyChecksum` - Verifies that the update checksum matches those within the last seen messages. + - `LastSeenMessagesValidator$ValidationException` - An exception thrown if the messages can not be validated. + - `MessageSignature` + - `describe` - Returns a stringified version of the message signature. + - `checksum` - Hashes the bytes within the signature into a single integer. + - `PlayerChatMessage#describeSigned` - Returns a stringified version of the chat message. +- `net.minecraft.network.codec` + - `ByteBufCodecs` + - `LONG_ARRAY` + - `lengthPrefixed` - Returns an operation that limits the size of the buffer to the given size. + - `IdDispatchCodec$DontDecorateException` - An interface that tells the exception handler to rethrow the raw exception rather than wrap it within an `EncoderException`. +- `net.minecraft.network.protocol` + - `CodecModifier` - A function that modifies some codec using a given object. + - `ProtocolInfoBuilder#context*Protocol` - Builds an `UnboundProtocol` with the given context used to modify the codecs to send. +- `net.minecraft.network.protocol.game.GameProtocols` + - `HAS_INFINITE_MATERIALS` - A modifier that checks the `ServerboundSetCreativeModeSlotPacket` for if the player has the necessary settings. If not, the packet is discarded. + - `$Context` - Returns the context used by the packet to modify the incoming codec. +- `net.minecraft.resources.DelegatingOps` + - `$DelegateListBuilder` - A list builder that can be subclassed if needed. + - `$DelegateRecordBuilder` - A record builder that can be subclassed if needed. +- `net.minecraft.server.bossevents.CustomBossEvent$Packed` - A record that backs the event information for serialization. +- `net.minecraft.server.commands.InCommandFunction` - A command function that takes in some input and returns a result. +- `net.minecraft.server.level` + - `DistanceManager#forEachBlockTickingChucnks` - Applies the provided consumer for each chunk with block ticking enabled. + - `ServerLevel` + - `areEntitiesActuallyLoadedAndTicking` - Returns whether the entity manager is actually ticking and loading entities in the given chunk. + - `tickThunder` - Ticks the thunger logic within a given level. + - `anyPlayerCloseEnoughForSpawning` - Returns if a player is close enough to spawn the entity at the given location. + - `ServerPlayer$RespawnConfig` - A record containing the respawn information for the player. +- `net.minecraft.util` + - `AbstractListBuilder` - A ops list builder which boils the implementation down to three methods which initializes, appends, and builds the final list. + - `Brightness` + - `block` - Returns the block light from a packed value. + - `sky` - Returns the sky light from a packed value. + - `HashOps` - A dynamic ops that generates a hashcode for the data. + - `ExtraCodecs` + - `UNTRUSTED_URI` - A codec for a URI that is not trusted by the game. + - `CHAT_STRING` - A codec for a string in a chat message. + - `legacyEnum` - A codec that maps an enum to its output in `Enum#toString`. + - `FileSystemUtil` - A utility for interacting with the file system. + - `GsonHelper#encodesLongerThan` - Returns whether the provided element can be written in the specified number of characters. + - `Unit#STREAM_CODEC` - A stream codec for a unit instance. + - `Util` + - `mapValues` - Updates the values of a map with the given function. + - `mapValuesLazy` - Updates the values of a map with the given function, but each value is resolved when first accessed. + - `growByHalf` - Returns an integer multiplied by 1.5, rounding down, clamping the value to some minimum and the max integer size. +- `net.minecraft.util.random.Weighted#map`, `WeightedList#map` - Transforms the stored object(s) to a new type. +- `net.minecraft.util.thread.ParallelMapTransform` - A helper that handles scheduling and batching tasks in parallel. +- `net.minecraft.world.effect.MobEffectInstance#withScaledDuration` - Constructs a new instance with the duration scaled by some float value. +- `net.minecraft.world.entity` + - `AreaEffectCloud#setPotionDurationScale` - Sets the scale of how long the potion should apply for. + - `DropChances` - A map of slots to probabilities indicating how likely it is for an entity to drop that piece of equipment. + - `Entity` + - `isInterpolating` - Returns whether the entity is interpolating between two steps. + - `sendBubbleColumnParticles` - Spawns bubble column particles from the server. + - `canSimulateMovement` - Whether the entity's movement can be simulated, usually from being the player. + - `propagateFallToPassengers` - Propogates the fall damage of a vehicle to its passengers. + - `lavaIgnite` - Ignites the entity for 15 seconds if not immune. + - `clearFreeze` - Sets the number of ticks the entity is frozen for to 0. + - `removeLatestMovementRecordingBatch` - Removes the last element from all movements performed this tick. + - `InterpolationHandler` - A class meant to easily handle the interpolation of the position and rotation of the given entity as necessary. + - `LivingEntity` + - `getLuck` - Returns the luck of the entity for random events. + - `getLastHurtByPlayer`, `setLastHurtByPlayer` - Handles the last player to hurt this entity. + - `getEffectBlendFactor` - Gets the blend factor of an applied mob effect. + - `applyInput` - Applies the entity's input as its AI, typically for local players. + - `INPUT_FRICTION` - The scalar to apply to the movements of the entity. +- `net.minecraft.world.entity.animal.camel.Camel#checkCamelSpawnRules` - Checks if a camel can spawn at a particular position. +- `net.minecraft.world.entity.animal.sheep.SheepColorSpawnRules` - A class that contains the color spawn configurations for a sheep's wool when spawning within a given climate. +- `net.minecraft.world.entity.npc.Villager#createDefaultVillagerData` - Returns the default type and profession of the villager to use when no data is set. +- `net.minecraft.world.entity.player.Player` + - `preventsBlockDrops` - Whether the player cannot drop any blocks on destruction. + - `gameMode` - Returns the current game mode of the player. + - `debugInfo` - Returns the common information about the player as a single string. +- `net.minecraft.world.inventory` + - `ContainerSynchronizer#createSlot` - Creates a `RemoteSlot` that represents a slot on the opposite side. + - `RemoteSlot` - A slot that represents the data on the opposing side, syncing when the data is not consistent. +- `net.minecraft.world.item` + - `EitherHolder#key` - Returns the resource key of the held registry object. + - `Item#STREAM_CODEC` + - `ItemStack` + - `OPTIONAL_UNTRUSTED_STREAM_CODEC` + - `MAP_CODEC` + - `canDestroyBlock` - Returns whether this item can destroy the provided block state. +- `net.minecraft.world.item.alchemy.PotionContents#getPotionDescription` - Returns the description of the mob effect with some amplifier. +- `net.minecraft.world.item.crafting` + - `Recipe#KEY_CODEC` + - `TransmuteResult` - A recipe result object that represents an item, count, and the applied components. +- `net.minecraft.world.item.equipment.trim.ArmorTrim#layerAssetId` - Returns the location of the the trim asset. +- `net.minecraft.world.level` + - `BlockGetter$BlockStepVisitor` - A consumer that takes in the current position and how many collisions within the desired path of travel. + - `ColorMapColorUtil` - A helper for getting the color from a map given the biome's temperature, downfall, colormap, and default color. + - `DryFoliageColor` - A color resolver for biomes with dry foliage. + - `GameRules` + - `getType` - Gets the game rule type from its key. + - `keyCodec` - Creates the codec for the key of a game rule type. + - `Level` + - `isMoonVisible` - Returns wehther the moon is currently visible in the sky. + - `getPushableEntities` - Gets all entities except the specified target within the provided bounding box. + - `getClientLeafTintColor` - Returns the color of the leaf tint at the specified location. + - `playPlayerSound` - Plays a sound to the current player on the client. + - `LevelReader#getHeight` - Returns the height of the map at the given position. + - `NaturalSpawner#INSCRIBED_SQUARE_SPAWN_DISTANCE_CHUNK` - Provides the minimum distance that the player is close enough for spawning to occur. +- `net.minecraft.world.level.biome` + - `Biome` + - `getDryFoliageColor`, `getDryFoliageColorFromTexture` - Gets the dry foliage color of the biome, either from the effects or from the climate settings. + - `BiomeSpecialEffects#getDryFoliageColorOverride`, `$Builder#dryFoliageColorOverride` - Returns the default dry foliage color when not pulling from a colormap texture. +- `net.minecraft.world.level.block` + - `BaseFireBlock#fireIgnite` - Lights an entity on fire. + - `Block` + - `UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS` - A flag that skips all potential sideeffects when updating a block entity. + - `UPDATE_SKIP_ALL_SIDEEFFECTS` - A flag that skips all sideeffects by skipping certain block entity logic, supressing drops, and updating the known shape. + - `UPDATE_SKIP_ON_PLACE` - A flag that skips calling `BlockState#onPlace` when set. + - `BonemealableBlock#hasSpreadableNeighbourPos`, `findSpreadableNeighbourPos` - Handles finding other positions that the vegetation can spread to on bonemeal. + - `CactusFlowerBlock` - A flower that grows on a cactus. + - `FireflyBushBlock` - A bush that spawns firefly particles around it. + - `SandBlock` - A colored sand block that can play ambient sounds. + - `SegmentableBlock` - A block that can typically be broken up into segments with unique sizes and placements. + - `ShortDryGrassBlock` - A single grass block that has been dried out. + - `TallDryGrassBlock` - A double grass block that has been dried out. + - `TerracottaBlock` - A terracotta block that can play ambient sounds. + - `TintParticleLeavesBlock` - A leaves block whose particles are tinted. + - `UntintedParticleLeavesBlock` - A leaves block whose particles are not tinted. + - `VegetationBlock` - A block that represents some sort of vegetation that can propogate light and need some sort of farmland or dirt to survive. +- `net.minecraft.world.level.block.entity.StructureBlockEntity#isStrict`, `setStrict` - Sets strict mode when generating structures. +- `net.minecraft.world.level.block.sounds.AmbientDesertBlockSoundsPlayer` - A helper to play sounds for a given block, typically during `animateTick`. +- `net.minecraft.world.level.block.state.BlockBehaviour#getEntityInsideCollisionShape` - Gets the collision shape of the block when the entity is within it. +- `net.minecraft.world.level.border.WorldBorder` + - `closestBorder` - Returns a list of the closest borders to the player based on their horizontal direction. + - `$DistancePerDirection` - A record containing the distance from the entity of the world border in a given direction. +- `net.minecraft.world.level.chunk.status.ChunkStatus#CODEC` +- `net.minecraft.world.level.entity.PersistentEntitySectionManager#isTicking` - Returns whether the specified chunk is currently ticking. +- `net.minecraft.world.level.levelgen.Heightmap$Types#STREAM_CODEC` +- `net.minecraft.world.level.levelgen.feature` + - `AbstractHugeMushroomFeature#placeMushroomBlock` - Places a mushroom block that specified location, replacing a block if it can. + - `FallenTreeFeature` - A feature that generates flane trees with a stump of given lengths. + - `TreeFeature#getLowestTrunkOrRootOfTree` - Retruns the lowest block positions of the tree decorator. +- `net.minecraft.world.level.levelgen.feature.configurations.FallenTreeConfiguration` - A configuration for fallen trees with stumps. +- `net.minecraft.world.level.levelgen.feature.treedecorators` + - `AttachedToLogsDecorator` - A decorator that attaches a random block to a given direction on a log with a set probability. + - `PlaceOnGroundDecorator` - A decorator that places the tree on a valid block position. +- `net.minecraft.world.level.levelgen.structure.pools` + - `ListPoolElement#getElements` - Returns the elements of the structure pool. + - `SinglePoolElement#getTemplateLocation` - Returns the location of the template used by the element. + - `StructureTemplatePool#getTemplates` - Returns a list of elements with their weights. +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure` + - `getStartPool` - Returns the starting pool of the jigsaw to generate. + - `getPoolAliases` - Returns all pools used by the jigsaw. +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate#getDefaultJointType` - Returns the default join type between two jigsaw pieces if none is specified or an error occurs during loading. +- `net.minecraft.world.level.material.Fluid#getAABB`, `FluidState#getAABB` - Returns the bounding box of the fluid. +- `net.minecraft.world.scores` + - `Objective#pack`, `$Packed` - Handles the serializable form of the objective data. + - `PlayerTeam#pack`, `$Packed` - Handles the serializable form of the player team data. + - `Scoreboard` + - `loadPlayerTeam`, `loadObjective` - Loads the data from the packed object. + - `$PackedScore` - Handles the serializable form of the scoreboard data. +- `net.minecraft.world.level.storage.loot.LootTable#KEY_CODEC` +- `net.minecraft.world.phys` + - `AABB$Builder` - A builder for constructing a bounding box by providing the vectors within. + - `Vec2#CODEC` +- `net.minecraft.world.phys.shapes.CollisionContext` + - `placementContext` - Constructs the context when placing a block from its item. + - `isPlacement` - Returns whether the context is being used for placing a block. +- `net.minecraft.world.ticks.TickPriority#CODEC` + +### List of Changes + +- `net.minecraft.client.Screenshot` is now a utility instead of an instance class, meaning all instance methods are removed + - `takeScreenshot(RenderTarget)` -> `takeScreenshot(RenderTarget, Consumer)`, not returning anything +- `net.minecraft.client.multiplayer` + - `ClientChunkCache#replaceWithPacketData` now takes in a `Map` instead of a `CompoundTag` + - `MultiPlayerGameMode#hasInfiniteItems` -> `net.minecraft.world.entity.LivingEntity#hasInfiniteMaterials` + - `ClientPacketListener#markMessageAsProcessed` now takes in a `MessageSignature` instead of a `PlayerChatMessage` +- `net.minecraft.client.multiplayer.chat.ChatListener#handleChatMessageError` now takes in a nullable `MessageSignature` +- `net.minecraft.client.player` + - `ClientInput#leftImpulse`, `forwardImpulse` -> `moveVector`, now protected + - `LocalPlayer#spinningEffectIntensity`, `oSpinningEffectIntensity` -> `portalEffectIntensity`, `oPortalEffectIntensity` +- `net.minecraft.client.renderer.LevelRenderer#getLightColor(BlockAndTintGetter, BlockState, BlockPos)` -> `getLightColor(LevelRenderer$BrightnessGetter, BlockAndTintGetter, BlockState, BlockPos)` +- `net.minecraft.client.renderer.blockentity.BlockEntityRenderer#render` now takes in a `Vec3` representing the camera's position +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` + - `$RenderSection` + - `getOrigin` -> `getRenderOrigin` + - `reset` is now public + - `releaseBuffers` is removed + - `$CompileTask#getOrigin` -> `getRenderOrigin` +- `net.minecraft.client.renderer.entity` + - `DonkeyRenderer` now takes in a `DonekyRenderer$Type` containing the textures, model layers, and equipment information + - `ItemEntityRenderer#renderMultipleFromCount` now has an overload that takes in the model bounding box + - `UndeadHorseRenderer` now takes in a `UndeadHorseRenderer$Type` containing the textures, model layers, and equipment information +- `net.minecraft.client.renderer.entity.layers` + - `EquipmentLayerRenderer$TrimSpriteKey#textureId` -> `spriteId` + - `VillagerProfessionLayer#getHatData` now takes in a map of resource keys to metadata sections and swaps the registry and value for a holder instance +- `net.minecraft.client.renderer.item` + - `ConditionalItemModel` now takes in a `ItemModelPropertyTest` instead of a `ConditionalItemModelProperty` + - `SelectItemModel` now takes in a `$ModelSelector` instead of an object map +- `net.minecraft.client.renderer.item.properties.conditional.ConditionalItemModelProperty` now implements `ItemModelPropertyTest` + - `ItemModelPropertyTest` holds the `get` method previously within `ConditionalItemModelProperty` +- `net.minecraft.commands.arguments` + - `ComponentArgument` + - `ERROR_INVALID_JSON` -> `ERROR_INVALID_COMPONENT` + - `getComponent` -> `getRawComponent` + - `ResourceKeyArgument#getRegistryKey` is now public + - `StyleArgument#ERROR_INVALID_JSON` -> `ERROR_INVALID_STYLE` +- `net.minecraft.commands.arguments.item` + - `ComponentPredicateParser$Context#createComponentTest`, `createPredicateTest` now takes in a `Dynamic` instead of a `Tag` + - `ItemPredicateArgument` + - `$ComponentWrapper#decode` now takes in a `Dynamic` instead of a `RegistryOps`, `Tag` pair + - `$PredicateWrapper#decode` now takes in a `Dynamic` instead of a `RegistryOps`, `Tag` pair +- `net.minecraft.core` + - `BlockMath` + - `VANILLA_UV_TRANSFORM_LOCAL_TO_GLOBAL`, `VANILLA_UV_TRANSFORM_GLOBAL_TO_LOCAL` is now private + - `getUVLockTransform` -> `getFaceTransformation` + - `Direction#rotate` now takes in a `Matrix4fc` instead of a `Matrix4f` + - `Rotations` is now a record +- `net.minecraft.data.loot.BlockLootSubProvider#createPetalDrops` -> `createSegmentedBlockDrops` +- `net.minecraft.network` + - `FriendlyByteBuf` + - `writeLongArray`, `readLongArray` now have static delegates which take in the `ByteBuf` and `*Fixed*` versions for fixed size arrays + - `ProtocolInfo$Unbound` -> `$Details`, `net.minecraft.network.protocol.SimpleUnboundProtocol`, `net.minecraft.network.protocol.UnboundProtocol`; not one-to-one + - `#bind` -> `net.minecraft.network.protocol.SimpleUnboundProtocol#bind`, `UnboundProtocol#bind`; not one-to-one + - `SkipPacketException` is now an interface instead of a subclass of `EncoderException` +- `net.minecraft.network.chat` + - `ComponentSerialization#flatCodec` -> `flatRestrictedCodec` + - `LastSeenMessages$Update` now takes in a byte representing the checksum value + - `LastSeenMessagesValidator` + - `applyOffset` now returns nothing and can throw a `$ValidationException` + - `applyUpdate` now returns the raw messages and can throw a `$ValidationException` +- `net.minecraft.network.codec.StreamCodec#composite` now has an overload for nine parameters +- `net.minecraft.network.protocol.ProtocolInfoBuilder` now takes in a third generic representing how to modify the provided codec. + - `addPacket` now has an overload that takes in a `CodecModifier` + - `build` -> `buildUnbound`, not one-to-one + - `protocol`, `serverboundProtocol`, `clientboundProtocol` now returns a `SimpleUnboundProtocol` +- `net.minecraft.network.protocol.ConfigurationProtocols` now contain `SimpleUnboundProtocol` constants +- `net.minecraft.network.protocol.game` + - `ClientboundContainerSetContentPacket` is now a record + - `ClientboundMoveEntityPacket#getyRot`, `getxRot` -> `getYRot`, `getXRot` + - `ClientboundPlayerChatPacket` now takes in a global index for the chat message + - `ClientboundLevelChunkPacketdata#getHeightmaps` now returns a `Map` + - `ClientboundUpdateAdvancementsPacket` now takes in a boolean representing whether to show the adavncements as a toast + - `GameProtocols` constants are now either `SimpleUnboundProtocol`s or `UnboundProtocol`s + - `ServerboundContainerClickPacket` is now a record + - `ServerboundMovePlayerPacket$Pos`, `$PosRot` now has an overload that takes in a `Vec3` for the position + - `ServerboundSetStructureBlockPacket` now takes in an additional boolean representing whether the structure should be generated in strict mode +- `net.minecraft.network.protocol.handshake.HandshakeProtocols#SERVERBOUND_TEMPLATE` is now a `SimpleUnboundProtocol` +- `net.minecraft.network.protocol.login.LoginProtocols#SERVERBOUND_TEMPLATE` constants are now `SimpleUnboundProtocol`s +- `net.minecraft.network.protocol.status.StatusProtocols#SERVERBOUND_TEMPLATE` constants are now `SimpleUnboundProtocol`s +- `net.minecraft.server.PlayerAdvancements#flushDirty` now takes in a boolean that represents whether the advancements show display as a toast +- `net.minecraft.server.bossevents.CustomBossEvent` + - `save` -> `pack`, not one-to-one + - `load` now takes in the id and the packed variant to unpack +- `net.minecraft.server.level` + - `DistanceManager` + - `hasPlayersNearby` now returns a `TriState` + - `forEachBlockTickingChunks` -> `forEachEntityTickingChunk`, not one-to-one + - `ServerEntity` now takes in a consumer for broadcasting a packet to all players but those in the ignore list + - `ServerLevel` + - `getForcedChunks` -> `getForceLoadedChunks` + - `isPositionTickingWithEntitiesLoaded` is now public + - `isNaturalSpawningAllowed` -> `canSpawnEntitiesInChunk`, `BlockPos` variant is removed + - `ServerPlayer` + - `getRespawnPosition`, `getRespawnAngle`, `getRespawnDimension`, `isRespawnForced` -> `getRespawnConfig`, not one-to-one + - `setRespawnPosition` now takes in a `$RespawnConfig` instead of the individual respawn information + - `loadAndSpawnParentVehicle`, `loadAndSpawnEnderpearls` now takes in a `CompoundTag` without the optional wrapping\ +- `net.minecraft.server.network.ServerGamePacketListenerImpl` now implements `GameProtocols$Context` +- `net.minecraft.sounds.SoundEvents` have the following sounds now `Holder` wrapped: + - `ITEM_BREAK` + - `SHIELD_BLOCK`, `SHIELD_BREAK`, + - `WOLF_ARMOR_BREAK` +- `net.minecraft.util` + - `Brightness` + - `FULL_BRIGHT` is now final + - `pack` now has a static overload that takes in the block and sky light. + - `ExtraCodecs#MATRIX4f` now is a `Codec` + - `Util#makeEnumMap` returns the `Map` superinstance rather than the specific `EnumMap` +- `net.minecraft.util.parsing.packrat.commands.TagParseRule` now takes in a generic for the tag type + - The construct is now public, taking in a `DynamicOps` +- `net.minecraft.util.profiling` + - `ActiveProfiler` now takes in a `BooleanSupplier` instead of a boolean + - `ContinuousProfiler` now takes in a `BooleanSupplier` instead of a boolean +- `net.minecraft.util.worldupdate.WorldUpgrader` now takes in the current `WorldData` +- `net.minecraft.world` + - `BossEvent$BossBarColor`, `$BossBarOverlay` now implements `StringRepresentable` + - `Container` now implements `Iterable` +- `net.minecraft.world.effect` + - `MobEffect` + - `getBlendDurationTicks` -> `getBlendInDurationTicks`, `getBlendOutDurationTicks`, `getBlendOutAdvanceTicks`; not one-to-one + - `setBlendDuration` now has an overload that takes in three integers to set the blend in, blend out, and blend out advance ticks + - `MobEffectInstance#tick` -> `tickServer`, `tickClient`; not one-to-one +- `net.minecraft.world.entity` + - `Entity` + - `cancelLerp` -> `InterpolationHandler#cancel` + - `lerpTo` -> `moveOrInterpolateTo` + - `lerpTargetX`, `lerpTargetY`, `lerpTargetZ`, `lerpTargetXRot`, `lerpTargetYRot` -> `getInterpolation` + - `onAboveBubbleCol` -> `onAboveBubbleColumn` now takes in a `BlockPos` for the bubble column particles spawn location + - Logic delegates to the protected static `handleOnAboveBubbleColumn` + - `isControlledByOrIsLocalPlayer` -> `isLocalInstanceAuthoritative`, now final + - `isControlledByLocalInstance` -> `isLocalClientAuthoritative`, now protected + - `isControlledByClient` -> `isClientAuthoritative` + - `fallDistance`, `causeFallDamage` is now a double + - `absMoveto` -> `absSnapTo` + - `absRotateTo` -> `asbSnapRotationTo` + - `moveTo` -> `snapTo` + - `sendBubbleColumnParticles` is now static, taking in the `Level` + - `onInsideBubbleColumn` logic delegates to the protected static `handleOnInsideBubbleColumn` + - `EntityType` + - `POTION` -> `SPLASH_POTION`, `LINGERING_POTION`, not one-to-one + - `$EntityFactory#create` can now return a null instance + - `ExperienceOrb#value` -> `DATA_VALUE` + - `ItemBasedSteering` no longer takes in the accessor for having a saddle + - `LivingEntity` + - `lastHurtByPlayerTime` -> `lastHurtByPlayerMemoryTime` + - `lerpSteps`, `lerpX`, `lerpY`, `lerpZ`, `lerpYRot`, `lerpXRot` -> `interpolation`, not one-to-one + - `isAffectedByFluids` is now public + - `removeEffectNoUpdate` is now final + - `tickHeadTurn` now returns nothing + - `canDisableShield` -> `canDisableBlocking`, now set via the `WEAPON` data component + - `calculateFallDamage` now takes in a double instead of a float + - `Mob` + - `handDropChances`, `armorDropChances`, `bodyArmorDropChance` -> `dropChances`, not one-to-one + - `getEquipmentDropChance` -> `getDropChances`, not one-to-one +- `net.minecraft.world.entity.ai.Brain#addActivityWithConditions` now has an overload that takes in an integer indiciating the starting priority +- `net.minecraft.world.entity.ai.behavior` + - `LongJumpToRandomPos$PossibleJump` is now a record + - `VillagerGoalPackages#get*Package` now takes in a holder-wrapped profession +- `net.minecraft.world.entity.ai.gossip.GossipContainer#store`, `update` -> `clear`, `putAll`, `copy`; not one-to-one +- `net.minecraft.world.entity.animal` + - `Pig` is now a `VariantHolder` + - `Sheep` -> `.sheep.Sheep` + - `WaterAnimal#handleAirSupply` now takes in a `ServerLevel` +- `net.minecraft.world.entity.animal.axolotl.Axolotl#handleAirSupply` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.ZombieVillager#setGossips` now takes in a `GossipContainer` +- `net.minecraft.world.entity.monster.warden.WardenSpawnTracker` now has an overload which sets the initial parameters to zero +- `net.minecraft.world.entity.npc` + - `Villager` now takes in either a key or a holder of the `VillagerType` + - `setGossips` now takes in a `GossipContainer` + - `VillagerData` is now a record + - `set*` -> `with*` + - `VillagerProfession` now takes in a `Component` for the name + - `VillagerTrades` + - `TRADES` now takes in a resource key as the key of the map + - This is similar for all other type specific trades + - `$FailureItemListing` is now private +- `net.minecraft.world.entity.player.Player` + - `stopFallFlying` -> `LivingEntity#stopFallFlying` + - `isSpectator`, `isCreative` no longer abstract in the `Player` class +- `net.minecraft.world.entity.projectile.ThrownPotion` -> `AbstractThrownPotion`, implemented in `ThrownLingeringPotion` and `ThrownSplashPotion` +- `net.minecraft.world.entity.raid.Raid(int, ServerLevel, BlockPos)` -> `Raid(BlockPos, Difficulty)` + - `tick`, `addWaveMob` now takes in the `ServerLevel` +- `net.minecraft.world.entity.vehicle` + - `AbstractMinecart#setDisplayBlockState` -> `setCustomDisplayBlockState` + - `MinecartBehavior` + - `cancelLerp` -> `InterpolationHandler#cancel` + - `lerpTargetX`, `lerpTargetY`, `lerpTargetZ`, `lerpTargetXRot`, `lerpTargetYRot` -> `getInterpolation` + - `MinecartTNT#primeFuse` now takes in the `DamageSource` cause +- `net.minecraft.world.inventory` + - `AbstractContainerMenu` + - `setRemoteSlotNoCopy` -> `setRemoteSlotUnsafe`, not one-to-one + - `setRemoteCarried` now takes in a `HashedStack` + - `ClickType` now takes in an id for its representations + - `ContainerSynchronizer#sendInitialData` now takes in a list of stacks rather than a `NonNullList` +- `net.minecraft.world.item` + - `EitherHolder` now takes in an `Either` instance rather than just an `Optional` holder and `ResourceKey` + - `Item` + - `canAttackBlock` -> `canDestroyBlock` + - `hurtEnemy` no longer returns anything + - `onCraftedBy` no longer takes in a separate `Level` instance, now relying on the one provided by the `Player` + - `ItemStack` + - `validateStrict` is now public + - `onCraftedBy` no longer takes in a separate `Level` instance, now relying on the one provided by the `Player` + - `MapItem` + - `create` now takes in a `ServerLevel` instead of a `Level` + - `lockMap` is now private + - `ThrowablePotionItem` is now abstract, containing two methods to create the `AbstractThrownPotion` entity + - `WrittenBookItem#resolveBookComponents` -> `WrittenBookContent#resolveForItem` +- `net.minecraft.world.item.alchemy.PotionContents` now implements `TooltipProvider` + - `forEachEffect`, `applyToLivingEntity` now takes in a float representing a scalar for the duration +- `net.minecraft.world.item.component.WrittenBookContent` now implements `TooltipProvider` +- `net.minecraft.world.item.crafting` + - `SmithingRecipe#baseIngredient` now returns an `Ingredient` + - `SmithingTransformRecipe` now takes in a `TransmuteResult` instead of an `ItemStack` and an `Ingredient` for the base + - `SmithingTrimRecipe` now takes in `Ingredient`s instead of `Optional` wrapped entries along with a `TrimPattern` holder + - `TransmuteRecipe` now takes in a `TransmuteResult` instead of an `Item` holder +- `net.minecraft.world.item.crafting.display.SlotDisplay$SmithingTrimDemoSlotDisplay` now takes in a `TrimPattern` holder +- `net.minecraft.world.item.enchantment.EnchantmentInstance` is now a record +- `net.minecraft.world.level` + - `BlockGetter#boxTraverseBlocks` -> `forEachBlockIntersectedBetween`, not one-to-one + - `CustomSpawner#tick` no longer returns anything + - `GameRules$Type` now takes in a value class + - `Level` + - `onBlockStateChange` -> `updatePOIOnBlockStateChange` + - `isDay` -> `isBrightOutside` + - `isNight` -> `isDarkOutside` + - `setMapData` -> `net.minecraft.server.level.ServerLevel#setMapData` + - `getFreeMapId` -> `net.minecraft.server.level.ServerLevel#getFreeMapId` + - `LevelAccessor#blockUpdated` -> `updateNeighborsAt` +- `net.minecraft.world.level.biome.MobSpawnSettings$SpawnerData` is now a record +- `net.minecraft.world.level.block` + - `AttachedStemBlock` now extends `VegetationBlock` + - `AzaleaBlock` now extends `VegetationBlock` + - `Block#fallOn` now takes a double for the fall damage instead of a float + - `BushBlock` now extends `VegetationBlock` and implements `BonemealableBlock` + - `ColoredFallingBlock#dustColor` is now protected + - `CropBlock` now extends `VegetationBlock` + - `DeadBushBlock` -> `DryVegetationBlock` + - `DoublePlantBlock` now extends `VegetationBlock` + - `FallingBlock#getDustColor` is now abstract + - `FlowerBedBlock` now extends `VegetationBlock` + - `FlowerBlock` now extends `VegetationBlock` + - `FungusBlock` now extends `VegetationBlock` + - `LeafLitterBlock` now extends `VegetationBlock` + - `LeavesBlock` is now abstract, taking in the chance for a particle to spawn + - Particles are spawned via `spawnFallingLeavesParticle` + - `MangroveLeavesBlock` now extends `TintedParticleLeavesBlock` + - `MushroomBlock` now extends `VegetationBlock` + - `NetherSproutsBlock` now extends `VegetationBlock` + - `NetherWartBlock` now extends `VegetationBlock` + - `ParticleLeavesBlock` -> `LeafLitterBlock` + - `PinkPetalsBlock` -> `FlowerBedBlock` + - `RootsBlock` now extends `VegetationBlock` + - `Rotation` now has an index used for syncing across the network + - `SaplingBlock` now extends `VegetationBlock` + - `SeagrassBlock` now extends `VegetationBlock` + - `SeaPickleBlock` now extends `VegetationBlock` + - `StemBlock` now extends `VegetationBlock` + - `SweetBerryBushBlock` now extends `VegetationBlock` + - `TallGrassBlock` now extends `VegetationBlock` + - `TntBlock#prime` now returns whether the primed tnt was spawned. + - `WaterlilyBlock` now extends `VegetationBlock` +- `net.minecraft.world.level.block.entity` + - `BlockEntity` + - `parseCustomNameSafe` now takes in a nullable `Tag` instead of a string + - `getPosFromTag` now takes in the `ChunkPos` + - `$ComponentHolder#COMPONENTS_CODEC` is now a `MapCodec` + - `BLockEntityType#create` is no longer nullable +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner#codec` now returns a `MapCodec` +- `net.minecraft.world.level.block.state.StateHolder` + - `getNullableValue` is now private + - `hasProperty` no longer contains a generic +- `net.minecraft.world.level.chunk` + - `ChunkAccess#setBlockState` now takes in the block flags instead of a boolean, and has an overload to update all set + - `LevelChunk#replaceWithPacketData` now takes in a `Map` instead of a `CompoundTag` +- `net.minecraft.world.level.chunk.storage.SerializableChunkData#getChunkTypeFromTag` -> `getChunkStatusFromTag`, not one-to-one +- `net.minecraft.world.level.gameevent.vibrations.VibrationSystem#DEFAULT_VIBRATION_FREQUENCY` -> `NO_VIBRATION_FREQUENCY` +- `net.minecraft.world.level.levelgen.feature.TreeFeature#isVine` is now public +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `Direct` -> `DirectPoolAlias` + - `Random` -> `RandomPoolAlias` + - `RandomGroup` -> `RandomGroupPoolAlias` +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate$JigsawBlockInfo` now takes in a `ResourceKey` to the `StructureTemplatePool` instead of a raw `ResourceLocation` +- `net.minecraft.world.level.saveddata.maps.MapFrame` is now a record + - `save`, `load` -> `CODEC`, not one-to-one +- `net.minecraft.world.level.storage.loot.functions.SetWrittenBookPagesFunction#PAGE_CODEC` -> `WrittenBookContent#PAGES_CODEC` +- `net.minecraft.world.scores` + - `Score#write` -> `CODEC`, not one-to-one + - `Scoreboard` + - `savePlayerScores` -> `packPlayerScores`, not one-to-one + - `loadPlayerScores` -> `loadPlayerScore`, not one-to-one + - `Team$CollisionRule`, `$Visibility` are now `StringRepresentable` +- `net.minecraft.world.phys.shapes.EntityCollisionContext` now takes in a boolean representing if it is used for placing a block +- `net.minecraft.world.ticks.SavedTick` + - `loadTick`, `saveTick`, `save` -> `codec`, not one-to-one + - `loadTickList` -> `filterTickListForChunk`, not one-to-one + +### List of Removals + +- `com.mojang.blaze3d.vertex.BufferUploader` +- `net.minecraft.core.Rotations#getWrapped*` +- `net.minecraft.network.chat.ComponentSerialization#FLAT_CODEC` +- `net.minecraft.network.protocol.game` + - `ClientboundAddExperimentOrbPacket` + - `ClientGamePacketListener#handleAddExperienceOrb` +- `net.minecraft.resources.ResourceLocation$Serializer` +- `net.minecraft.server.network.ServerGamePacketListenerImpl#addPendingMessage` +- `net.minecraft.world` + - `BossEvent$BossBarColor#byName`, `$BossBarOverlay#byName` + - `Clearable#tryClear` +- `net.minecraft.world.effect.MobEffectInstance#save`, `load` +- `net.minecraft.world.entity` + - `Entity` + - `isInBubbleColumn` + - `isInWaterRainOrBubble`, `isInWaterOrBubble` + - `newDoubleList`, `newFloatList` + - `recordMovementThroughBlocks` + - `EntityEvent#ATTACK_BLOCKED`, `SHIELD_DISABLED` + - `ItemBasedSteering` + - `addAdditionalSaveData`, `readAdditionalSaveData` + - `setSaddle`, `hasSadddle` + - `LivingEntity` + - `timeOffs`, `rotOffs` + - `rotA` + - `oRun`, `run` + - `animStep`, `animStep0` + - `appliedScale` + - `canBeNameTagged` + - `Mob` + - `DEFAULT_EQUIPMENT_DROP_CHANCE` + - `PRESERVE_ITEM_DROP_CHANCE_THRESHOLD`, `PRESERVE_ITEM_DROP_CHANCE` + - `NeutralMob#setLastHurtByPlayer` + - `PositionMoveRotation#ofEntityUsingLerpTarget` +- `net.minecraft.world.entity.ai.attributes.AttributeModifier#save`, `load` +- `net.minecraft.world.entity.animal` + - `Dolphin#setTreasurePos`, `getTreasurePos` + - `Fox$Variant#byName` + - `MushroomCow$Variant#byName` + - `Panda$Gene#byName` + - `Salmon$Variant#byName` + - `Turtle` + - `getHomePos` + - `setTravelPos`, `getTravelPos` + - `isGoingHome`, `setGoingHome` + - `isTravelling`, `setTravelling` +- `net.minecraft.world.entity.animal.armadillo.Armadillo$ArmadilloState#fromName` +- `net.minecraft.world.entity.npc.VillagerTrades#EXPERIMENTAL_WANDERING_TRADER_TRADES` +- `net.minecraft.world.entity.projectile.AbstractArrow#getBaseDamage` +- `net.minecraft.world.entity.raid.Raid` + - `getLevel`, `getId` + - `save` +- `net.minecraft.world.entity.vehicle.AbstractMinecart#hasCustomDisplay`, `setCustomDisplay` +- `net.minecraft.world.item.ItemStack#parseOptional`, `saveOptional` +- `net.minecraft.world.item.equipment.trim.TrimPattern#templateItem` +- `net.minecraft.world.level.Level#updateNeighborsAt(BlockPos, Block)` +- `net.minecraft.world.level.block.entity` + - `CampfireBlockEntity#dowse` + - `PotDecorations#save`, `load` +- `net.minecraft.world.level.levelgen.BelowZeroRetrogen#read` +- `net.minecraft.world.level.levelgen.structure.structures.RuinedPortalPiece$VerticalPlacement#byName` +- `net.minecraft.world.level.saveddata.maps.MapBanner#LIST_CODEC` +- `net.minecraft.world.scores.Team` + - `$CollisionRule#byName` + - `$Visibility#getAllNames`, `byName` +- `net.minecraft.world.ticks.LevelChunkTicks#save`, `load` diff --git a/src/detailed-primers/1.21.6-from-1.21.5.md b/src/detailed-primers/1.21.6-from-1.21.5.md new file mode 100644 index 0000000..1ce79a0 --- /dev/null +++ b/src/detailed-primers/1.21.6-from-1.21.5.md @@ -0,0 +1,2203 @@ +# Minecraft 1.21.5 -> 1.21.6 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.5 to 1.21.6. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Soaryn for some `ItemStack` best practices and typo fixes +- @earthcomputer for color changes when drawing strings + +## 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](https://misode.github.io/versions/?id=1.21.6&tab=changelog). + +## GUI Changes + +The GUI rendering system has significantly changed from the previous version. While it may seem somewhat similar on the surface, the actual implementation details are much more complex and roundabout. This will explain a high-level overview of the new system with some basic examples. + +### Prepare and Render + +Rendering a GUI has been broken into two phases: 'prepare' and 'render'. + +The prepare phase is what we typically consider the GUI render methods (e.g., `Gui#render`, `AbstractContainerScreen#renderBg`, etc.). These methods, instead of actually rendering the components, now submit them to the `GuiRenderState` to be stored for use during the 'render' phase. The `GuiRenderState` is stored on the `GameRenderer` and passed to the `GuiGraphics` which uses the previous methods to add the desired objects to the render state. + +The render phase is what actually handles the rendering of all the objects. This is handled through the `GuiRenderer`, which reads the data from the `GuiRenderState` and, after a bit of delegated preparation and sorting, renders the objects to the screen. The `GuiRenderer` is also stored on the `GameRenderer`. + +### Element Ordering + +Now, how are elements rendered onto screen? In the previous versions, this happened mainly based on the order of the render calls. However, the new system using two different methods of sorting. The first method handles the depth using strata and a linear tree. The second method uses a comparator based on three things (in order of priorty): the `ScreenRectangle` scissor, the `RenderPipeline` order, and the `TextureSetup`'s hash code. These are all stored on the `GuiElementRenderState` passed to the `GuiRenderState` via `GuiRenderState#submitGuiElement`. + +Once the elements have been ordered, they are rendered starting at a Z of `0`, with each element rendered `0.01` ahead of the previous. + +As a warning, due to the element sort order, certain custom configurations may result in incorrect screen renders. As such, it is imperative that you understand how the methods and their assigned values work when sorting elements. + +#### Strata and Trees + +The first method of sorting handles the z-depth an object is rendered at. + +First let's start with the linear tree. As the name implies, it is basically a doubly-linked `GuiRenderState$Node` list. Each node contains its own list of elements to render. Navigating the node list is handled using `GuiRenderState#up` or `down`, where each either gets the next node, or creates a new one if it doesn't exist. Nodes within a given tree are rendered from bottom to top, meaning that `down` will render any elements submitted before the current node, while `up` will render any elements submitted after the current node. + +Determining what node an object is added to is computed automatically when submitting an element using its `ScreenArea`. The `ScreenArea` defines the `bounds` of your element to be rendered. Essentially, a node will be added in the `up` direction if the bounds of the element intersect with any other element on the current node. + +Then there are strata. A stratum is essentially a linear tree. Strata are rendered in the order they are created, which means calling `nextStratum` will render all elements after the previous stratum. This can be used if you want to group elements into a specific layer. Note: you cannot navigate to a prior stratum. + +#### The Comparator + +The comparator handles sorting the elements within a given node in a linear tree in a strata. + +##### Screen Rectangle Scissor + +The `ScreenRectangle` is simply the area that the element is allowed to draw to, stored via `GuiElementRenderState#scissorArea`. Elements with no specified `ScreenRectangle` will be ordered first, followed by the minimum Y, the maximum Y, the minimum X, and the maximum X. + +##### Render Pipeline + +`RenderPipeline`s define the pipeline used to render some object to the screen, including its shaders, format, uniforms, etc. This is stored via `GuiElementRenderState#pipeline`. Pipelines are sorted in the order they are built. This means that `RenderPipelines#ENTITY_TRANSLUCENT` will be rendered before `RenderPipelines#GUI` if on the same layer and scissor rectangle. As this is a system that relies on classloading constants, if you want to add new elements, make sure your mod loader supports some kind of dynamic pipeline ordering. + +##### Texture Hash Code + +`TextureSetup` defines `Sampler0`, `Sampler1`, and `Sampler2` for use in the render pipelines, stored via `GuiElementRenderState#textureSetup`. Elements with no textures will be ordered first, followed by `getSortKey` of the record object. Note that, at the moment, this returns the `hashCode` of the `TextureSetup`, which may be non-deterministic as `GpuTextureView` does not implement `hashCode`, relying instead on the identity object hash. + +### GuiElementRenderState + +Now that we understand ordering, what exactly is the `GuiElementRenderState` that we've been using? Well essentially, every object rendered to the screen is represented by a `GuiElementRenderState`, from the player seen in the inventory menu to each individual item. A `GuiElementRenderState` defines four methods. First, there are the common ones used for ordering and how to render to the screen (`pipeline`, `scissorArea`, `textureSetup`, `bounds`). Then there is `buildVertices`, which takes in the `VertexConsumer` to write the vertices to and the z-depth. For GUIs, this typically calls `VertexConsumer#addVertexWith2DPose`. + +There are three types of `GuiElementRenderState`s provided by vanilla: `BlitRenderState`, `ColoredRectangleRenderState`, `GlyphEffectRenderState`, and `GlyphRenderState`. `ColoredRectangleRenderState` and `GlyphRenderState`/`GlyphEffectRenderState` are simple cases for handling a basic color rectangle and text character, respectively. `BlitRenderState` covers every other case as almost every method eventually writes to a `GpuTexture` which is then consumed by this. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState$Node#submitGuiElement`. The `GuiRenderState` makes `submitBlitToCurrentLayer` and `submitGlyphToCurrentLayer` available to add textures and glyphs. For example, these are called by `GuiGraphics#*line`, `fill`, and `blit*` methods. + +#### GuiItemRenderState + +`GuiItemRenderState` is a special case used to render an item to the screen. It takes in the stringified name of the item, the current pose, its XY coordinates, and its scissor area. The `ItemStackRenderState` it holds is what defines how the item is rendered. The rendering bounds are computed based on the item model bounding box when `ClientItem$Properties#oversizedInGui` is true; otherwise, using a 16x16 square when false. + +Just before the 'render' phase, the `GuiRenderer` effectively turns the `GuiItemRenderState` into a `GuiElementRenderState`, more specifically a `BlitRenderState`. This is done by constructing an item atlas `GpuTexture` which the item is drawn to, and then that texture is submitted as a `BlitRenderState`. All `GuiItemRenderState`s use `RenderPipelines#GUI_TEXTURED_PREMULTIPLIED_ALPHA`. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitItem`. This is called by `GuiGraphics#render*Item*` methods. + +#### GuiTextRenderState + +`GuiTextRenderState` is a special case used to render text to the screen. It takes in the `Font`, `FormattedCharSequence`, current pose, its XY coordinates, color, background color, whether it has a drop shadow, and its rendering bounds. + +Just before the 'render' phase, the `GuiRenderer` turns the `GuiTextRenderState` into a `GuiElementRenderState`, more specifically a `GlyphRenderState` or `GlyphEffectRenderState` depending on what should be rendered via `GuiTextRenderState#ensurePrepared`. This performs a similar process as the item render state where the text is written to a `GpuTexture` to be consumed. Any backgrounds are rendered first, followed by the background effects, then the character, then finally the foreground effects. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitText`. This is called by `GuiGraphics#draw*String` and `render*Tooltip` methods. + +#### Picture-in-Picture + +Picture-in-Picture is a special case used to render arbitrary objects to a `GpuTexture` to be passed into a `BlitRenderState`. A Picture-in-Picture is made up of two components the `PictureInPictureRenderState`, and the `PictureInPictureRenderer`. + +`PictureInPictureRenderState` is an interface which can store some data used to render the object to the texture. By default, it must supply the minimum and maximum XY coordinates, the texture scale, its scissor area, and its rendering bounds. You can also choose to specify the transformation matrix via `pose`. Any other data can be added by the implementor. + +```java +public record ExamplePIPRenderState(boolean data, int x0, int x1, int y0, int y1, float scale, @Nullable ScreenRectangle scissorArea, @Nullable ScreenRectangle bounds) + implements PictureInPictureRenderState {} +``` + +`PictureInPictureRenderer` is the renderer which writes the data to the `GpuTexture`. It does this by taking advantage of the fact that the `RenderSystem#output*Override` textures are written to in a `BufferSource` if they are not null. A `PictureInPictureRenderer` method must implement three methods. `getRenderStateClass` returns the class of the `PictureInPictureRenderState` implementation. `getTextureLabel` returns the texture label for debugging purposes. `renderToTexture` is where the render logic is called to write the data to the texture. + +```java +public class ExamplePIPRenderer extends PictureInPictureRenderer { + + // Takes in the buffer source from `RenderBuffers` + public ExamplePIPRenderer(MultiBufferSource.BufferSource bufferSource) { + super(bufferSource); + } + + @Override + public Class getRenderStateClass() { + // The class of the render state + return ExamplePIPRenderState.class; + } + + @Override + protected void renderToTexture(ExamplePIPRenderState renderState, PoseStack pose) { + // Render whatever you want here + // You can make use of the buffer source via `this.bufferSource` + } + + @Override + protected void blitTexture(ExamplePIPRenderState renderState, GuiRenderState guiState) { + // You can override this if you want to change how your layer is submitted to the render state + // By default, this uses the `BlitRenderState` + + // Remove this if you want to handle submission yourself + super.blitTexture(renderState, guiState); + } + + @Override + protected boolean textureIsReadyToBlit(ExamplePIPRenderState renderState) { + // When true, this will skip setting up the textures and projection matrices and use whatever is currently available + return false; + } + + @Override + protected String getTextureLabel() { + // This can be anything, but it should be unique + return "examplemod: example pip"; + } +} +``` + +To be able to use the renderer, is must be added to `GuiRenderer#pictureInPictureRenderers`. As the constructor takes in an immutable list while the renderer stores an immutable map, use whatever method is provided by your mod loader. + +```java +// We will assume: +// - `GuiRenderer#bufferSource` is accessible +// - The map is made mutable +// For some GuiRenderer renderer + +var examplePIP = new ExamplePIPRenderer(renderer.bufferSource); + +renderer.pictureInPictureRenderers.put( + examplePIP.getRenderStateClass(), + examplePIP +); +``` + +`PictureInPictureRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitPicturesInPictureState`. This is called by `GuiGraphics#submit*RenderState` methods. + +### Logic Changes + +`GuiGraphics#drawString` now joins the rest of the `GuiGraphics` methods by allowing the `int` color argument to accept an alpha channel (upper eight bits). This means that any color string without an alpha specified will not be rendered. Previous behavior can be replicated by ORing your `int` color with `0xFF000000` or by passing your color into `ARGB#opaque`. + +### Contextual Bars + +Many HUD elements on the screen take over where the experience bar is rendered. However, how these are rendered and which one is prioritized is handled through the contextual bar system. A contextual bar is made up of two parts, the `ContextualBarRenderer`, responsible for rendering the bar to the screen, and the `Gui$ContextualInfo`, which is used as the bar's identifier. + +A `ContextualBarRenderer` requires two methods to be implemented: `renderBackground`, which renders the bar itself, and `render`, which renders elements that appear on top of the bar. + +```java +public class ExampleContextualBarRenderer implements ContextualBarRenderer { + + @Override + public void renderBackground(GuiGraphics graphics, DeltaTracker delta) { + // Render background bar sprites here + } + + @Override + public void render(GuiGraphics graphics, DeltaTracker delta) { + // Render anything that might sit on top of the bar + } +} +``` + +`Gui$ContextInfo` is an enum, so your mod loader will need to either allow extensions or some other method of identifying a bar renderer. Then, the renderer needs to be added to map of renderers stored in `Gui#contextualInfoBarRenderers`. As this is an immutable map, use whatever method is provided by your mod loader. + +```java +// We will assume: +// - Created a new enum value `EXAMPLEMOD_EXAMPLE` +// - The map is made mutable +// For some Gui gui +gui.contextualInfoBarRenderers.put( + EXAMPLEMOD_EXAMPLE, + ExampleContextualBarRenderer::new +); +``` + +Finally, to get your bar to be called and prioritized, you need to modify `Gui#nextContextualInfoState` to return your enum value, or whatever method is provided by your mod loader. + +### Dialogs + +To more generally handle screens which provide some basic functionalities -- such as confirmation screens, button selection, or user input, Vanilla has provided a generic dialog system. These dialogs can be constructed in a datapack and delivered on the client by calling `Player#openDialog`. The basic JSON description is documented in [Minecraft Snapshot 25w20a](https://www.minecraft.net/en-us/article/minecraft-snapshot-25w20a). + +For a quick overview, a basic `Dialog` contains the following components: a title, an optional external title for navigation, whether the screen can be closed by pressing 'esc', and its `DialogBody` contents. Everything else is determined by the dialog itself, but it has functionality for user inputs via `InputControl`s. Buttons are typically added through `ClickAction`s which hold the common button data and an event to execute on click. If the dialog is canceled (e.g., closed), then `onCancel` is run. + +`DialogBody` and `InputControl` are simply generic interfaces that have no defined structure. Implementing them, or any dialog for that matter, requires some registration to the available types on both the client and server. + +#### Custom Bodies + +A `DialogBody` is simply the contents of a dialog screen. This is generally immutable information that should be displayed at all times. Every dialog holds a list of these `DialogBody`s as every screen has some text to explain what it is for. It only contains one method `mapCodec`, which is used as the registry key and encoder for the body information. + +```java +// Obviously, a body would have actual contents, but this is simply an example implementation +public record ExampleDialogBody(boolean val1, int val2) implements DialogBody { + public static final MapCodec BODY_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.BOOL.fieldOf("val1").forGetter(ExampleDialogBody::val1), + Codec.INT.fieldOf("val2").forGetter(ExampleDialogBody::val2) + ).apply(ExampleDialogBody::new)); + + @Override + public MapCodec mapCodec() { + return BODY_CODEC; + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_BODY_TYPE, "examplemod:example_body", ExampleDialogBody.BODY_CODEC); +``` + +```json5 +// For some dialog +{ + // ... + "body": [ + { + // Our body + "type": "examplemod:example_body", + "val1": true, + "val2": 0 + }, + // ... + ] +} +``` + +How does this body actually render then? Well, that is done via a `DialogBodyHandler`. This contains a single method `createControls` that generates the `LayoutElement` to render given the `DialogScreen` and the dialog data. This body handler can be linked to the `MapCodec` via `DialogBodyHandlers#register`. + +```java +public class ExampleDialogBodyHandler implements DialogBodyHandler { + + @Override + public LayoutElement createControls(DialogScreen screen, ExampleDialogBody body) { + // Create the element (widgets, layouts, etc.) + return new StringWidget(...); + } +} + +// Note that `register` is not public, so this needs to be access widened +DialogBodyHandlers.register(BODY_CODEC, new ExampleDialogBodyHandler()); +``` + +#### Custom Inputs + +An `InputControl` represents some input a user can provide, whether that would be some text or a button submission click. This is generally made up of components that can accept or provide some string value or tag based on a state. All dialogs can provide these inputs; through the `DialogControlSet`. It only contains one method `mapCodec`, which is used as the registry key and encoder for the input control. + +```java +public record ExampleInputControl(int value) implements InputControl { + public static final MapCodec INPUT_CODEC = Codec.INT.fieldOf("value").xmap( + ExampleInputControl::new, ExampleInputControl::value + ); + + @Override + public MapCodec mapCodec() { + return INPUT_CODEC; + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.INPUT_CONTROL_TYPE, "examplemod:example_input", ExampleInputControl.INPUT_CODEC); +``` + +```json5 +// For some dialog (assume `minecraft:simple_input_form`) +{ + "inputs": [ + { + // Our input + "type": "examplemod:example_input", + + // The identifier for the data of this input + "key": "example_input", + + "value": 0 + }, + // ... + ] +} +``` + +Like above, the input is rendered via a `InputControlHandler`. This contains a single method `addControl`, which provides the `Screen` and input control and creates the `LayoutElement` and its associated `Action$ValueGetter` via `$Output`. This input handler can be linked to the `MapCodec` via `InputControlHandlers#register`. + +```java +public class ExampleInputControlHandler implements InputControlHandler { + + @Override + public void addControl(ExampleInputControl control, Screen screen, InputControlHandler.Output output) { + EditBox box = new EditBox(...); + box.setValue(String.valueOf(control.value())); + + // Add the elements to the output + output.accept( + // The element to render + box, + // The value output of the input + Action.ValueGetter.of(box::getValue) + ); + } +} + +// Note that `register` is not public, so this needs to be access widened +InputControlHandlers.register(INPUT_CODEC, new ExampleInputControlHandler()); +``` + +### Custom Actions + +As shown above, an input can provide some value to pass to an `Action`. The former is known as a `$ValueGetter`, which essentially gets a stringified or tagged input to use. The latter, meanwhile, ends up creating the `ClickEvent` that is sent to the server. These are typically created through `ActionButton`s which defines some common button data along with the `Action` to perform. + +A custom action contains two methods: one which returns the `MapCodec` (`codec`) to use during encoding, while the other creates the `ClickEvent` based on the map of input strings to their `$ValueGetter`s. + +```java +public record ExampleAction() implements Action { + public static final MapCodec ACTION_CODEC = MapCodec.unit(new ExampleAction()); + + @Override + public MapCodec codec() { + return ACTION_CODEC; + } + + @Override + public Optional createAction(Map keysToGetters) { + // Handle how you want to map the key input map to some click event + return Optional.empty(); + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_ACTION_TYPE, "examplemod:example_action", ExampleAction.ACTION_CODEC); +``` + +```json5 +// For some dialog (assume `minecraft:notice`) +{ + "action": { + // Button data + "label": "Example!", + "tooltip": "This is an example!", + "width": 80, + + // The action to perform + "action": { + // Out action type + "type": "examplemod:example_action" + } + } +} +``` + +Depending on how you implement your `Dialog` below, the action button will automatically be added to the screen, or you will need to add it in one of the methods via `DialogControlSet#createActionButton`: + +```java +// For some DialogScreen implementation, we will assume some `SimpleDialog` +@Override +protected void updateHeaderAndFooter(HeaderAndFooterLayout layout, DialogControlSet controls, SimpleDialog dialog, DialogConnectionAccess access) { + dialog.mainActions().forEach(actionButton -> layout.addToFooter(controls.createActionButton(actionButton).build())); +} +``` + +#### Custom Dialogs + +A `Dialog` is pretty much all of the above components put together as desired. It is up to the user to choose how to implement them. Every `Dialog` must provide its `CommonDialogData`, which defines the basic title, body contents, and functionality. In additional, a `Dialog` may choose to execute an `Action` on close via `onCancel`. + +```java +// `common` is already implemented by the record +public record ExampleDialog(CommonDialogData common, boolean val1, int val2) implements Dialog { + public static final MapCodec DIALOG_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + CommonDialogData.MAP_CODEC.forGetter(ExampleDialog::common), + Codec.BOOL.fieldOf("val1").forGetter(ExampleDialog::val1), + Codec.INT.fieldOf("val2").forGetter(ExampleDialog::val2) + ).apply(ExampleDialog::new)); + + @Override + public MapCodec codec() { + return DIALOG_CODEC; + } + + @Override + public Optional onCancel() { + // You can choose to return something here, or empty if nothing should be done + return Optional.empty(); + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_TYPE, "examplemod:example_dialog", ExampleDialog.DIALOG_CODEC); +``` + +```json5 +// For some dialog in `data/examplemod/dialog/example.json` +{ + // Our dialog type + "type": "examplemod:example_dialog", + + // Common button data + "title": "Example dialog!", + "can_close_with_escape": true, + "after_action": "wait_for_response", + + // Our custom params + "val1": true, + "val2": 0 +} +``` + +Like the others, a dialog type can only be rendered through a `DialogScreen$Factory`. This interface constructs a `DialogScreen` given the parent `Screen`, `Dialog` instance, and `DialogConnectionAccess` used to communicate to the server. This dialog screen can then be linked to the `MapCodec` via `DialogScreens#register`. + +```java +public class ExampleDialogScreen extends DialogScreen { + + public ExampleDialogScreen(@Nullable Screen previousScreen, ExampleDialog dialog, DialogConnectionAccess connectionAccess) { + super(previousScreen, dialog, connectionAccess); + } + + // You can choose to implement the other methods as you wish + // See existing dialog screens for an example + + @Override + protected void populateBodyElements(LinearLayout layout, DialogControlSet controls, ExampleDialog dialog, DialogConnectionAccess access) { + // Add elements and actions to the body of the screen (usually the center) + } + + @Override + protected void updateHeaderAndFooter(HeaderAndFooterLayout layout, DialogControlSet controls, ExampleDialog dialog, DialogConnectionAccess access) { + // Add elements and actions to the header and footer of the screen (top and bottom) + } +} + +// Note that `register` is not public, so this needs to be access widened +DialogScreens.register(DIALOG_CODEC, ExampleDialogScreen::new); +``` + +- `com.mojang.blaze3d.vertex.VertexConsumer#addVertexWith2DPose` - Adds a vertex to be rendered in 2d space. +- `net.minecraft.client.gui` + - `Font` + - `drawInBatch` no longer returns anything + - `prepareText` - Prepares the text to be rendered to the screen. + - `splitIgnoringLanguage` - Splits the text in the order provided without being processed by the language handler. + - `ALPHA_CUTOFF` is removed + - `$GlyphVisitor` - An interface that handles a glyph or effect to be rendered. + - `$PreparedText` - An interface that defines how a piece of text should be rendered by visiting each glyph. + - `$StringRenderOutput` -> `$PreparedTextBuilder`, no longer takes in the `MultiBufferSource`, `Matrix4f`, `$DisplayMode`, packed light coords, and the inverse depth boolean + - `Gui` + - `shouldRenderDebugCrosshair` - Returns true if the debug crosshair should be rendered. + - `$RenderFunction` - An interface that defines how a certain section or element is rendered on the gui. + - `GuiGraphics` now takes in a `GuiRenderState` instead of the `MultiBufferSource$BufferSource` + - `MAX_GUI_Z`, `MIN_GUI_Z` are removed + - `pose` now returns a `Matrix3x2fStack` + - `flush` is removed + - `nextStratum` - Adds another layer to traverse through that renders after all nodes in the previous tree. + - All methods no longer take in a `RenderType`, `VertexConsumer`, or `Function`, instead specifying a `RenderPipeline` and a `TextureSetup` depending on the call + - `drawString`, `drawStringWithBackdrop` no longer returns anything + - `draw*String` methods must now pass in an ARGB value, where A cannot be 0. + - `renderItem(ItemStack, int, int, int, int)` is removed + - `drawSpecial` is removed, replaced by individual `submit*RenderState` depending on the special case + - `blurBeforeThisStratum` - Notifies the render state that a blur effect should render between this strata and all previously rendered ones. This can only be applied between once per frame. + - `render*Tooltip` -> `set*TooltipForNextFrame`, does not directly add to the render state, instead waiting for `renderDeferredTooltip` to be called when not present or overridden + - `renderDeferredTooltip` - Adds the tooltip information to be rendered on a new stratum. + - `blitSprite` now has an overload that takes in a float R tint color + - `$ScissorStack#peek` - Gets the last rectangle on the stack. + - `LayeredDraw` class is removed +- `net.minecraft.client.gui.components` + - `AbstractTextAreaWidget` now has an overload which takes in two additional booleans of whether to show the background or decorations + - `AbstractWidget#getTooltip` is removed + - `CycleButton$Builder#displayOnlyValue` now has an overload that takes in the `boolean` to set + - `EditBox` + - `setCentered` - Sets whether the text position should be centered. + - `setTextShadow` - Sets whether the text should have a drop shadow effect. + - `FocusableTextWidget` can now take in a boolean indicating whether to fill the background + - `DEFAULT_PADDING` is now public + - `ImageWidget#updateResource` - Updates the sprite of the image on the component. + - `ItemDisplayWidget` - A widget that displays an `ItemStack`. + - `LogoRenderer#keepLogoThroughFade` - When true, keeps the logo visible even when the title screen is fading. + - `MultiLineEditBox` is now package private and should be constructed via `builder`, calling the `$Builder#set*` methods + - `setLineLimit` - Sets the line limit of the text field. + - `setValue` now has an overload that takes in the `boolean` to determine whether it should force pass the max line limit + - `MultiLineLabel` + - `getStyleAtCentered` - Computes the component style for centered text. + - `getStyleAtLeftAligned` - Computes the component style for left aligned text. + - `MultilineTextField#NO_CHARACTER_LIMIT` -> `NO_LIMIT` + - `setLineLimit` - Sets the maximum number of lines that can be written on the text field. + - `hasLineLimit` - Returns whether the text field has some line limit. + - `setValue` now has an overload that takes in the `boolean` to determine whether it should force pass the max line limit + - `MultiLineTextWidget#configureStyleHandling` - Sets whether something is displayed when hovering over components and what to do on click. + - `ScrollableLayout` - A layout with some defined bounds that can be scrolled through. + - `SplashRenderer#render` now takes in a float for the R color instead of an int + - `WidgetTooltipHolder#refreshTooltipForNextRenderPass` now takes in the `GuiGraphics` and the XY position +- `net.minecraft.client.gui.components.spectator.SpectatorGui#renderTooltip` -> `renderAction` +- `net.minecraft.client.gui.components.tabs` + - `LoadingTab` - A tab that indicates information is currently being loaded. + - `Tab#getTabExtraNarration` - Returns the hint narration of the tab. + - `TabManager` can now take in two `Consumer`s on what to do when a tab is selected or deselected + - `TabNavigationBar` + - `getTabs` - Returns the list of tabs on the navigation bar. + - `setTabActiveState` - Sets the active state of the given tab index. + - `setTabTooltip` - Sets the tooltip information of the given tab index. +- `net.minecraft.client.gui.components.toasts` + - `NowPlayingToast` - A toast that displays the currently playing background music. + - `Toast` + - `xPos`, `yPos` - Gets the x and y position in relation to the current toast index. + - `onFinishedRendering` - A method called once the toast has finished rendered on screen. + - `ToastManager` now takes in the `Options` + - `showNowPlayingToast`, `hideNowPlayingToast`, `createNowPlayingToast`, `removeNowPlayingToast` - Handles the 'Now Playing' music toast. + - `$ToastInstance#resetToast` - Resets the toast. +- `net.minecraft.client.gui.contextualbar` + - `ContextualBarRenderer` - An interface which defines an object with some background to render. + - `ExperienceBarRenderer` - Draws the experience bar. + - `JumpableVehicleBarRenderer` - Draws the jump power bar (e.g. horse jumping). + - `LocatorBarRenderer` - Draws the bar that points to given waypoints. +- `net.minecraft.client.gui.font.GlyphRenderTypes` now takes in a `RenderPipeline` for the gui rendering +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` now takes in a `GpuTextureView` + - `extractEffect` - Extracts a glyph effect (e.g. drop shadow) submits the element to be rendered. + - `extractBackground` - Extracts a glyph effect and submits the element to be rendered on the background Z. + - `left`, `top`, `right`, `bottom` - Computes the bounds of the glyph. + - `textureView` - Returns the view of the texture making up the glyph. + - `guiPipeline` - Returns the pipeline to render the glyph. + - `renderChar`, `renderEffect` now takes in an additional boolean that sets the Z offset to `0` when true and `0.001` when false + - `$Effect#left`, `top`, `right`, `bottom` - Computes the bounds of the glyph effect. + - `$GlyphInstance#left`, `top`, `right`, `bottom` - Computes the bounds of the glyph instance. +- `net.minecraft.client.gui.navigation.ScreenRectangle` + - `transformAxisAligned` now takes in a `Matrix3x2f` instead of a `Matrix4f` + - `intersects` - Returns whether this rectangle overlaps with another rectangle. + - `encompasses` - Returns whether this rectangle contains the entirety of another rectangle. + - `transformMaxBounds` - Returns a new rectangle that is moved into a given position by the provided matrix. +- `net.minecraft.client.gui.render` + - `GuiRenderer` - A class that renders all submitted elements to the screen. + - `TextureSetup` - A record that specifies samplers 0-2 for use in a render pipeline. The first two textures views are arbitrary with the third being for the current lightmap texture. +- `net.minecraft.client.gui.render.pip` + - `GuiBannerResultRenderer` - A renderer for the banner result preview. + - `GuiBookModelRenderer` - A renderer for the book model in the enchantment screen. + - `GuiEntityRenderer` - A renderer for a given entity. + - `GuiProfilerChartRenderer` - A renderer for the profiler chart. + - `GuiSignRenderer` - A renderer for the sign background in the edit screen. + - `GuiSkinRenderer` - A renderer for a player with a given skin. + - `OversizedItemRenderer` - A rendered for when an item model should be rendered larger than its item slot. + - `PictureInPictureRenderer` - An abstract class meant for rendering dynamic elements that are not standard 2d elements, items, or text. +- `net.minecraft.client.gui.render.state` + - `BlitRenderState` - An element state for a basic 2d texture blit. + - `ColoredRectangleRenderState` - An element state for a simple rectangle with a tint. + - `GlyphEffectRenderState` - An element state for a glyph effect (e.g., font text drop shadow). + - `GlyphRenderState` - An element state for a glyph (font text). + - `GuiElementRenderState` - An interface representing the state of a element to render. + - `GuiItemRenderState` - A record representing the state of an item to render. + - `GuiRenderState` - The state of the GUI to render to the screen. + - `GuiTextRenderState` - A record representing the state of the text and its location to render. + - `ScreenArea` - An interface which defines the render area of an element. This does not affect scissoring, instead layer orders. +- `net.minecraft.client.gui.render.state.pip` + - `GuiBannerResultRenderState` - The state of the banner result preview. + - `GuiBookModelRenderState` - The state of the book model in the enchantment screen. + - `GuiEntityRenderState` - The state of a given entity. + - `GuiProfilerChartRenderState` - The state of the profiler chart. + - `GuiSignRenderState` - The state of the sign background in the edit screen. + - `GuiSkinRenderState` - The state of a player with a given skin. + - `OversizedItemRenderState` - The state of an item model that can be rendered at an arbitrary size. + - `PictureInPictureRenderState` - An interfaces that defines the basic state necessary to render the picture-in-picture to the screen. +- `net.minecraft.client.gui.screens` + - `ConfirmScreen` + - `layout` - Defines a vertical list of elements spaced by eight units. + - `yesButton`, `noButton` -> `yesButtonComponent`, `noButtonComponent` + - `yesButton`, `noButton` now represent the actual buttons + - `addAdditionalText` - Adds any additional text before the buttons in the layout. + - `addButtons` - Adds the buttons in the layout. + - `PauseScreen` + - `rendersNowPlayingToast` - Returns whether the 'Now Playing' toast should be rendered. + - `onDisconnect` -> `disconnectFromWorld`, now public and static; not one-to-one + - `Screen` + - `CUBE_MAP` -> `net.minecraft.client.renderer.GameRenderer#cubeMap` + - `PANORAMA` -> `net.minecraft.client.renderer.GameRenderer#panorama` + - `renderBlurredBackground` now takes in the `GuiGraphics` + - `*TooltipForNextRenderPass` methods are either removed or moved to `GuiGraphics` + - `FADE_IN_TIME` - Represents how much time in milliseconds does it take for some element to fade in. + - `fadeWidgets` - Sets the alpha of the `AbstractWidget`s added as children to the screen. + - `handleClickEvent` - Handles the event to play when the component is clicked. + - `defaultHandleClickEvent` - The default logic to execute when the component is clicked. + - `clickUrlAction` - The logic to perform when a URL is clicked (has the Open URL style). + - `clickCommandAction` - The logic to perform when a command should be executed (has the \* Command style). +- `net.minecraft.client.gui.screens.dialog` + - `ButtonListDialogScreen` - A dialog screen that contains some list of buttons. + - `DialogConnectionAccess` - A client side interface that processes general interaction information from the dialog. + - `DialogControlSet` - An input handler for a dialog screen. + - `DialogListDialogScreen` - A button list of `DialogListDialog`s. + - `DialogScreen` - A screen for some dialog modal. + - `DialogScreens` - A factory registry of dialog modals to their associated screen. + - `MultiButtonDialogScreen` - A button list of `MultiActionDialog`s. + - `ServerLinksDialogScreen` - A button list of `ServerLinksDialog`s. + - `SimpleDialogScreen` - A dialog screen for some simple dialog. + - `WaitingForResponseScreen` - A screen that handles the downtime between client/server communication of dialog submissions. +- `net.minecraft.client.gui.screens.dialog.body` + - `DialogBodyHandler` - A list of body elements describing the contents between the title and actions/inputs. + - `DialogBodyHandlers` - A registry of `DialogBody`s to their `DialogBodyHandler`s. +- `net.minecraft.client.gui.screens.dialog.input` + - `InputControlHandler` - A user input handler. + - `InputControlHandlers`- A registry of `InputControl`s to their `InputControlHandler`s. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen` + - `SLOT_ITEM_BLIT_OFFSET` is removed + - `renderContents` - Renders the slot and labels of an inventory. + - `renderCarriedItem` - Renders the held item. + - `renderSnapbackItem` - Renders the swapped item with the held item. + - `$SnapbackData` - Holds the information about the dragging or swapped item as it moves from the held location to its slot location. + - `AbstractSignEditScreen#offsetSign` -> `getSignYOffset`, not one-to-one + - `BookEditScreen` + - `TEXT_*`, `IMAGE_*`, `BACKGROUND_TEXTURE_*` are now public + - `BookSignScreen` - A screen for signing a book. + - `BookViewScreen` + - `closeScreen` -> `closeContainerOnServer`, not one-to-one + - `$BookAccess#getPage` now returns a `Component` + - `EffectsInInventory` + - `renderEffects` is now public + - `renderTooltip` has been overloaded to a public method + - `InventoryScreen#renderEntityInInventory` no longer takes in the XY offset, instead taking in 4 `int`s to represent the region to render to + - `ItemCombinerScreen#renderFg` is removed +- `net.minecraft.client.gui.screens.inventory.tooltip` + - `ClientTooltipComponent#renderText` no longer takes in the pose and buffer, instead the `GuiGraphics` to submit the text for rendering + - `TooltipRenderUtil#renderTooltipBackground` no longer takes in a Z offset +- `net.minecraft.client.gui.screens.multiplayer.ServerLinksScreen` class is removed, replaced by dialog modal +- `net.minecraft.client.gui.screens.social` + - `PlayerEntry#refreshHasDraftReport` - Sets whether the current context as a report for this player. + - `SocialInteractionsPlayerList#refreshHasDraftReport` - Refreshes whether the current context as a report for all players. +- `net.minecraft.client.gui.screens.worldselection.ExperimentsScreen$ScrollArea` class is removed, replaced by the `ScrollableLayout` +- `net.minecraft.client.model.geom.ModelPart#getExtentsForGui` - Gets the set of vectors representing the part transformed into their appropriate space. +- `net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl` + - `showDialog` - Shows the current dialog, creating the screen dynamically. + - `serverLinks` - Returns the entries of server links the client can access. + - `createDialogAccess` - Creates the dialog handler on the client used for communication. + - `clearDialog` - Closes the current dialog screen. +- `net.minecraft.client.player.LocalPlayer#experienceDisplayStartTick` - Represents the start tick of when the experience display should be prioritized. +- `net.minecraft.client.renderer` + - `GameRenderer` no longer takes in a `ResourceManager` + - `ITEM_ACTIVATION_ANIMATION_LENGTH` is removed + - `setRenderHand` is removed + - `renderZoomed` is removed + - `getPanorama` - Returns the panorama renderer. + - `LightTexture#getTexture` -> `getTextureView`, not one-to-one + - `MapRenderer#WIDTH`, `HEIGHT` are now public + - `PanoramaRenderer#registerTextures` - Registers the texture for use by the cube map. + - `PostPass$Input#texture` now returns a `GpuTextureView` instead of a `GpuTexture` + - `RenderPipelines` + - `GUI_OVERLAY`, `GUI_GHOST_RECIPE_OVERLAY`, `GUI_TEXTURED_OVERLAY` are removed + - `GUI_TEXTURED_PREMULTIPLIED_ALPHA` - A pipeline that assumes the textures have already had their transparency premultiplied during the composite stage. + - `RenderStateShard` + - `$Builder#add` no longer takes in whether the shard should be blurred + - `$TextureStateShard` no longer takes in a `TriState` to set the blur mode + - `RenderType` + - `debugLine` is removed + - `gui`, `guiOverlay`, `guiTexturedOverlay`, `guiOpaqueTexturedBackground`, `guiNauseaOverlay`, `guiTextHighlight`, `guiGhostRecipeOverlay`, `guiTextured` are removed + - `vignette` is removed + - `crosshair` is removed + - `mojangLogo` is removed + - `ScreenEffectRenderer` is now an instance implementation instead of simply a static method + - The constructor takes in the current `Minecraft` instance and a `MultiBufferSource` + - `renderScreenEffect` is now an instance method, taking in whether the entity is sleeping and the partial tick + - `resetItemActivation`, `displayItemActivation` - Handles when an item is automatically activated (e.g., totem). +- `net.minecraft.client.renderer.blockentity` + - `*Renderer#getExtents` - Adds the transformed vectors representing all models to a set. + - `HangingSignRenderer` + - `MODEL_RENDER_SCALE` is now public + - `translateBase` is now public + - `SignRenderer` + - `RENDER_SCALE` is now public + - `applyInHandTransforms` - Transforms the stack to properly represent the held sign's position. + - `SkullBlockRenderer#getRenderType(SkullBlock$Type, ResolvableProfile, ResourceLocation)` -> `getSkullRenderType`, `getPlayerSkinRenderType`; not one-to-one +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `GUI_SLOT_CENTER_X`, `GUI_SLOT_CENTER_Y`, `ITEM_DECORATION_BLIT_OFFSET` are removed + - `COMPASS_*` -> `SPECIAL_*` +- `net.minecraft.client.renderer.item` + - `ClientItem$Properties#oversizedInGui` - When true, allows an item to render outside the 16x16 box in a GUI; otherwise, clips the size to the box. + - `ItemStackRenderState` + - `setAnimated`, `isAnimated` - Returns whether the item is animated (e.g., foil). + - `appendModelIdentityElement`, `getModelIdentity`, `clearModelIdentity` - Handles the identity component being rendered. + - `getModelBoundingBox` - Computes the bounding box of the model. + - `setOversizedInGui`, `isOversizedInGui` - Handles when the item can be oversized in the GUI based on its property. +- `net.minecraft.client.renderer.special` + - `PlayerHeadSpecialRenderer` - Renders an player head based on its render info. + - `SkullSpecialRenderer` now implements `NoDataSpecialModelRenderer`, no longer taking in the model or texture override, instead just the `RenderType` to use + - `SpecialModelRenderer#getExtents` - Adds the transformed vectors representing all models used by this renderer to a set. +- `net.minecraft.client.renderer.texture.TextureAtlasSprite#isAnimated` - Returns whether the sprite has any animation. +- `net.minecraft.commands.arguments.ResourceOrIdArgument#dialog`, `getDialog`, `$DialogArgument` - Handles command arguments for dialog screens. +- `net.minecraft.core.registries` + - `BuiltInRegistries#DIALOG_TYPE`, `DIALOG_ACTION_TYPE`, `INPUT_CONTROL_TYPE`, `DIALOG_BODY_TYPE` + - `Registries#DIALOG_TYPE`, `DIALOG_ACTION_TYPE`, `INPUT_CONTROL_TYPE`, `DIALOG_BODY_TYPE`, `DIALOG` +- `net.minecraft.data.tags.DialogTagsProvider` - A tags provider for dialogs. +- `net.minecraft.network.chat` + - `ClientEvent` + - `$Action#SHOW_DIALOG`, `CUSTOM` + - `valueCodec` - Returns the map codec used to encode this action. + - `$Custom` - An event that contains some nbt payload to send to the server, currently does nothing. + - `$ShowDialog` - An event that shows the specified dialog. + - `CommonComponents` + - `GUI_RETURN_TO_MENU` - The component that displays the 'Return to Menu' text. + - `disconnectButtonLabel` - Returns the component based on whether the server is local. +- `net.minecraft.network.protocol.common` + - `ClientboundClearDialogPacket` - Closes the current dialog screen. + - `ClientboundShowDialogPacket` - Opens a new dialog screen. + - `ServerboundCustomClickActionPacket` - Sends a custom action to the server. +- `net.minecraft.server.dialog` + - `ActionButton` - A button that can perform some `Action` on click. + - `ButtonListDialog` - A dialog modal that has some number of columns to click buttons of. + - `CommonButtonData` - The data that is associated with every button within a dialog modal. + - `CommonDialogData` - The data that is associated with every dialog modal. + - `ConfirmationDialog` - A dialog modal whether you can either click yes or no. + - `Dialog` - The base interface that defines some dialog modal. + - `DialogAction` - The action to perform typically after some action button is clicked. + - `DialogListDialog` - A scrollable list of buttons that lead to other dialogs. + - `Dialogs` - A datapack bootstrap registering `Dialog`s. + - `DialogTypes` - A registry of map codecs to encode some dialog model. + - `Input` - A handler that maps some key to an `InputControl`. + - `MultiActionDialog` - A scrollable list of actions arrange in columns. + - `NoticeDialog` - A simple screen with one action in the footer. + - `ServerLinksDialog` - A scrollable list of links received from the server, arrange in columns. + - `SimpleDialog` - A dialog that defines the main actions that can be taken. +- `net.minecraft.server.dialog.action` + - `Action` - A general operation to perform on some input, usually a button click. + - `ActionTypes` - A registry of map codecs to encode some action. + - `CustomTemplate` - Builds a command and requests the server to run it. + - `CustomAll` - Builds a custom server click action from all inputs and requests the server to run it. + - `ParsedTemplate` - A template that encodes some string similar to how function macros work. + - `StaticAction` - An action that fires a `ClickEvent` on activation. +- `net.minecraft.server.dialog.body` + - `DialogBody` - A body element describing the content between the title and actions/inputs. + - `DialogBodyTypes` - A registry of map codecs to encode some body. + - `ItemBody` - An item with an optional description. + - `PlainMessage` - A multiline label. +- `net.minecraft.server.dialog.input` + - `BooleanInput` - A plain checkbox with a label. + - `InputControl` - A control mechanism to accept user input. + - `InputControlTypes` - A registry of map codecs to encode some input control. + - `NumberRangeInput` - A slider for picking a numeric value from some range. + - `SingleOptionInput` - A button that cycles between a set of options. + - `TextInput` - Simple text input. +- `net.minecraft.world.entity.player.Player#openDialog` - Opens the specified dialog screen. + +## Waypoints + +Waypoints are simply a method to track the position of some object in the game. The underlying system is handled by the `WaypointManager`, responsible for holding the waypoints it is tracking while also allowing updates and removals as necessary. The server handles waypoints through the `ServerWaypointManager` (obtained via `ServerLevel#getWaypointManager`), which holds an active connect to the transmitter to receive live updates. The client receives these waypoints via the `ClientWaypointManager` (obtained via `ClientPacketListener#getWaypointManager`), which simply holds some identifier along with an exact position, a chunk if the position is not within the view distance, or an angle if the distance is further than the stored `Waypoint$Fade#farDist`, which is over 332 blocks away by default. + +Entities track waypoints by default. + +### Styles and Icons + +Every waypoint is represents by an icon of some kind, which is defined by its `WaypointStyle` and the color of the icon. A `WaypointStyle` is similar to a client item or a equipment model, where it has some key pointed to by a `WaypointStyleAsset` that's located in `assets//waypoint_style/.json`. This contains a list of sprites located within `assets//textures/gui/sprites/hud/locator_bar_dot/.png` which is chosen based upon the distance from the tracker. The sprites change between the range specified by the near and far distance. + +```json5 +// For some style examplemod:example_style +// It will be found in `assets/examplemod/waypoint_style/example_style.json` +{ + // Represents that any value closer will use the first sprite when rendering the bar + // Defaults to 128 when not specified + "near_distance": 100, + // Represents that any value further will use the last sprite when rendering the bar + // Defaults to 332 when not specified + // Must be greater than near distance + "far_distance": 400, + // A non-empty list of textures relative to `assets//textures/gui/sprites/hud/locator_bar_dot/.png` + // This is what's used to lerp between the two distances + "sprites": [ + // Points to `assets/examplemod/textures/gui/sprites/hud/locator_bar_dot/example_style_0.png` + "examplemod:example_style_0", + "examplemod:example_style_1", + "examplemod:example_style_2" + ] +} +``` + +The icon can then be constructed using its constructor and referenced via `WaypointTransmitter#waypointIcon` or `TrackedWaypoint#icon` on the server or client, respectively. + +```java +// We will assume that this constructor is made public for a more dynamic usage +// Currently, it can only be set on a `LivingEntity` through its `CompoundTag` via `locator_bar_icon` +public static Waypoint.Icon EXAMPLE_ICON = new Waypoint.Icon( + // The registry key of the waypoint style + // Points to `assets/examplemod/waypoint_style/example_style.json` + ResourceKey.create(WaypointStyleAssets.ROOT_ID, ResourceLocation.fromNamespaceAndPath("examplemod", "example_style")), + // The color of the waypoint + // When not present, uses the hashcode of the waypoint identifier + Optional.of(0xFFFFFF) +); +``` + +### Connections + +Waypoints, when tracked, are managed through their connections via `WaypointTransmitter$Connection`. A connection is responsible for syncing information to the client, whether connecting, disconnecting, or updating. + +```java +public class ExampleBlockConnection implements WaypointTransmitter.Connection { + + private final BlockState state; + private final BlockPos pos; + private final Waypoint.Icon icon; + private final ServerPlayer receiver; + + public ExampleBlockConnection(BlockState state, BlockPos pos, Waypoint.Icon icon, ServerPlayer receiver) { + this.state = state; + this.pos = pos; + this.icon = icon; + this.recevier = receiver; + } + + public static boolean doesSourceIgnoreReceiver(BlockPos pos, ServerPlayer player) { + double receiveRange = player.getAttributeValue(Attributes.WAYPOINT_RECEIVE_RANGE); + return pos.distSqr(player.blockPosition()) >= receiveRange * receiveRange; + } + + @Override + public boolean isBroken() { + // When true, it will attempt to remake the connection to this transmitter + // This is only called when updating the position + return ExampleBlockConnection.doesSourceIgnoreReceiver(this.pos, this.receiver); + } + + @Override + public void connect() { + // This sends the tracking packet to the client + this.receiver.connection.send(ClientboundTrackedWaypointPacket.addWaypointPosition(this.state.toString() + ": " + this.pos.toString(), this.icon, this.pos)); + } + + @Override + public void disconnect() { + // This sends the removal packet to the client + this.receiver.connection.send(ClientboundTrackedWaypointPacket.removeWaypoint(this.state.toString() + ": " + this.pos.toString())); + } + + @Override + public void update() { + // This updates the tracked value on the client assuming that the connect has not broken + // In our case, we can assume this never changes as the position of a block should remain consistent + } +} +``` + +### Transmitters + +A `WaypointTransmitter` is responsible for constructing the connection between it and the server. For your object to transmit a location, it must implement `WaypointTransmitter` and its three methods. `waypointIcon` simply returns the icon to display. `isTransmittingWaypoint` will determine whether the waypoint can be transmitted from this object. `makeWaypointConnectionWith` actually handles constructing the connection used to track the position or angle of the connection. + +```java +public class ExampleWaypointBlock extends BlockEntity implements WaypointTransmitter { + + // ... + + @Override + public boolean isTransmittingWaypoint() { + // This should return false if no connection should be made + return true; + } + + @Override + public Optional makeWaypointConnectionWith(ServerPlayer player) { + // Make a connection if nothing is ignored + return ExampleBlockConnection.doesSourceIgnoreReceiver(this.getBlockPos(), player) + ? Optional.empty() + : Optional.of(new ExampleBlockConnection(this.getBlockState(), this.getBlockPos(), this.waypointIcon(), player)); + } + + @Override + public Waypoint.Icon waypointIcon() { + return EXAMPLE_ICON; + } +} +``` + +Then, all you need to do is track, update, or untrack the transmitter as necessary. This can be done using the methods provided by `ServerWaypointManager`: + +```java +// We will assume we have access to: +// - ServerLevel serverLevel +// - ExampleWaypointBlock be + +// Tracking the waypoint, such as on some initialization +serverLevel.getWaypointManager().trackWaypoint(be); + +// Update the waypoint if the position changes +serverLevel.getWaypointManager().updateWaypoint(be); + +// Remove the waypoint once it no longer exists +serverLevel.getWaypointManager().untrackWaypoint(be); +``` + +- `net.minecraft.client` + - `Camera` now implements `TrackedWaypoint$Camera` + - `Minecraft#getWaypointStyles` - Returns a manager of keys to the style of a waypoint. +- `net.minecraft.client.data.models.WaypointStyleProvider` - A data provider that generates waypoint styles. +- `net.minecraft.client.multiplayer.ClientPacketListener#getWaypointManager` - Gets the client manager used for tracking waypoints. +- `net.minecraft.client.renderer.GameRenderer` now implements `TrackedWaypoint$Projector` +- `net.minecraft.client.resources` + - `WaypointStyle` - Defines the style used to render a waypoint. + - `WaypointStyleManager` - The manager that maps some key to the style of a waypoint. +- `net.minecraft.client.waypoints.ClientWaypointManager` - A client-side manager for tracked waypoints. +- `net.minecraft.commands.arguments.WaypointArgument` - A static method holder that gets some waypoint transmitter from an entity. +- `net.minecraft.network.protocol.game` + - `ClientboundTrackedWaypointPacket` - A packet that sends some operation for a waypoint to the client. + - `ClientGamePacketListener#handleWaypoint` - Handles the waypoint packet on the client. +- `net.minecraft.server.ServerScoreboard$Method` enum is removed +- `net.minecraft.server.level.ServerLevel#getWaypointManager` - Gets the server manager used for tracking waypoints. +- `net.minecraft.server.level.ServerPlayer#isReceivingWaypoints` - Whether the player is receiving waypoints from other locations or entities. +- `net.minecraft.server.waypoints.ServerWaypointManager` - A server-side manager for tracked waypoints (e.g., players and transmitters). +- `net.minecraft.world.entity` + - `Entity#getRequiresPrecisePosition`, `setRequiresPrecisePosition` - Handles when a more precise position is needed for tracking. + - `LivingEntity` now implements `WaypointTransmitter` +- `net.minecraft.world.waypoints` + - `TrackedWaypoint` - A waypoint that is identified by some UUID or string, displayed via a `Waypoint$Icon`, and specified via `$Type`. + - `TrackedWaypointManager` - A waypoint manager for `TrackedWaypoint`s. + - `Waypoint` - An interface that represents some positional location. This holds no information, and is typically used in the context of `TrackedWaypoint`. + - `WaypointManager` - An interface that tracks and updates waypoints. + - `WaypointStyleAsset` - A class that indicates a style asset. + - `WaypointStyleAssets` - A class that defines all vanilla style assets. + - `WaypointTransmitter` - An object that transmits some position that can be connected to and tracked. + +## Blaze3d Changes + +Just like the previous update Blaze3d has new redesigns that change how rendering is handled. + +### Buffer Slices + +The most important change within the rendering system is the use of `GpuBufferSlice`s. As the name implies, it simply takes some slice of a `GpuBuffer`, using an `offset` to indicate the starting index, and the `length` to indicate its size. When dealing with anything rendering related, even when passing to a shader, you will almost always be dealing with a `GpuBufferSlice`. A way to think about it is that the buffer is just some arbitrary list of object where a slice represents a specific object. + +To create a slice, simply call `GpuBuffer#slice`, optionally providing the starting index and length. In most instances, you will not be calling this method directly, instead dealing with other methods that call it for you. Note that as you are generally writing data to these slices, they should be constructed before a try-with-resources `RenderPass` is created. + +### Uniform Rework + +The uniform system has been completely overhauled such that, unless you are familiar with specific features, it might seem completely foreign. In a nutshell, uniforms are now stored as either interface objects, a texel buffer, or a sampler. These are populated either by `GpuBuffer`s or `GpuBufferSlice`s. + +#### Uniform Types + +A uniform is currently represented as one of two `UniformType`s: either as an `UNIFORM_BUFFER`/interface block, or a `TEXEL_BUFFER`. When setting up a pipeline and calling `withUniform`, you must specify your uniform with one of the above types. If you choose to use a texel buffer, you must also specify the format of the texture data. Samplers have not changed. + +```java +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder(...) + // Uses a uniform interface block called 'ExampleUniform' + .withUniform("ExampleUniform", UniformType.UNIFORM_BUFFER) + // Uses a buffer called 'ExampleTexel' that stores texture data as a 8-bit R value + .withUniform("ExampleTexel", UniformType.TEXEL_BUFFER, TextureFormat.RED8I) + // Perform other setups + .build(); +``` + +#### Interface Blocks + +A `UNIFORM_BUFFER` is stored as a `std140` interface block. In GLSL, this is represented like so: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +// ExampleUniform is the name of the block +layout(std140) uniform ExampleUniform { + // The data within the block + // Post Effects can only use int, float, vec2, vec3, ivec3, vec4, or mat4 + vec4 Param1; + float Param2; +}; +``` + +The values can be used freely inside the main block like so: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +out vec4 fragColor; + +void main() { + fragColor = Param1; +} +``` + +The uniform block can either be inside the same file as the main function or, if it will be reused, as a `moj_import`, where the uniform file is within `assets//shaders/include/`. Note that any shaders used before resource packs are loaded cannot use `moj_import`. + +Post Effects define their interface blocks in the `uniform` input: + +```json5 +// In assets/examplemod/post_effect/example_post_effect.json +// Inside a 'passes' object +{ + "vertex_shader": "...", + // ... + "uniforms": { + // The name of the interface block + "ExampleUniform": [ + // A parameter within the uniform block + // See `UniformValue` for codec formats + { + // The name of the parameter + "name": "Param1", + // The parameter type, one of: + // - int + // - ivec3 + // - float + // - vec2 + // - vec3 + // - vec4 + // - matrix4x4 (mat4) + "type": "vec4", + // The value stored in the uniform + // Dynamic values from the codebase are no longer supported + "value": [ 0.0, 0.0, 0.0, 0.0 ] + }, + { + "name": "Param2", + "type": "float", + "value": 0 + } + ] + } +} +``` + +#### Texel Buffers + +Texel buffers are typically represented as a `isamplerBuffer` to be queried from, typically using `texelFetch`: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +uniform isamplerBuffer ExampleTexel; + +void main() { + // Read the documentation to understand how texel fetch works + texelFetch(ExampleTexel, gl_InstanceID); +} +``` + +#### Writing Custom Uniforms + +Writing custom uniforms can only happen when you are the one responsible for creating the `RenderPass`. Like before, you create and cache the object before opening the `RenderPass`, then you set the uniform by calling `RenderPass#withUniform`. The only difference is that, instead of providing arbitrary objects, you must now either provide a `GpuBuffer` or `GpuBufferSlice` with the uniform data written to it. For a texel buffer, this is usually some encoded data in the desired texture format (such as a mesh). For an interface block, the easiest method is to use the `Std140Builder` to populate the buffer with the correct values. + +There are many different methods of writing to a `GpuBuffer` or `GpuBufferSlice`, such as using the newly created `MappableRingBuffer`. It is up to you to figure out what method works best in your scenario. The following is simply one solution out of many. + +```java +// Buffer for 'ExampleUniform' +// Takes in the name of the buffer, its usage, and the size +private final MappableRingBuffer ubo = new MappableRingBuffer( + // Buffer name + () -> "Example UBO", + // Buffer Usage + // We set 128 as its used for a uniform and 2 since we are writing to it + // Other bits can be found as constants in `GpuBuffer` + GpuBuffer.USAGE_UNIFORM | GpuBuffer.USAGE_MAP_WRITE, + // The size of the buffer + // Easiest method is to use Std140SizeCalculator to properly calculate this + new Std140SizeCalculator() + // Param1 + .putVec4() + // Param2 + .putFloat() + .get() +); + +// Buffer for 'ExampleTexel' +private final MappableRingBuffer utb = new MappableRingBuffer( + // Buffer name + () -> "Example UTB", + // We set 256 as its used for a texel buffer and 2 since we are writing to it + GpuBuffer.USAGE_UNIFORM_TEXEL_BUFFER | GpuBuffer.USAGE_MAP_WRITE, + // The size of the buffer + // It will likely be larger than this for you + 3 +); + +// In some render method + +// Populate the buffers as required + +// As we are using a ring buffer, this simply uses the next available buffer in the list +this.ubo.rotate(); +// Write the data to the buffer +try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.ubo.currentBuffer(), false, true)) { + Std140Builder.intoBuffer(view.data()) + .putVec4(0f, 0f, 0f, 0f) + .putFloat(0f); +} + +// Similar thing here +this.utb.rotate(); +try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.utb.currentBuffer(), false, true)) { + view.data() + .put((byte) 0) + .put((byte) 0) + .put((byte) 0); +} + +// Create the render pass and pass in the buffers as part of the uniform +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(...)) { + // .. + pass.setUniform("ExampleUniform", this.ubo.currentBuffer()); + pass.setUniform("ExampleTexel", this.utb.currentBuffer()); + // ... +} +``` + +### Fog Environments + +The fog system has been reworked into an environment/render state-like handler. Each environment mostly handles setting up the fog data and color. Some additional processing is provided for the individual `FogType`s and special mob effects. + +All environments are handled through the `FogEnvironment`. A environment is setup via the `setupFog` method, which is responsible for mutating the passed in `FogData` to the values associated with that environment. If the fog colors its surroundings, then `providesColor` should return true, with the base color tint applied in `getBaseColor`. Likewise, if the fog darkens its surroundings, then `modifiesDarkness` should return true, with the modified darkness returned via `getModifiedDarkness`. To determine whether an environment should apply, `isApplicable` is checked. If not applicable, then `onNotApplicable` is called. + +All environments are registered to `FogRenderer#FOG_ENVIRONMENTS`; however, what environment to use is based on `isApplicable` and the list order. For the color and darkness, the fog environment chosen is the last one in the list where one of the `provides*` methods return true. For the actual fog setup, the fog environment chosen is the first one in the list. + +### Render Pass Scissoring now only OpenGL + +The scissoring state has been removed from the generic pipeline code, now only accessible through the OpenGL implementation. Generic region handling has been delegated to `CommandEncoder#clearColorAndDepthTextures`. Note that this does not affect the existing `ScreenRectangle` system that handles the blit facing scissoring. + +- `com.mojang.blaze3d.buffers` + - `BufferType` enum is removed + - `BufferUsage` enum is removed + - `GpuBuffer` now takes two ints represent the size and usage, the type is no longer specified + - `type` is removed + - `usage` now returns an int + - `slice` - Returns a record representing a slice of some buffer. The actual buffer is not modified in any way. + - `$ReadView` -> `$MappedView` + - `GpuBufferSlice` - A record that represents a slice of some buffer by holding a reference to the entire buffer, an offset index of the starting point, and the length of the slice. + - `GpuFence` is now an interface, with its OpenGL implementation moved to `blaze3d.opengl.GlFence` + - `Std140Builder` - A buffer inserter for an interface block laid out in the `std140` format. This is used for the uniform blocks within shaders. + - `Std140SizeCalculator` - An object used for keeping track of the size of some interface block. +- `com.mojang.blaze3d.opengl` + - `AbstractUniform` is removed, replaced by the `Std140*` classes + - `BufferStorage` - A class that create buffers given its types. Its implementations define its general usage. + - `DirectStateAccess` + - `createBuffer` - Creates a buffer. + - `bufferData` - Initializes a buffer's data store. + - `bufferSubData` - Updates a subset of a buffer's data store. + - `bufferStorage` - Creates the data store of a buffer. + - `mapBufferRange` - Maps a section of a buffer's data store. + - `unmapBuffer` - Relinguishes the mapping of a buffer and invalidates the pointer to its data store. + - `GlBuffer` now takes in a `DirectStateAccess`, two ints, and a `ByteBuffer` instead of a `GlDebugLabel` and its `Buffer*` enums + - `initialized` is removed + - `persistentBuffer` - Holds a reference to an immutable section of some buffer. + - `$ReadView` -> `$GlMappedView` + - `GlCommandEncoder` + - `executeDrawMultiple` now takes in a collection of strings that defines the list of required uniforms and a generic indicating the object of the draw call + - `executeDraw` now takes in two `int`, the number of instances of the specified range of indices to be rendered and the base vertex + - `GlConst#toGl` for `BufferType` and `BufferUsage` -> `bufferUsageToGlFlag`, `bufferUsageToGlEnum` + - `GlDebugLabel#pushDebugGroup`, `popDebugGroup` - Profiler commands for grouping similar calls. + - `GlDevice` + - `USE_GL_ARB_buffer_storage` - Sets the extension flag for `GL_ARB_buffer_storage`. + - `getBufferStorage` - Returns the storage responsible for creating buffers. + - `GlProgram` + - `Uniform` fields have been removed + - `safeGetUniform`, `setDefaultUniforms` are removed + - `bindSampler` is removed + - `getSamplerLocations`, `getSamplers`, `getUniforms` -> `getUniforms` which returns a map of names to their `Uniform` objects + - `GlRenderPass` + - `uniforms` now is a `HashMap` + - `dirtSamplers` is removed + - `samplers` map now holds a `GpuTextureView` value + - `pushedDebugGroups` - Returns the number of groups pushed onto the stack. No debug groups must be open for the render pass to be closed. + - `isScissorEnabled` - Returns whether the scissoring state is enabled which crops the area that is rendered to the screen. + - `getScissorX`, `getScissorY`, `getScissorWidth`, `getScissorHeight` - Returns the values representing the scissored rectangle. + - `GlTexture` now takes in an additional integer for the usage and depth/layers + - `flushModeChanges` now takes in an `int` which represents the texture target + - `addViews`, `removeViews` - Manages the views looking at a texture for some mip levels. + - `GlTextureView` - A view implementation of a texture for some mip levels. + - `Uniform` is now a sealed interface which is implemented as either a buffer object, texel buffer, or a sampler +- `com.mojang.blaze3d.pipeline` + - `BlendFunction#PANORAMA` is removed + - `CompiledRenderPipeline#containsUniform` is removed + - `RenderPipeline` + - `$Builder#withUniform` now has an overload that can take in a `TextureFormat` + - `$UniformDescription` now takes in a nullable `TextureFormat` + - `RenderTarget` + - `colorTextureView`, `depthTextureView`, `getColorTextureView`, `getDepthTextureView` - A view of the current color and depth textures. + - `blitAndBlendToTexture` now takes in a `GpuTextureView` instead of a `GpuTexture` +- `com.mojang.blaze3d.platform.Lightning` is now `AutoCloseable` + - `setup*` -> `setupFor`, an instance method that takes in an `$Entry` + - `updateLevel` - Updates the lighting buffer, taking in whether to use the nether diffused lighting. +- `com.mojang.blaze3d.shaders` + - `FogShape` -> `net.minecraft.client.renderer.fog.FogData`, not one-to-one + - `UniformType` now only holds two types: `UNIFORM_BUFFER`, or `TEXEL_BUFFER`, and no longer takes in a count +- `com.mojang.blaze3d.systems` + - `CommandEncoder` + - `clearColorAndDepthTextures` now has an overload that takes in four `int`s representing the region to clear the texture information within + - `writeToBuffer`, `mapBuffer(GpuBuffer, int, int)` now take in a `GpuBufferSlice` instead of a `GpuBuffer` + - `createFence` - Creates a new sync fence. + - `createRenderPass` now takes in a `Supplier`, used for determining the name of the pass to use as a debug group, and `GpuTextureView`s instead of `GpuTexture`s + - `writeToTexture` now takes in an additional `int` representing the depth or layer to write to + - `presentTexture` now takes in a `GpuTextureView` instead of a `GpuTexture` + - `GpuDevice` + - `createBuffer` no longer takes in a `BufferUsage`, with `BufferType` replaced by an `int` + - `getUniformOffsetAlignment` - Returns the uniform buffer offset alignment. + - `createTexture` now takes in additionals `int` for the usage and the number of depth/layers, see `GpuTexture` constants + - `createTextureView` - Creates a view of a texture for a certain range of mip levels. + - `RenderPass` + - `enableScissor` is removed + - `bindSampler` can now take in a nullable `GpuTextureView` + - `setUniform` can either take in a `GpuBuffer` or `GpuBufferSlice` instead of the raw inputs + - `drawIndexed` now takes the following `int`s: the base vertex, the start index, the number of elements, and the prim count + - `drawMultipleIndexed` now takes in a collection of strings that defines the list of required uniforms and a generic indicating the object of the draw call + - `pushDebugGroup`, `popDebugGroup` - Profiler commands for grouping similar calls. + - `$UniformUploader#upload` now takes in a `GpuBufferSlice` instead of an array of `float`s + - `$Draw` now has a generic that passed in to upload any uniforms to the buffer + - `RenderSystem` + - `SCISSOR_STATE` -> `scissorStateForRenderTypeDraws`, now private + - Accessible through `getScissorStateForRenderTypeDraws` + - `enableScissor`, `disableScissor` -> `enableScissorForRenderTypeDraws`, `disableScissorForRenderTypeDraws`, not one to one + - `PROJECTION_MATRIX_UBO_SIZE` - Returns the size of the projection matrix uniform + - `setShaderFog`, `getShaderFog` now deals with a `GpuBufferSlice` + - `setShaderGlintAlpha`, `getShaderGlintAlpha` is removed + - `setShaderLights`, `getShaderLights` now deals with a `GpuBufferSlice` + - `setShaderColor`, `getShaderColor` + - `setup*Lighting` methods are removed + - `setProjectionMatrix`, `getProjectionMatrix` (now `getProjectionMatrixBuffer`) now deals with a `GpuBufferSlice` + - `setShaderGameTime`, `getShaderGameTime` -> `setGlobalSettingsUniform`, `getGlobalSettingsUniform`; not one-to-one + - `getDynamicUniforms` - Returns a list of uniforms to write for the shader. + - `bindDefaultUniforms` - Binds the default uniforms to be used within a `RenderPass` + - `outputColorTextureOverride`, `outputDepthTextureOverride` are now `GpuTextureView`s + - `setupOverlayColor`, `setShaderTexture`, `getShaderTexture` now operate on `GpuTextureView`s instead of `GpuTexture`s +- `com.mojang.blaze3d.textures` + - `GpuTexture` now takes in an int representing the usage flags and number of depth/layers + - `usage` - The flags that define how the texture can be used. + - `depthOrLayers`, `getDepthOrLayers` - Defines how many layers or depths are available for a given texture. This is meant as a generic count for available texture encodings. Only cubemap support is currently available (meaning the layer count must be a multiple of 6). + - `GpuTextureView` - A view of some texture for a range of mip levels. + - `TextureFormat#RED8I` - An 8-bit signed integer handling the red color channel. +- `com.mojang.blaze3d.vertex` + - `ByteBufferBuilder` now takes in a long for the maximum capacity + - `exactlySized` - Returns a buffer that is its maximum capacity. This should be called over the public constructor. + - `DefaultVertexFormat#EMPTY` - A vertex format with no elements. +- `net.minecraft.client.renderer` + - `CachedOrthoProjectionMatrixBuffer` - An object that caches the orthographic projection matrix, rebuilding if the width or height of the screen changes. + - `CachedPerspectiveProjectionMatrixBuffer` - An object that caches the perspective projection matrix, rebuilding if the width, height, or field of view changes. + - `CloudRenderer` + - `FLAG_INSIDE_FACE`, `FLAG_USE_TOP_COLOR` are now private + - `RADIUS_BLOCKS` is removed + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `CubeMap` is now `AutoCloseable` + - `render` no longer takes in the float for the partial tick. + - `DynamicUniforms` - A class that writes the uniform interface blocks to the buffer for use in shaders. + - `DynamicUniformStorage` - A class that holds the uniforms within a slice of a mappable ring buffer. + - `FogParameters` record is removed, now stored in a general `GpuBufferSlice` + - `FogRenderer` now implements `AutoCloseable` -> `.fog.FogRenderer` + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `getBuffer` - Gets the buffer slice that holds the uniform for the current fog mode. + - `setupFog` no longer takes in the `FogMode`, returning nothing + - `$FogData#mode` is removed, replaced by `skyEnd`, `cloudEnd` + - `$FogMode` enums have been replaced with `NONE` and `WORLD`, not one-to-one + - `GameRenderer` + - `getGlobalSettingsUniform` - Returns the uniform for the game settings. + - `getLighting` - Gets the lighting renderer. + - `setLevel` - Sets the current level the renderer is rendering. + - `GlobalSettingsUniform` - An object fod handling the uniform holding the current game settings. + - `LevelRenderer` + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `renderLevel` now takes in a `GpuBufferSlice`, the fog vector, and whether the current position is foggy instead of the `GameRenderer` + - `MappableRingBuffer` - An object that contains three buffers that are written to as required, then rotates to the next buffer to use on end. These are synced using fences. + - `PanoramaRenderer#render` now takes in a boolean for whether to change the spin up the spin rather than two floats. + - `PerspectiveProjectionMatrixBuffer` - An object that holds the projection matrix uniform. + - `PostChain` + - `load` now takes in the `CachedOrthoProjectionMatrixBuffer` + - `addToFrame` no longer takes in the `Consumer` + - `process` no longer takes in the `Consumer` + - `PostChainConfig` + - `$FixedSizedTarget` record is removed + - `$FullScreenTarget` record is removed + - `$InternalTarget` is now a record which can take in an optional width, height, whether the target is persistent, and the clear color to use + - `$Pass#uniforms` is now a `Map>` + - `$Uniform` record is removed + - `PostPass` is now `AutoCloseable`, taking in a `Map>` for the uniforms along with a list of `PostPass$Input`s + - `addToFrame` no longer takes in the `Consumer`, with the `Matrix4f` passed in as a `GpuBufferSlice` + - `$Input` + - `bindTo` is removed + - `texture` - Constructs a `GpuTexture` for the input given the map of resources. + - `samplerName` - Returns the name of the sampler. + - `SkyRenderer#renderSunMoonAndStars` no longer takes in the `FogParameters` + - `UniformValue` - An interface that represents a uniform stored within an interface block. +- `net.minecraft.client.renderer.chunk.SectionRendererDispatcher$RenderSection#setDynamicTransformIndex`, `getDynamicTransformIndex` - Handles the index used to query the correct dynamic transforms for a given section. +- `net.minecraft.client.renderer.fog.environment` + - `AirBasedFogEnvironment` - An environment whose color is derived from the air of the biome + - `AtmosphericFogEnvironment` - The default fog environment if no other special cases match. + - `BlindessFogEnvironment` - An environment that activates if the entity has the blindness effect. + - `DarknessFogEnvironment` - An environment that activates if the entity has the darkness effect. + - `DimensionOrBossFogEnvrionment` - An environment that activates based on if there are any bosses or the dimension special effects. + - `FogEnvironment` - An abstract class that determines how the fog should render at a given location for an entity. + - `LavaFogEnvironment` - An environment that activates if the entity is within lava. + - `MobEffectFogEnvironment` - An environment that activates based on if the entity has a given mob effect. + - `PowderedSnowFogEnvironment` - An environment that activates if the entity is within powdered snow. + - `WaterFogEnvironment` - An environment that activates if the entity is within water. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `setUseMipmaps` - Sets whether the texture should use mipmapping. + - `textureView`, `getTextureView` - Represents the current texture view. + - `CubeMapTexture` - A cubemap compatible texture, textures are expected to have suffixes `_0` to `_5`. + - `ReloadableTexture#doLoad` is now protected +- `net.minecraft.world.level.material.FogType` + - `DIMENSION_OR_BOSS` - Fog for dimension special effects or bosses. + - `ATMOSPHERIC` - Default fog type. + +## Tag Providers: Appender Rewrite + +The `TagAppender` has been rewritten to a degree, changing the basic implementations of `TagsProvider`s. + +By default, the `TagsProvider` no longer provides any useful methods for adding content to a `TagBuilder`. The most you can do is construct the builder using `TagsProvider#getOrCreateRawBuilder` and add elements or tags via their `ResourceLocation` using one of the available `add*` methods. + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends TagsProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries, CompletableFuture> parentProvider) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries, + // Optional: A parent provider to use the generate tags of + // Typically obtained from TagsProvider#contentsGetter + parentProvider + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagBuilder builder = this.getOrCreateRawBuilder(EXAMPLE_TAG); + builder + // Add single element + .addElement(ResourceLocation.fromNamespaceAndPath("minecraft", "apple")) + // Add tag to builder + .addTag(ItemTags.WOOL.location()); + } +} +``` + +But what if we want to reference tags by their `ResourceKey`? Or registry object? This is where the rewritten `TagAppender` comes in. `TagAppender` is an interface with two generics, `E` which represents the type of the entry to add, and `T` which represents the type of the objects within the tag. A `TagAppender` has five common methods: three that add entries (`add`, `addAll`, `addOptional`), and two that add tags (`addTag`, `addOptionalTag`). A `TagAppender` can be created via `forBuilder`, which accepts `ResourceKey`s for entries. + +`KeyTagProvider` provides this for you by adding a `tag` method, creating the appender from a `TagKey`. Generally, datapack registry objects have their tags generated using this provider: + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends KeyTagProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagAppender, Item> builder = this.tag(EXAMPLE_TAG); + builder + // Add single element + .add(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("minecraft", "apple"))) + // Add tag to builder + .addTag(ItemTags.WOOL); + } +} +``` + +`TagAppender`s can also be mapped to change their entry type using the `map` method. This takes in a function which maps the new entry type to the original entry type. `IntrinsicHolderTagsProvider` provides this for you via a `tag` method, creating the appender from a `TagKey` and mapping it using a key extractor. Generally, built-in registry objects have their tags generated using this provider: + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends IntrinsicHolderTagsProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries, + // Maps the registry object to its resource key + item -> item.builtInRegistryHolder().key() + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagAppender builder = this.tag(EXAMPLE_TAG); + builder + // Add single element + .add(Items.APPLE) + // Add tag to builder + .addTag(ItemTags.WOOL); + } +} +``` + +### Copying Tags: Block and Item + +Copying tags no longer exists in the traditional sense, where it loops through the elements of an existing tag. Instead, the implementation has been narrowed down to a general `BlockItemTagsProvider`. This method provides a `TagAppender` by taking in both a block and an item tag, and then converting them appropriately within the `Vanilla*TagsProvider`. As such, it is less copying and more mapping blocks to their associated items. + +The one drawback is that tags that are used within other tags (calling `addTag`) must have the same name. For example, adding `BlockTags#LOGS` only works because there is a `minecraft:logs` for both block and item tags. Meanwhile, adding `BlockTags#CEILING_HANGING_SIGNS` would fail as the associated item tag is `minecraft:hanging_signs` instead of `minecraft:ceiling_hanging_signs`. + +```java +// We will assume there is some TagKey BLOCK_EXAMPLE_TAG +// We will assume there is some TagKey ITEM_EXAMPLE_TAG +public class ExampleBlockItemTagsProvider extends BlockItemTagsProvider { + + @Override + public void run() { + // Add block item tags here + // Will add entries to block or item tag depending on the provider + TagAppender builder = this.tag(BLOCK_EXAMPLE_TAG, ITEM_EXAMPLE_TAG); + builder + // Add single element + .add(Blocks.TERRACOTTA) + // Add tag to builder + // There exists both `minecraft:logs` in block and item tags + .addTag(BlockTags.LOGS); + } +} + +// For some IntrinsicHolderTagsProvider or IntrinsicHolderTagsProvider +@Override +protected void addTags(HolderLookup.Provider registries) { + // Add tags here + new ExampleBlockItemTagsProvider() { + // Or depending on the situation + protected TagAppender tag(TagKey blockTag, TagKey itemTag) { + // Return a TagAppender + // See VanillaItemTagsProvider$BlockToItemConverter for an item example + // See VanillaBlockTagsProvider for a block example + } + }.run(); +} +``` + +- `net.minecraft.data.tags` + - `BlockItemTagsProvider` - A provider that generates tags for block items, using the block and item tag equivalents as a starting point. + - `IntrinsicHolderTagsProvider` + - `tag` now returns the raw `TagAppender` + - `$IntrinsicTagAppender` class is removed + - `ItemTagsProvider` class is removed + - `KeyTagProvider` - A provider which appends elements via their `ResourceKey`. + - `TagsProvider` + - `tag` is removed + - `$TagAppender` -> `TagAppender`, not one-to-one + - `VanillaItemTagsProvider` now implements `IntrinsicHolderTagsProvider` + - `BlockToItemConverter` - A tag appender that adds a block to an item tag. + +## Generic Encoding and Decoding: Replacing Direct NBT Access + +Direct access to get data out of some NBT has been removed completely from higher level objects like entities and block entities. This means that, generally, you cannot directly touch the `CompoundTag` during the serialization process. Instead, indirect access is provided to nbt tags via `ValueInput` and `ValueOutput`. As their name implies, these read values from and write values to the data object, respectively. The methods available are similar to those on `CompoundTag`s. For `ValueInput`, there's the `get*` methods by providing the associated key, and `get*Or` for a get-or-default if not present. There is also `read` for handling `Codec`s. For `ValueOutput`, there's the `put*` methods by providing the associated key and value, and also a `store` for `Codec`s. List variants exists separately on the input/output access. + +As such, most methods that take in a `CompoundTag` now instead take in a `ValueInput` for `read`/`load` or `ValueOutput` for `write`/`save`. + +```java +// For some Entity with an ItemStack stack +@Override +protected void readAdditionalSaveData(ValueInput in) { + super.readAdditionalSaveData(in); + // By default, the input uses a registry ops + this.stack = in.read("example_stack", ItemStack.CODEC).orElse(ItemStack.EMPTY); +} + +@Override +protected void addAdditionalSaveData(ValueOutput out) { + super.addAdditionalSaveData(out); + // By default, the output uses a registry ops + in.storeNullable("example_stack", ItemStack.CODEC, this.stack); +} + +// For some BlockEntity with an int value +@Override + protected void loadAdditional(ValueInput in) { + super.loadAdditional(in); + this.value = in.getIntOr("value", 0); + } + + @Override + protected void saveAdditional(ValueOutput out) { + super.saveAdditional(out); + out.putInt("value", this.value); + } +``` + +### NBT Implementations + +To provide indirect access to `CompoundTag`s, there are implementations of `ValueInput` and `ValueOutput` called `TagValueInput` and `TagValueOutput` respectively. + +A `TagValueOutput` can be created using either `createWithContext` or `createWithoutContext`. 'With context' means that the output has access to the `HolderLookup$Provider` for registry objects while 'without context' does not. Currently, no location uses `createWithoutContext`. Internally, this creates a new `CompoundTag`. Then, this output is passed around to be populated before finally returning the NBT for writing via `buildResult`. + +A `TagValueInput`, on the other hand, can be created via `create`, taking in the `HolderLookup$Provider` and the `CompoundTag` to read from. If the data is stored as a list of objects rather than a single object, you can pass in a `List` and get back a `ValueInputList`. Note this does not handle indicies, only providing an iterable or stream associated implementation. + +### Problem Reporter + +In addition to what's mentioned above, the `create*` methods also take in a `ProblemReporter`, used for collecting all problems encountered when attempting to serialize/deserialize the data. It is up to the implementation to determine whether this report causes a crash or gives a warning. A `ProblemReporter` contains two methods: `report`, which reports a `$Problem`; and `forChild`, which further groups `$Problem`s using a `$PathElement`. Both problems and path elements are simply interface objects that return a string indicating what the problem is or the grouping, respectively. + +There are two common `ProblemReporter`s that are used: `$Collector`, which is typically used with data providers, and `$ScopedCollector`, which is used with disk objects (e.g., entities, block entities, chunks, etc.). A `$Collector` typiccally uses either `forEach` to report each problem one by one, `getReport`/`getTreeReport` to return a stringified problems, or `isEmpty` to list if there are any problems. A `$ScopedCollector` does the same, except this is `AutoCloseable`, in case nothing is done with the output. In these scenarios, the reports are written to a logger. + +Each collector takes in an initial `$PathElement`. This typically comes from the object itself containing some method called `problemPath`, which implements the interface. The `HolderLookup$Provider` is provided in the same fashion. + +```java +// For some object with HolderLookup.Provider registries +// There is also a Logger LOGGER + +// Let's assume our root path element is implemented like so +public record ExamplePathElement(String name) implements ProblemReporter.PathElement { + + @Override + public String get() { + return "Example: " + this.name(); + } +} + +// For a data provider +ProblemReporter.Collector problems = new ProblemReporter.Collector( + // Can be empty for a non-specified root + new ExamplePathElement("data_provider") +); +// Pass around the provider + +// For a disk-based object +try (ProblemReporter.ScopedCollector problems = new ProblemReporter.ScopedCollector(new ExamplePathElement("EXAMPLE TEST"), LOGGER)) { + TagValueOutput out = TagValueOutput.createWithContext(problems, this.registries); + // Pass around the output to write data + + // For the input + // The last parameter can be whatever CompoundTag, using the output as an example + TagValueInput in = TagValueInput.create(problems, this.registries, out.buildResult()); + // Pass around the input to read data +} +``` +- `net.minecraft.nbt.StringTag#escapeWithoutQuotes` - Creates a string that escapes control characters, quotations, apostrophes, and backslashes. +- `net.minecraft.server.level.ServerPlayer` + - `loadAndSpawnParentVehicle` now takes in a `ValueInput` + - `loadAndSpawnEnderPearls` now takes in a `ValueInput` + - `loadGameTypes` now takes in a `ValueInput` +- `net.minecraft.server.players.PlayerList#load` takes in a `ProblemReporter`, returning an optional `ValueInput` +- `net.minecraft.util.ProblemReporter` + - `DISCARDING` - A reporter which discards all reporters. + - `forChild` now takes in a `$PathElement` + - `report` now takes in a `$Problem` + - `$Collector` now has a constructor that takes in the root `$PathElement` + - `isEmpty` - Returns whether there are no reports. + - `forEach` - Loops through all available problems. + - `getReport` now returns a regular `String` + - `getTreeReport` - Gets the report and all its children using DFS. + - `$ElementReferencePathElement` - A path element that references some `ResourceKey`. + - `$FieldPathElement` - A path element that references some string. + - `$IndexedFieldPathElement` - A path element that references some string at an index. + - `$IndexedPathElement` - A path element that references some index. + - `$PathElement` - An interface that defines the grouping or element. + - `$Problem` - An interface that defines a problem with an element. + - `$RootElementPathElement` - A path element that references some `ResourceKey` as the root. + - `$RootFieldPathElement` - A path element that references some string as the root. + - `$ScopedCollector` - A collector that logs warnings when problems arise. +- `net.minecraft.world` + - `ContainerHelper` + - `saveAllItems` now takes in a `ValueOutput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` while returning nothing + - `loadAllItems` now takes in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `LockCode#addToTag`, `fromTag` now takes in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `RandomziableContainer#tryLoadLootTable`, `trySaveLootTable` now takes in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` + - `SimpleContainer` + - `fromTag` -> `fromItemList`, not one-to-one + - `createTag` -> `storeAsItemList`, not one-to-one +- `net.minecraft.world.entity` + - `Entity` + - `saveAsPassenger` now takes in a `ValueOutput` instead of a `CompoundTag` + - `save` now takes in a `ValueOutput` instead of a `CompoundTag` + - `saveWithoutId` now takes in a `ValueOutput` instead of a `CompoundTag`, returning nothing + - `load` now takes in a `ValueInput` instead of a `CompoundTag` + - `readAdditionalSaveData` now takes in a `ValueInput` instead of a `CompoundTag` + - `addAdditionalSaveData` now takes in a `ValueOutput` instead of a `CompoundTag` + - `problemPath` - Returns the path element to report problems from. + - `EntityRenference` + - `store` now takes in a `ValueOutput` instead of a `CompoundTag` + - `read`, `readWithOldOwnerConversion` now take in a `ValueInput` instead of a `CompoundTag` + - `Entity` + - `UUID_TAG` -> `TAG_UUID` + - `create`, `by` now take in a `ValueInput` instead of a `CompoundTag` + - `loadEntityRecursive` now takes in a `ValueInput` instead of a `CompoundTag` + - `loadEntitiesRecursive` now takes in a `ValueInput$ValueInputList` instead of a list of nbt tags + - `loadStaticEntity` now takes in a `ValueInput` instead of a `CompoundTag` + - `EntityReference#store` - Writes the reference data to the `ValueOutput`. + - `Leashable#readLeashData`, `writeLeashData` now take in a `ValueInput`/`ValueOutput` instead of a `CompoundTag` + - `LivingEntity#ATTRIBUTES_FIELD` -> `TAG_ATTRIBUTES` + - `NeutralMob#addPersistentAngerSaveData`, `readPersistentAngerSaveData` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` +- `net.minecraft.world.entity.npc.InventoryCarrier#readInventoryFromTag`, `writeInventoryToTag` now take in a `ValueInput`/`ValueOutput` instead of a `CompoundTag` +- `net.minecraft.world.entity.player.Inventory` + - `save` now takes in a `ValueOutput$TypedOutputList`, returning nothing + - `load` now takes in a `ValueOutput$TypedInputList` +- `net.minecraft.world.entity.variant.VariantUtils` + - `writeVariant` now takes in a `ValueOutput` instead of a `CompoundTag` + - `readVariant` now takes in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `RegistryAccess` +- `net.minecraft.world.entity.vehicle.ContainerEntity#addChestVehicleSaveData`, `readChestVehicleSaveData` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` +- `net.minecraft.world.inventory.PlayerEnderChestContainer` + - `fromTag` -> `fromSlots`, not one-to-one + - `createTag` -> `storeAsSlots`, not one-to-one +- `net.minecraft.world.item` + - `BlockItem#setBlockEntityData` now takes in a `TagValueOutput` instead of a `CompoundTag` + - `ItemStack#parse`, `save` are removed +- `net.minecraft.world.level` + - `BaseCommandBlock#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider`, returning nothing + - `BaseSpawner#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, returning nothing +- `net.minecraft.world.level.block.SculkSpreader#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` +- `net.minecraft.world.level.block.entity.BlockEntity` + - `load*` methods now take in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `save*` methods now take in a `ValueOutput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `removeComponentsFromTag` now takes in a `ValueOutput` instead of a `CompoundTag` + - `parseCustomNameSafe` now takes in a `ValueInput` and key instead of a tag and `HolderLookup$Provider` + - `problemPath` - Returns the path element to report problems from. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner#load`, `store` - Handles writing the spawner data. +- `net.minecraft.world.level.chunk.ChunkAccess#problemPath` - Returns the path element to report problems from. +- `net.minecraft.world.level.storage` + - `PlayerDataStorage#load` now returns a `ValueInput` instead of a `CompoundTag`, taking in a `ProblemReporter` + - `TagValueInput` - A compound tag input. + - `TagValueOutput` - A compound tag output. + - `ValueInput` - An interface that defines how to read data from some object. + - `ValueInputContextHelper` - A class that contains the context used to read object data. + - `ValueOutput` - An interface that defines how to write data to some object. +- `net.minecraft.world.level.storage.loot.ValidationContext` + - `forChild`, `enterElement` now takes in a `ProblemReporter$PathElement` instead of a `String` + - `reportProblem` now takes in a `ProblemReporter$Problem` instead of a `String` + - `$MissingReferenceProblem` - A problem where the referenced object is missing. + - `$ParametersNotProvidedProblem` - A problem where the loot context params are missing. + - `$RecursiveReferenceProblem` - A problem where the referenced object is referencing itself. + - `$ReferenceNotAllowedProblem` - A problem where the referenced object is not allowed to be referenced. +- `net.minecraft.world.level.storage.loot.entries` + - `AlternativesEntry#UNREACHABLE_PROBLEM` - A problem where the altnerative entry can never be executed. + - `CompositeEntryBase#NO_CHILDREN_PROBLEM` - A problem where the composite has no entries. + - `NestedLootTable#INLINE_LOOT_TABLE_PATH_ELEMENT` - An element which indicates that a table is inlined. + +## Server Player Changes + +`MinecraftServer` is no longer publicly exposed on the `ServerPlayer`. Additionally, `serverLevel` has been removed, now replaced with overloading `level` to return the `ServerLevel`. + +- `net.minecraft.server.level.ServerPlayer` + - `server` field is now private + - `serverLevel` -> `level`, still returns `ServerLevel` + +## 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. + +### Leashes + +The leash system has been updated to support up to four on enabled entities. Additionally, the physics have been updated to more properly handle real-world elasicity of some stretchable object. + +- `net.minecraft.client.renderer.entity.state.EntityRenderState` + - `leashState` now returns a list of `$LeashState`s + - `$LeashState#slack` - Whether the leash has any slack. +- `net.minecraft.world.entity` + - `Entity` + - `shearOffAllLeashConnections` - Handles when shears are used to removed a leash. + - `dropAllLeashConnections` - Handles when all leashes should be removed from an entity. + - `getQuadLeashHolderOffsets` - Gets the offsets when four leashes attached to an entity. + - `supportQuadLeashAsHolder` - Returns whether the entity can be leashed up to four times. + - `notifyLeashHolder`, `notifyLeasheeRemoved` - Handles when the leash is ticked on an entity and when its removed. + - `setLeashOffset` is removed + - `getLeashOffset` -> `Leashable#getLeashOffset` + - `Leashable` + - `MAXIMUM_ALLOWED_LEASHED_DIST` - The maximum distance a leash can be attached to an entity. + - `AXIS_SPECIFIC_ELASTICITY` - The resistance of the leash along each axis. + - `SPRING_DAMPENING` - The loss of energy when the leash is oscillating on stretch. + - `TORSIONAL_ELASTICITY` - The resistance of the leash under torque. + - `STIFFNESS` - The stiffness of the leash. + - `ENTITY_ATTACHMENT_POINT` - Specifies the attachment point of the leash on the entity. + - `LEASHER_ATTACHMENT_POINT` - Specifies the attachment point of the leash on the holder. + - `SHARED_QUAD_ATTACHMENT_POINTS` - Specifies the attachment points of the leashes on an entity. + - `canHaveALeashAttachedToIt` -> `canHaveALeashAttachedTo`, not one-to-one + - `leashDistanceTo` - Returns the distance of the leash traveled between the holder and leashee. + - `onElasticLeashPull` - Handles when the leash is being pulled upon. + - `leashSnapDistance` - Returns when the leash will attempt to remove itself from the entity. + - `leashElasticDistance` - Returns the max distance before the elasticity of the leash becomes a physics factor. + - `handleLeashAtDistance` is removed + - `angularFriction` - Returns the angular friction of the entity on a block or within a liquid. + - `whenLeashedTo` - Notifies the entity that the leash is attached. + - `elasticRangeLeashBehaviour`, `legacyElasticRangeLeashBehaviour` -> `checkElasticInteractions`, not one-to-one + - `supportQuadLeash` - Whether the entity can be leashed up to four times. + - `getQuadLeashOffsets` - Returns the offsets of each leash attached to the entity. + - `createQuadLeashOffsets` - Creates the offsets for each of the four possible leash positions. + - `leashableLeashedTo` - Gets all entities within a 32-block radius that are leashed to this holder. + - `$LeashData#angularMomentum` - Returns the angular momentum of the entity when leashed. + - `$Wrench` - A record which handles the force and torque applied to the leash. +- `net.minecraft.world.item.LeadItem#leashableInArea` -> `Leashable#leashableInArea` + +### Removal of Mob Effects Atlas + +The mob effect atlas has been removed and merged with the gui altas. + +- `net.minecraft.client.Minecraft#getMobEffectTextures` is removed +- `net.minecraft.client.gui.Gui#getMobEffectSprite` - Gets the location of the mob effect sprite. +- `net.minecraft.client.resources.MobEffectTextureManage` class is removed +- `AtlasIds#MOB_EFFECTS` is removed + +### Permission Sources + +The permission checks for commands have been abstracted into its own `PermissionSource` interface. This provides the previously provided `hasPermission` method, in addition to a new method `allowsSelectors`, which returns whether the source has the necessary permission to select other entities (defaults to level 2 perms). You can incoporate the permission check into your commands by calling `Commands#hasPermission` with the desired level in `ArgumentBuilder#requires`. + +- `net.minecraft.client.multiplayer` + - `ClientPacketListener` + - `getCommands` now returns a `ClientSuggestionProvider` generic + - `sendUnattendedCommand` now takes in a `Screen` instead of a `boolean` + - `ClientSuggestionListener` now implements `PermissionSource`, taking in a boolean of whether it allows restricted commands + - `allowRestrictedCommands` - Returns whether restricted commands can be suggested. +- `net.minecraft.commands` + - `Commands#hasPermission` - Returns a permission check for the given level. + - `CommandSourceStack` now implements `PermissionSource` + - `ExecutionCommandSource` now implements `PermissionSource` + - `PermissionSource` - Returns the source of the permission to run a command. + - `SharedSuggestionProvider` + - `suggestResgitryElements` now takes in a `HolderLookup` instead of a `Registry` + - `listSuggestions` - Lists the suggestion for some registry elements. + - `hasPermission` is removed +- `net.minecraft.commands.synchronization.SuggestionProviders` + - `AVAILABLE_SOUNDS`, `SUMMONABLE_ENTITIES` now take in a `SharedSuggestionProvider` for their generic + - `cast` - Casts the suggestion provider to the correct type. + - `safelySwap` is removed + - `$Wrapper` -> `$RegisteredSuggestion` +- `net.minecraft.world.entity.Entity#getCommandSenderWorld` is removed + +### Animation Baking + +Animations are now baked into `KeyframeAnimation`. Each `KeyframeAnimation` is made up of entries that apply the keyframes to a given `ModelPart`. To create an animation, the definition should be baked via `AnimationDefinition#bake` in the model constructor, then calling `#apply` or `#applyWalk` as required during `EntityModel#setupAnim`. + +```java +// For some entity model +// Assume some AnimationDefinition EXAMPLE_DEFN +// Assume our ExampleEntityState has some AnimationState exampleAnimState +public class ExampleModel extends EntityModel { + + private final KeyframeAnimation exampleAnim; + + public ExampleModel(ModelPart root) { + // We pass in whatever 'root' that can apply all animations + this.exampleAnim = EXAMPLE_DEFN.bake(root); + } + + @Override + public void setupAnim(ExampleEntityState state) { + super.setupAnim(state); + this.exampleAnim.apply(state.exampleAnimState, state.ageInTicks); + } +} +``` + +- `net.minecraft.client.animation` + - `AnimationDefinition#bake` - Bakes a defined animation to be used on a `Model`. + - `KeyframeAnimation` - A baked animation used to move `ModelPart`s on a given `Model`. + - `KeyframeAnimations#animate` -> `KeyframeAnimation$Entry#apply` +- `net.minecraft.client.model.Model` + - `getAnyDescendantWithName` is removed + - `animate` -> `KeyframeAnimation#apply` + - `animateWalk` - `KeyframeAnimation#applyWalk` + - `applyStatic` -> `KeyframeAnimation#applyStatic` +- `net.minecraft.client.model.geom.ModelPart` + - `getAllParts` now returns a `List` + - `createPartLookup` - Creates a lookup of part names to their `ModelPart`, any duplicate names are ignored. + +### ChunkSectionLayers + +`RenderType`s used for defining how a block or fluid should render are now replaced with `ChunkSectionLayer`s. These functionally do the same thing as the `RenderType`; however, they only specify the `RenderPipeline` to use along with the buffer information. This also means that certain `RenderType`s are removed, like `TRANSLUCENT`, as they were only used for the block chunk rendering. + +This also means that adding to `ItemBlockRenderTypes#TYPE_BY_BLOCK` must specify the `ChunkSectionLayer` instead of the associated `RenderType`. + +- `net.minecraft.client.renderer` + - `ItemBlockRenderTypes` + - `getChunkRenderType` now returns a `ChunkSectionLayer` + - `getRenderLayer(FluidState)` now returns a `ChunkSectionLayer` + - `RenderType` + - `translucent` is removed + - `getRenderTarget`, `getRenderPipeline` is removed + - `chunkBufferLayers` is removed +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` - An enum that defines how an individual chunk layer (e.g., solid blocks, translucent blocks) is rendered. + - `ChunkSectionLayerGroup` - An enum that groups the layers for rendering. + - `ChunkSectionsToRender` - A record that contains the draws of a given chunk, allowing them to be rendered per layer group. + - `RenderChunk` -> `SectionCopy` + - `RenderChunkRegion` -> `RenderSectionRegion` + - `RenderRegionCache#createRegion` now takes in a `long` instead of a `SectionPos` + - `SectionCompiler$Results` + - `globalBlockEntities` -> - `net.minecraft.client.multiplayer.ClientLevel#getGloballyRenderedBlockEntities` + - `renderedLayers` now takes in a `ChunkSectionLayer` for the key + - `SectionMesh` - An interface that defines the mesh of a given section within a chunk + - `SectionRenderDispatcher` + - `getBatchToCount` -> `getCompileQueueSize` + - `setCamera`, `getCameraPosition` are removed + - `blockUntilClear` is removed + - `clearBatchQueue` -> `clearCompileQueue`, now public + - `$CompiledSection` -> `CompiledSectionMesh` + - `$RenderSection` + - `getBuffers` is removed + - `uploadSectionLayer(RenderType, MeshData)` -> `upload(Map, CompiledSectionMesh)`, not one-to-one + - `uploadSectionIndexBuffer` now takes in a `CompiledSectionMesh` and a `ChunkSectionLayer` instead of a `RenderType` + - `getDistToPlayerSqr` is removed + - `getCompiled` -> `getSectionMesh`, not one-to-one + - `rebuildSectionAsync` no longer takes in the `SectionRenderDispatcher` + - `setDynamicTransformIndex`, `getDynamicTransformIndex` are removed + - `$SectionBuffers` -> `SectionBuffers` + - `$TranslucencyPointOfView` -> `TranslucencyPointOfView` +- `net.minecraft.server.level.ChunkMap#getUpdatingChunkIfPresent` is now public +- `net.minecraft.world.level.TicketStorage` + - `purgeStaleTickets` now takes in the `ChunkMap` + - `removeTicketIf` now takes in a `BiPredicate` instead of a `Predicate`, taking in the chunk position and the ticket +- `net.minecraft.world.level.chunk.ChunkAccess#isSectionEmpty` is removed + +### Tag Changes + +- `minecraft:block` + - `plays_ambient_desert_block_sounds` is split into `triggers_ambient_desert_sand_block_sounds`, `triggers_ambient_desert_dry_vegetation_block_sounds` + - `happy_ghast_avoids` + - `triggers_ambient_dried_ghast_block_sounds` +- `minecraft:dialog` + - `pause_screen_additions` + - `quick_actions` +- `minecraft:entity_type` + - `can_equip_harness` + - `followable_friendly_mobs` +- `minecraft:item` + - `harnesses` + - `happy_ghast_food` + - `happy_ghast_tempt_items` + +### List of Additions + +- `com.mojang.blaze3d.pipeline` + - `BlendFunction#TRANSLUCENT_PREMULTIPLIED_ALPHA` - A blend function that assumes the target has a premultiplied alpha from the composite step. + - `RenderPipeline` + - `getSortKey` - Returns a value representing how the element should be sorted for rendering. Used for layer sorting. + - `updateSortKeySeed` - Updates the seed of the sort key, currently unused. +- `com.mojang.blaze3d.systems.RenderSystem` + - `outputColorTextureOverride` - Holds a texture containing the override color used instead of whatever is specified in the `RenderType` target. + - `outputDepthTextureOverride` - Holds a texture containing the override depth used instead of whatever is specified in the `RenderType` target. +- `com.mojang.blaze3d.textures.GpuTexture#setUseMipmaps` - Sets whether the texture should use mipmaps at different distances. +- `net.minecraft` + - `FileUtil#isPathPartPortable` - Returns whether the provided string does not match any of the windows reserved filenames. + - `WorldVersion$Simple` - A simple implementation of the current world version. +- `net.minecraft.advancements.critereon` + - `ItemUsedOnLocationTrigger$TriggerInstance#placedBlockWithProperties` - Creates a trigger where a block was placed with the specified property. + - `PlayerInteractTrigger$TriggerInstance#equipmentSheared` - Creates a criterion trigger that actus upon a player taking off an item on some entity. +- `net.minecraft.client` + - `GameNarrator#saySystemChatQueued` - Narrates a component if either system or chat message narration is enabled. + - `Minecraft#disconnectWithSavingScreen` - Disconnects the current client instance and shows the 'Saving Level' screen. + - `Options` + - `keyQuickActions` - A key mapping for showing the quick actions dialog. + - `cloudRange` - Returns the maximum distance clouds can render at. + - `musicFrequency` - Returns how frequency the background music handled by the `MusicManager` should play. + - `showNowPlayingToast` - Returns whether the 'Now Playing' toast is shown. + - `getFinalSoundSourceVolume` - Computes the volume for the given sound source, with non-master sources being scaled by the master source. + - `NarratorStatus#shouldNarrateSystemOrChat` - Returns whether the current narration status is anything but `OFF`. +- `net.minecraft.client.color.ColorLerper` - A utility class for lerping between color types based on some partial tick. +- `net.minecraft.client.data.models.BlockModelGenerators#createDriedGhastBlock` - Creates the dired ghast block model definition. +- `net.minecraft.client.data.models.model` + - `ModelTemplates#DRIED_GHAST` - A template that uses the `minecraft:block/dried_ghast` parent. + - `TextureMapping#driedGhast` - Creates the default texture mapping for the dried ghast model. + - `TextureSlot#TENTACLES` - Provides a texture key `tentacles`. +- `net.minecraft.client.model` + - `GhastModel#animateTentacles` - Animates the tentacles of a ghast. + - `HappyGhastHarnessModel` - A model representing the a ghast harness. + - `HappyGhastModel` - A model representing a 'tamed' ghast. + - `QuadrupedModel#createBodyMesh` now takes in two booleans for handling if the left and right hind leg textures are mirrored, respectively. +- `net.minecraft.client.multiplayer.ClientLevel` + - `DEFAULT_QUIT_MESSAGE` - The component holding the quit game text. + - `disconnect(Copmonent)` - Disconnects from the current level instance, showing the associated component. +- `net.minecraft.client.renderer.entity.HappyGhastRenderer` - The renderer for a 'tamed' ghast. +- `net.minecraft.client.renderer.entity.layers.RopesLayer` - The render layer for the ropes used on a 'tamed' ghast. +- `net.mienecraft.client.renderer.entity.state.HappyGhastRenderState` - The state of a 'tamed' ghast. +- `net.minecraft.client.resources.model.EquipmentclientInfo$LayerType#HAPPY_GHAST_BODY` - A layer representing the body of a happy ghast. +- `net.minecraft.client.resources.sounds.RidingHappyGhastSoundInstance` - A tickable sound instance that plays when riding a happy ghast. +- `net.minecraft.client.sounds` + - `MusicManager` + - `getCurrentMusicTranslationKey` - Returns the translation key of the currently playing music. + - `setMinutesBetweenSongs` - Sets the frequency between the background tracks. + - `showNowPlayingToastIfNeeded` - Shows the now playing toast if it needs to be seen. + - `$MusicFrequency` - The frequency of the background tracks being played. + - `SoundEngine$PlayResult` - The starting state of the sound trying to be played. +- `net.minecraft.commands.arguments` + - `HexColorArgument` - An integer argument that takes in a hexadecimal color. + - `ResourceOrIdArgument` + - `createGrammar` - Creates the grammar used to parse the argument. + - `$InlineResult` - A result that returns a direct holder. + - `$ReferenceResult` - A result that returns a reference holder. + - `$Result` - An interface that represents the result of some argument parsing. +- `net.minecraft.data.loot.LootTableProvider$MissingTableProblem` - A record that holds the key of some missing built-in table generator. +- `net.minecraft.data.recipes.RecipeProvider` + - `dryGhast` - The recipe for a dried ghast. + - `harness` - The recipe for a colored harness. +- `net.minecraft.gametest.framework.GameTestTicker#startTicking` - Starts ticking the runner for the game tests. +- `net.minecraft.nbt.NbtUtils` + - `addCurrentDataVersion`, `addDataVersion`, adds the data version to some nbt tag. +- `net.minecraft.network.FriendlyByteBuf#writeEither`, `readEither` - Handles an `Either` with the given stream encoders/decoders. +- `net.minecraft.network.codec.ByteBufCodecs` + - `RGB_COLOR` - A stream codec that writes the RGB using three bytes. + - `lenientJson` - Creates a stream codec that parses a json in lenient mode. + - `optionalTagCodec` - Creates a stream codec that parses an `Optional`-wrapped `Tag` using the supplied `NbtAccounter`. +- `net.minecraft.network.protocol.game` + - `ServerboundChangeGameModePacket` - Changes the current gamemode. + - `ServerboundCustomClickActionPacket` - Executes a custom action on the server, currently does nothing. +- `net.minecraft.server.MinecraftServer#handleCustomClickAction` - Handles a custom action sent from a click event. +- `net.minecraft.server.level.ServerLevel` + - `updateNeighboursOnBlockSet` - Updates the neighbors of the current position. If the blocks are not the same (not including their properties), then `BlockState#affectNeighborsAfterRemoval` is called. + - `waitForChunkAndEntities` - Adds a task that causes the server to wait until entities are loaded in the provided chunk range. +- `net.minecraft.sources.SoundSource#UI` - Sounds that come from some user interface. +- `net.minecraft.stats` + - `RecipeBookSettings#MAP_CODEC` + - `ServerRecipeBook#pack`, `loadUntrusted`, `$Packed` - Handles encoding and decoding the data of the recipe book. +- `net.minecraft.util` + - `ARGB` + - `setBrightness` - Returns the brightness of some color using a float between 0 and 1. + - `color` - Returns a ARGB color from a float red and integer alpha. + - `ExtraCodecs` + - `VECTOR2F` + - `VECTOR3I` + - `NBT` + - `LenientJsonParser` - A json parser using lenient rules. + - `Mth#smallestSquareSide` - Takes the ceiled square root of a number. + - `StrictJsonParser` - A json parser using strict rules. +- `net.minecraft.world` + - `Difficulty#STREAM_CODEC` + - `ItemStackWithSlot` - A record which holds a stack along with its slot index. +- `net.minecraft.world.entity` + - `Entity` + - `MAX_MOVEMENTS_HANDELED_PER_TICK` - The maximum number of movements that can be applied to an entity in a given tick. + - `isInClouds` - Returns whether the entity's Y position is between the cloud height and four units above. + - `teleportSpectators` - Teleports the spectators currently viewing from the player's perspective. + - `isFlyingVehicle` - Returns whether the vehicle can fly. + - `clearMovementThisTick` - Clears all movement the entity will make this tick. + - `EntityAttachments#getAverage` - Returns the average location of all attachment points. + - `ExperienceOrb` + - `awardWithDirection` - Adds an experience orb that moves via the specified vector. + - `unstuckIfPossible` - Attempts to find and move the orb to a free position. + - `Mob` + - `isWithinHome` - Returns whether the position is within the entity's restriction radius. + - `canShearEquipment` - Returns whether the current player can shear the equipment off of this mob. +- `net.minecraft.world.entity.ai.control.MoveControl#setWait` - Sets the operation to `WAIT`. +- `net.minecraft.world.entity.ai.goal.TemptGoal` + - `stopNavigation`, `navigateTowards` - Handles navigation towards the player. + - `$ForNonPathfinders` - A tempt goal that navigates towards a wanted position rather than immediately pathfinding. +- `net.minecraft.world.entity.ai.navigation.PathNavigation#canNavigateGround` - Returns whether the entity can pathfind while on the ground. +- `net.minecraft.world.entity.ai.sensing.AdultSensorAnyType` - An adult sensor that ignores whether the entity is the same type as the child. +- `net.minecraft.world.entity.animal` + - `HappyGhast` - An entity representing a happy ghast. + - `HappyGhastAi` - The brain of the happy ghast. +- `net.minecraft.world.entity.decoration.ArmorStand` + - `setArmorStandPose`, `getArmorStandPose`, `$ArmorStandPose` - Handles the pose of the armor stand. +- `net.minecraft.world.entity.monster.Ghast` + - `faceMovementDirection` - Rotates the entity to face its current movement direction. + - `$RandomFloatAroundGoal#getSuitableFlyToPosition` - Gets a position that the ghast should fly to. +- `net.minecraft.world.entity.player.Inventory#SLOT_BODY_ARMOR`, `SLOT_SADDLE` - The indicies for the corresponding slot. +- `net.minecraft.world.entity.projectile.ProjectileUtil#computeMargin` - Computes the bounding box margin to check for a given entity based on its tick count. +- `net.minecraft.world.item.component` + - `ItemAttributeModifiers` + - `forEach` - Applies the consumer to all attributes within the slot group. + - `$Builder#add` - Adds an attribute to apply for a given slot group with a display. + - `$Display` - Defines how an attribute modifier should be displayed within its tooltip. + - `$Default` - Shows the default attribute display. + - `$Hidden` - Does not show any attribute info. + - `$OverrideText` - Overrides the attribute text with the component provided. + - `Equippable$Builder` + - `setCanBeSheared` - Sets whether the equipment can be sheared off the entity. + - `setShearingSound` - Sets the sound to play when a piece of equipment is sheared off an entity. + - `ResolvableProfile#pollResolve` - Returns the profile of the stored id or name. +- `net.minecraft.world.item.equipment.Equippable#harness` - Represents a harness to equip. +- `net.minecraft.world.level` + - `CollisionGetter` + - `getPreMoveCollisions` - Returns an iterable of shapes containing the entity and block collisions at the given bounding box and futue movement direction. + - `getBlockCollisionsFromContext` - Gets the block shapes from the given collision context. + - `GameType#STREAM_CODEC` + - `Level` + - `precipitationAt` - Returns the precipitation at a given position. + - `onBlockEntityAdded` - Logic to run when a block entity is added to the level. +- `net.minecraft.world.level.block` + - `BaseRailBlock#rotate` - Rotates the current rail shape in the associated direction. + - `DriedGhastBlock` - A block that represents a dried ghast. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner$FullConfig` - Represents the entire configuration of a trial. +- `net.minecraft.world.level.dimension.DimensionDefaults` + - `CLOUD_THICKNESS` - The block thickness of the clouds. + - `OVERWORLD_CLOUD_HEIGHT` - The cloud height level in the overworld. +- `net.minecraft.world.level.levelgen.flat.FlatLayerInfo#heightLimited` - Returns a new layer info whether the current height is limited to the specified value, as long as that value is not within the maximum range already. +- `net.minecraft.world.phys` + - `AABB` + - `intersects` - Returns whether the `BlockPos` intersects with this box. + - `distanceToSqr` - Returns the squared distance of the bounding boxes from their furthest point. + - `Vec3#rotateClockwise90` - Rotates the vector 90 degrees clockwise (flip x and z and invert new x value). +- `net.minecraft.world.phys.shapes.CollisionContext` + - `withPosition` - Returns the collision context of an entity with its bottom y position. + +### List of Changes + +- `com.mojang.blaze3d.platform.Window#setGuiScale`, `getGuiScale` now deals with an `int` instead of a `double` +- `net.mineraft` + - `DetectedVersion` no longer implements `WorldVersion` + - `WorldVersion` methods now use record naming schema due to `WorldVersion$Simple` usage + - `getDataVersion` -> `dataVersion` + - `getId` -> `id` + - `getName` -> `name` + - `getProtocolVersion` -> `protocolVersion` + - `getPackVersion` -> `packVersion` + - `getBuildTime` -> `buildTime` + - `isStable` -> `stable` +- `net.minecraft.client` + - `GameNarrator` + - `sayChat` -> `sayChatQueued` + - `say` -> `saySystemQueued` + - `sayNow` -> `saySystemNow` + - `Minecraft` + - `grabPanoramixScreenshot` no longer takes in the window width and height to set + - `disconnect()` -> `disconnectWithProgressScreen` + - `Screenshot#grab`, `takeScreenshot` now takes in an `int` representing the downscale factor +- `net.minecraft.client.main.GameConfig$QuickPlayData` now takes in a `$QuickPlayVariant` + - `path` -> `logPath` + - `singleplayer` -> `variant` with `$QuickPlaySinglePlayerData` + - `multiplayer` -> `variant` with `$QuickPlayMultiplayerData` + - `realms` -> `variant` with `$QuickPlayRealmsData` + - null for `singleplayer`, `multiplayer`, `realms` is represented by `variant` with `$QuickPlayDisabled` +- `net.minecraft.client.data.models.ItemModelGenerators#generateWolfArmor` -> `generateTwoLayerDyedItem` +- `net.minecraft.client.gui.components.DebugScreenOverlay#render3dCrosshair` now takes in the current `Camera` +- `net.minecraft.client.gui.components.debugchart.ProfilerPieChart` + - `RADIUS` is now public + - `CHART_Z_OFFSET` -> `PIE_CHART_THICKNESS`, now public +- `net.minecraft.client.multiplayer` + - `ClientLevel$ClientLevelData#getClearColorScale` -> `voidDarknessOnsetRange`, not one-to-one + - `MultiPlayerGameMode#createPlayer` now takes in an `Input` instead of a `boolean` +- `net.minecraft.client.player.LocalPlayer` now takes in the last sent `Input` instead of a `boolean` for the shift key + - `getLastSentInput` - Gets the last sent input from the server. +- `net.minecraft.client.quickplay.QuickPlay#connect` now takes in a `GameConfig$QuickPlayVariant` instead of a `GameConfig$QuickPlayData` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects` no longer takes in the current cloud level and whether there is a ground + - `LightTexture#getTarget` -> `getTexture` +- `net.minecraft.client.renderer.blockentity.BlockEntityRenderer#shouldRenderOffscreen` no longer takes in the `BlockEntity` +- `net.minecraft.client.resources` + - `AbstractSoundInstance#sound` is now `Nullable` + - `SoundInstance#getSound` is now `Nullable` +- `net.minecraft.client.sounds` + - `SimpleSoundInstance#forMusic` now also takes in the `float` volume + - `SoundEngine` now takes in the `MusicManager` + - `pause` -> `pauseAllExcept`, not one-to-one + - `play` now returns a `$PlayResult` + - `SoundManager` now takes in the `MusicManager` + - `pause` -> `pauseAllExcept`, not one-to-one + - `play` now returns a `SoundEngine$PlayResult` +- `net.minecraft.commands.arguments` + - `ResourceOrIdArgument` now takes in an arbitrary codec rather than a `Holder`-wrapped value + - `ERROR_INVALID` -> `ERROR_NO_SUCH_ELEMENT`, now public, not one-to-one + - `VALUE_PARSER` -> `OPS`, now public, not one-toe + - `ResourceSelectorArgument#getSelectedResources` no longer takes in the `ResourceKey` +- `net.minecraft.commands.functions.StringTemplate` + - `fromString` no longer takes in the line number + - `isValidVariableName` is now public +- `net.minecraft.data.recipes.RecipeProvider#colorBlockWithDye` -> `colorItemWithDye`, now takes in the `RecipeCategory` +- `net.minecraft.gametest.framework.GameTestInfo#prepareTestStructure` is now nullable +- `net.minecraft.network` + - `Connection#send` now takes in a `ChannelFutureListener` instead of a `PacketSendListener` + - `FriendlyByteBuf#readJsonWithCodec` -> `readLenientJsonWithCodec` + - `PacketSendListener` is now a class whose methods return `ChannelFutureListener`s instead of `PacketSendListener`s + - `onSuccess`, `onFailure` are removed +- `net.minecraft.network.codec` + - `ByteBufCodecs#fromCodec` now has an overload that takes in some ops and a codec + - `StreamCodec#composite` now has an overload that takes in ten parameters +- `net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket` is now a record +- `net.minecraft.network.protocol.game` + - `ClientboundChangeDifficultyPacket` is now a record + - `ClientboundCommandsPacket` now takes in a `$NodeInspector` + - `getRoot` is now generic, taking in a `$NodeBuilder` + - `$NodeBuilder` - A builder for a given command. + - `$NodeInspector` - An agent that checks the information of a given command node. + - `ServerboundChangeDifficultyPacket` is now a record +- `net.minecraft.server.ReloadableServerRegistries$Holder#lookup` returns a `HolderLookup$Provider` +- `net.minecraft.server.network.ServerCommonPacketListenerImpl#send` now takes in a `ChannelFutureListener` instead of a `PacketSendListener` +- `net.minecraft.sounds.Music` is now a record +- `net.minecraft.stats.RecipeBookSettings` + - `getSettings` is now public + - `$TypeSettings` is now public +- `net.minecraft.world.entity` + - `AreaEffectCloud#setParticle` -> `setCustomParticle` + - `Entity` + - `checkSlowFallDistance` -> `checkFallDistanceAccumulation` + - `collidedWithFluid`, `collidedWithShapeMovingFrom` are now public + - `canBeCollidedWith` now takes the entity its colliding with + - `spawnAtLocation` now has an overload that takes in a `Vec3` for the offset position + - `removeLatestMovementRecordingBatch` -> `removeLatestMovementRecording` + - `EntityReference` is now final + - `ExperienceOrb` now has an overload that takes in two vectors for the position and movement + - `FlyingMob` is replaced by calling `LivingEntity#travelFlying` + - `LivingEntity#canBreatheUnderwater` is no longer `final` + - `Mob` + - `restrictTo` -> `setHomeTo` + - `getRestrictCenter` -> `getHomePosition` + - `getRestrictRadius` -> `getHomeRadius` + - `clearRestriction` -> `clearHome` + - `hasRestriction` -> `hasHome` +- `net.minecraft.world.entity.ai.attributes` + - `AttributeInstance` + - `save` -> `pack`, `$Packed`; not one-to-one + - `load` -> `apply`, not one-to-one + - `AttributeMap` + - `save` -> `pack`; not one-to-one + - `load` -> `apply`, not one-to-one +- `net.minecraft.world.entity.ai.behavior` + - `AnimalPanic` now has overloads that take in a radius or a position getter + - `BabyFollowAdult#create` now returns a `OneShot` and can take in a `boolean` of whether to target the eye position + - `EntityTracker` can now take in a `boolean` of whether to target the eye position + - `FollowTemptation` now has an overload that checks whether the entity needs to track the entity's eye height. +- `net.minecraft.world.entity.ai.goal.TemptGoal` now has an overload that takes in the stop distance + - `mob` is now a `Mob` + - `speedModifier` is now `protected` +- `net.minecraft.world.entity.ai.memory.MemoryModuleType#NEAREST_VISIBLE_ADULT` now holds a `LivingEntity` +- `net.minecraft.world.entity.ai.navigation` + - `FlyingPathNavigation`, `GroundPathNavigation#setCanOpenDoors` -> `PathNavigation#setCanOpenDoors` +- `net.minecraft.world.entity.ai.sensing.AdultSensor` now looks for a `LivingEntity` + - `setNearestVisibleAdult` is now `protected` +- `net.minecraft.world.entity.animal.*Variants#selectVariantToSpawn` -> `entity.variant.VariantUtils#selectVariantToSpawn`, not one-to-one +- `net.minecraft.world.entity.animal.Fox#isJumping` -> `LivingEntity#isJumping` +- `net.minecraft.world.entity.animal.horse.AbstractHorse` + - `isJumping` -> `LivingEntity#isJumping` + - `setStanding` now takes in an `int` instead of a `boolean` for the stand counter + - the `false` logic is moved to `clearStanding` +- `net.minecraft.world.entity.monster` + - `Ghast` now implements `Mob` + - `$GhastLookGoal` is now public, taking in a `Mob` + - `$GhastMoveControl` is now public, taking in whether it should be careful when moving and a supplied boolean of whether the ghast should stop moving + - `$RandomFloatAroundGoal` is now `public`, taking in a `Mob` and a block distance + - `Phantom` now implements `Mob` +- `net.minecraft.world.entity.player` + - `Abilities` + - `addSaveData` -> `pack`, `$Packed`; not one-to-one + - `loadSaveData` -> `apply`, not one-to-one + - `Player` no longer takes in the `BlockPos` and y rotation +- `net.minecraft.world.entity.projectile` + - `AbstractThrownPotion#onHitAsPostion` now takes in a `HitResult` instead of a nullable `Entity` + - `EyeOfEnder#signalTo` now takes in a `Vec3` instead of a `BlockPos` + - `Projectile` + - `ownerUUID`. `cachedOwner` -> `owner`, now protected; not one-to-one + - `setOwner` now has an overload to take in an `EntityReference` + - `ProjectileUtil` + - `DEFAULT_ENTITY_HIT_RESULT_MARGIN` is now public + - `getEntityHitResult` now takes in a `Projectile` instead of an `Entity` +- `net.minecraft.world.item.ItemStack` + - `forEachModifier` now takes in a `TriConsumer` that provides the modifier display + - `hurtAndBreak` now has an overload which gets the `EquipmentSlot` from the `InteractionHand` +- `net.minecraft.world.item.equipment.Equippable` now takes in whether the equipment can be sheared off an entity and the sound to play when doing so +- `net.minecraft.world.level.BlockGetter` + - `forEachBlockIntersectedBetween` now returns a boolean indicating that each block visited in the intersected area can be successfully visited + - `$BlockStepVisitor#visit` now returns whether the location can be successfully moved to +- `net.minecraft.world.level.block.AbstractCauldronBlock#SHAPE` is now protected +- `net.minecraft.world.level.block.entity` + - `BlockEntity#getNameForReporting` is now public + - `SignBlockEntity#executeClickCommandsIfPresent` now takes in a `ServerLevel` instead of the `Level`, parameters are reordered + - `StructureBlockEntity#saveStructure` now takes in a list of blocks to ignore +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner` now takes in a `$FullConfig` + - `getConfig` -> `activeConfig` + - `get*Config` -> `*config` + - `getData` -> `getStateData` + - `TrialSpawnerData` -> `TrialSpawnerStateData`, serialized form as `TrialSpawnerStateData$Packed`, not one-to-one +- `net.minecraft.world.level.block.sounds.AmbientDesertBlockSoundsPlayer#playAmbientBlockSounds` has been split into `playAmbientSandSounds`, `playAmbientDryGrassSounds`, `playAmbientDeadBushSounds`, `shouldPlayDesertDryVegetationBlockSounds`; not one-to-one +- `net.minecraft.world.level.dimension.DimensionType` now takes in an optional integer representing the cloud height level +- `net.minecraft.world.level.entity` + - `PersistentEntitySectionManager#processPendingLoads` is now public + - `UUIDLookup#getEntity` can now return null +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate#fillFromWorld` now takes in a list of blocks to ignore rather than a single `Block` +- `net.minecraft.world.level.storage.DataVersion` is now a record +- `net.minecraft.world.phys.shapes.CollisionContext#placementContext` now takes in a `Player` instead of an `Entity` + +### List of Removals + +- `net.minecraft.client.Minecraft#disconnect(Screen)` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#getCloudHeight`, `hasGround` + - `LevelRenderer#updateGlobalBlockEntities` +- `net.minecraft.client.renderer.texture.AbstractTexture` + - `defaultBlur` + - `setFilter` +- `net.minecraft.network.chat.Component$Serializer`, `$SerializerAdapter` +- `net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket$Action#*_SHIFT_KEY` +- `net.minecraft.server.ReloadableServerRegistries$Holder#getKeys` +- `net.minecraft.server.players.PlayerList#getPlayerForLogin` +- `net.minecraft.stats` + - `RecipeBookSettings#read`, `write` + - `ServerRecipeBook#toNbt`, `fromNbt` +- `net.minecraft.util` + - `GsonHelper#fromNullableJson(..., boolean)`, `fromJson(..., boolean)` + - `LowerCaseEnumTypeAdapterFactory` +- `net.minecraft.world.entity.ai.attributes.AttributeInstance#ID_FIELD`, `TYPE_CODEC` +- `net.minecraft.world.entity.animal.horse.AbstractHorse#setIsJumping` +- `net.minecraft.world.entity.animal.sheep.Sheep#getColor` +- `net.minecraft.world.entity.monster.Drowned#waterNavigation`, `groundNavigation` +- `net.minecraft.world.entity.projectile.Projectile#findOwner`, `setOwnerThroughUUID` +- `net.minecraft.world.level.Level#disconnect()` +- `net.minecraft.world.level.block` + - `AbstractCauldronBlock#isEntityInsideContent` + - `TerracottaBlock` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner` + - `*_CONFIG_TAG_NAME` + - `codec` +- `net.minecraft.world.level.dimension.DimensionType#parseLegacy` diff --git a/src/detailed-primers/1.21.7-from-1.21.6.md b/src/detailed-primers/1.21.7-from-1.21.6.md new file mode 100644 index 0000000..08689e4 --- /dev/null +++ b/src/detailed-primers/1.21.7-from-1.21.6.md @@ -0,0 +1,38 @@ +# Minecraft 1.21.6 -> 1.21.7 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.6 to 1.21.7. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +## 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](https://misode.github.io/versions/?id=1.21.7&tab=changelog). + +## 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. + +### List of Additions + +- `com.mojang.blaze3d.opengl.DirectStateAccess#copyBufferSubData` - Copies all or part of one buffer object's data store to the data store of another buffer object. +- `com.mojang.blaze3d.pipeline.BlendFunction#INVERT` - Inverts the blend factors of the RGB source and destination. Alpha uses the default one from source and zero from destination. +- `com.mojang.blaze3d.systems.CommandEncoder#copyToBuffer` - Copies the data store of one buffer slice to another buffer slice. +- `net.minecraft.Util#isAarch64` - Returns whether the OS architecture uses aarch64. +- `net.minecraft.client.gui.GuiGraphics#textHighlight` - Adds a highlighted box around the provided bounds. +- `net.minecraft.client.renderer.RenderPipelines#GUI_INVERT` - A render pipeline for drawing a gui element with inverted colors. +- `net.minecraft.client.renderer.item.TrackingItemRenderState` - A render state that tracks the model sources being used to render the item stack. + +### List of Changes + +- `com.mojang.blaze3d.pipeline.RenderPipeline$Builder#withColorLogic` is now deprecated +- `net.minecraft.client.gui.renderer.GuiRenderer#MIN_GUI_Z` is now private +- `net.minecraft.client.gui.render.state.GuiItemRenderState` now takes in a `TrackingItemRenderState` instead of a `ItemStackRenderState` + - `itemStackRenderState` now returns a `TrackingItemRenderState` +- `net.minecraft.client.renderer.RenderPipelines#GUI_TEXT_HIGHLIGHT` now uses the `ADDITIVE` blend function instead of the `OR_REVERSE` color logic +- `net.minecraft.client.renderer.item.ItemStackRenderState#getModelIdentity` -> `TrackingItemRenderState#getModelIdentity` + +### List of Removals + +- `net.minecraft.client.renderer.item.ItemStackRenderState#clearModelIdentity` diff --git a/src/detailed-primers/1.21.8-from-1.21.7.md b/src/detailed-primers/1.21.8-from-1.21.7.md new file mode 100644 index 0000000..b5bb3b5 --- /dev/null +++ b/src/detailed-primers/1.21.8-from-1.21.7.md @@ -0,0 +1,19 @@ +# Minecraft 1.21.7 -> 1.21.8 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.7 to 1.21.8. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +## 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](https://misode.github.io/versions/?id=1.21.8&tab=changelog). + +## 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. + +### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds` - A helper for working around issues with specific graphics hardware. diff --git a/src/detailed-primers/1.21.9-from-1.21.8.md b/src/detailed-primers/1.21.9-from-1.21.8.md new file mode 100644 index 0000000..5e677ef --- /dev/null +++ b/src/detailed-primers/1.21.9-from-1.21.8.md @@ -0,0 +1,3062 @@ +# Minecraft 1.21.8 -> 1.21.9 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.8 to 1.21.9. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Soaryn for pointing out some non-recommended rendering usages +- @Deximus-Maximus for some typos + +## 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](https://misode.github.io/versions/?id=1.21.9&tab=changelog). + +## The Debugging Overhaul + +The entirety of the debug system has been completely overhauled, from exposing the internal debugging tools to the debug screen. This documentation aims to provide a high level overview for handling your own debug screen and renderer additions. + +### Debug Renderers + +Vanilla now allows users to see the debug renderers provided by the internal API by enabling them through the JVM properties via `-DMC_DEBUG_ENABLED` with whatever other desired flags. Users can take advantage of these exposed features to handle their own renderers through the vanilla provided pipeline. This overview will explain via patching the existing renderers and subscribers as needed, but these can generally be set up wherever needed. The benefit vanilla provides is its integration into existing objects (e.g. entities, block entities) and the general synchronization across the network. Of course, you can always use a simple `boolean` instead. After all, although the flags in `SharedConstants` are final, they are still checked every tick. + +#### Subscribe to Debuggers + +In most cases, information that you want to render and debug are stored on the server side. Sometimes, the information in question will be synced on the client, but in most cases it is usually some kind of partial state only necessary for rendering. + +```java +// An example object on the server +public record ExampleObject(Block held, int count) {} + +// An example on the client +// Count is not used for rendering, only for server logic +public class ExampleRenderState { + Block held; +} +``` + +Therefore, if we want to see the additional data from the server, we need some method to not only synchronize it to the client, but also update it whenever the value changes. To do so, vanilla provides `DebugSubscription`s: a class that stores the information required to sync an object if it has changed. The constructor contains two fields: the `StreamCodec` to sync the object across the network, and an optional `int` that, when greater than zero, will purge the synced value from the client if there were no more updates within the specified time. + +To handle the logic associated with synchronization, the server makes use of `TrackingDebugSynchronizer`s to handle player listeners and sync the object when necessary, and `LevelDebugSynchronizers` to handle the general tracking and ticking of the synchronizers. This data is then sent to the `ClientDebugSubscriber` for storage and the `DebugRenderer` for rendering. Note that clients can only see the debug information if they are either the owner of a singleplayer world or is an operator of the server. Additionally, the client can only request subscriptions that are added to the set provided by `ClientDebugSubscriber#requestedSubscriptions`. + +`DebugSubscription`s must be registered to `BuiltInRegistries#DEBUG_SUBSCRIPTION`: + +```java +public static final DebugSubscription EXAMPLE_OBJECt = Registry.register( + BuiltInRegistries.DEBUG_SUBSCRIPTION + ResourceLocation.withNamespaceAndPath("examplemod", "example_object"), + new DebugSubscription<>( + // The stream codec to sync the example object + StreamCodec.composite( + ByteBufCodecs.registry(Registries.BLOCK), ExampleObject::block, + ByteBufCodecs.VAR_INT, ExampleObject::count, + ExampleObject::new + ), + // The maximum number of ticks between updates + // before the data is purged from the client + // Set to zero if it should never expire + 0 + ) +); +``` + +To be able to check for updates properly, the object used must correctly implement `hashCode` and `equals`, not relying on the object identity. + +#### Debug Sources + +So, how do we tell the synchronizer to track and update our `DebugSubscription`? Well, you can extend `TrackingDebugSynchronizer` or use its subclasses and implement the tracking and syncing logic yourself, either by patching `LevelDebugSynchronizers` or creating your own. However, if the data you would like to track is directly attached to a `LevelChunk`, `Entity`, or `BlockEntity` and can be updated from their associated server object, you can make use of the `DebugValueSource`. + +`DebugValueSource` is a way to register `DebugSubscription`s as a `TrackingDebugSynchronizer$SourceSynchronizer`. This will poll and send updates to every player tracking the source with the subscription enabled every tick. Registering a `DebugSubscription` is done via `DebugValueSource#registerDebugValues`, taking in the server level and the `$Registration` interface. The registration is then handled via `$Registration#register` by passing in the subscription and a supplier to construct the subscription value. + +```java +// Assume we have some ExampleObject exampleObject in the below classes + +// For some BlockEntity, Entity, or LevelChunk subclass +@Override +public void registerDebugValues(ServerLevel level, DebugValueSource.Registration registrar) { + super.registerDebugValues(level, registrar); + // Register our subscription + registrar.register( + // The subscription + EXAMPLE_OBJECT, + // The supplied subscription object + () -> this.exampleObject + ); +} +``` + +#### Rendering the Debug Information + +Once the information has been synced to the client and stored within `ClientDebugSubscriber` (assuming you are using the above method), we now need to render that information to the screen. This is typically handled through `DebugRenderer#render`, which checks the enabled debug renderers via `refreshRendererList` before running the associated renderers. Technically, it doesn't particularly matter where as the data can be obtained at any point in the render process, but this will assume you are patching `refreshRendererList` to add your own renderer to either the opaque or translucent renderers. + +All renderers implement `DebugRenderer$SimpleDebugRenderer` to call `render`, which provides the current `PoseStack`, buffer source, camera XYZ, and `Frustum`. In addition, vanilla passes in a `DebugValueAccess` via `Connection#createDebugValueAccess` to get the synched debug information from the `ClientDebugSubscriber`. `DebugRenderer` provides simple methods to render text or boxes in specific locations using `render*`. + +The `DebugValueAccess` contains two types of methods: `get*Value` to obtain the debug object for that specific source (e.g. position, entity); and `forEach*`, which loops through all sources sending out the debug object. Which you use depends on which source you registered your `DebugSubscription` to. + +```java +// We will assume that our example object was registered to an entity +public class ExampleObjectRenderer implements DebugRenderer.SimpleDebugRenderer { + + @Override + public void render(PoseStack poseStack, MultiBufferSource bufferSource, double x, double y, double z, DebugValueAccess access, Frustum frustum) { + // Loop through all blocks with our example object + access.forEachEntity(EXAMPLE_OBJECT, (entity, exampleObject) -> { + // Render the debug info + DebugRenderer.renderTextOverMob( + poseStack, bufferSource, entity, + // Text Y offset (entities display a lot of information) + 100, + // Text to render + "Held Count: " + exampleObject.count(), + // Text color + 0xFFFFFFFF, + // The scale of the text + 1f + ); + }); + } +} +``` + +## Debug Screens + +The debug screens allows for users to to enable, disable, or only show in F3 specific components. This modular system allows for modders to add their own debug entries to the screen. Not all parts of this explanation is accessible without a bit more modding work, so those areas will be specifically pointed out. + +#### `DebugScreenEntry` + +Every debug option has its own entry that either defines what is being displayed (e.g., fps, memory), or no-ops to be handled by a separate implementation (e.g., entity hitboxes, chunk borders). This is known as a `DebugScreenEntry`, which defines three methods. + +First is the `category`. In vanilla, this is almost always `DebugEntryCategory#SCREEN_TEXT`, as all a debug entry does is draw text to the screen. The other available option `RENDERER` is only for no-op as the rendering options always rendered independent from the debug screen. `DebugEntryCategory` is simply a record with a label and some sort of sort key value, so more can be added by calling the constructor. All the category is used for is searching in the debug options screen. + +Next is `isAllowed`. This method determines whether the debug option should render on the screen independent of the entry status. By default, this is true only when the `Minecraft#showOnlyReducedInfo` accessibility option is false. Some debug entries override this method to always return true, or if some other check passes. + +Finally, there is the `display` method. This is responsible for drawing the text to the screen using the `DebugScreenDisplayer`. It also takes in the current `Level`, client chunk, and server chunk. The `DebugScreenDisplayer` has four methods that each draw text to the screen. First, there is the standard `addLine` class, which just adds the string to either the left or right side depending on what element its rendered as. These will always come one right after the other. Then, there is `addPriorityLine`, which will always be added to the top of either the left or the right side. Finally, there is `addToGroup`, which takes an additional key to render the lines as one separate group with an extra new line added at the end. + +```java +public class ExampleDebugEntry implements DebugScreenEntry { + + public static final ResourceLocation GROUP_ONE = ResourceLocation.fromNamespaceAndPath("examplemod", "group_one"); + public static final ResourceLocation GROUP_TWO = ResourceLocation.fromNamespaceAndPath("examplemod", "group_two"); + + + @Override + public void display(DebugScreenDisplayer displayer, @Nullable Level level, @Nullable LevelChunk clientChunk, @Nullable LevelChunk serverChunk) { + // The following will display like so if it is the only entry on the screen: + // First left! First Right! + // + // Hello world! Random text! + // Lorem ipsum. + // I am another group! + // I am one group This will appear after with no line breaks! + // All in a row + // Provided in a list. + // + + displayer.addLine("Hello world!"); + displayer.addLine("Lorem ipsum."); + displayer.addLine("Random text!"); + + // These will be displayed first + displayer.addPriorityLine("First left!"); + displayer.addPriorityLine("First right!"); + + // These will be grouped separately based on the key + displayer.addToGroup(GROUP_ONE, List.of( + "I am one group", + "All in a row", + "Provided in a list." + )); + + displayer.addToGroup(GROUP_TWO, "I am another group!"); + displayer.addToGroup(GROUP_TWO, "This will appear after with no line breaks!"); + } + + @Override + public boolean isAllowed(boolean reducedDebugInfo) { + // Always show regardless of accessibility option + return true; + } +} +``` + +Then, simply register your entry to `DebugScreenEntries` to have it display. It can be toggled on through the debug menu using the provided key + +```java +// This method is private, so its access will need to be widened +DebugScreenEntries.register( + // The id, this will be displayed on the options screen + ResourceLocation.fromNamespaceAndPath("examplemod", "example_entry"), + // The screen entry + new ExampleScreenEntry(); +); +``` + +#### External Toggles and Checks + +What if you want to toggle the active status separately from the options menu? What if you want to check is an entry is enabled to display debug data in-game? This can be done by accessing the `DebugScreenEntryList` through the `Minecraft` instance. + +Toggling the current status can be done via `DebugScreenEntryList#toggleStatus`. How this behaves changes depending on what screen is active. Basically, calling toggle will always flip the debug entry on or off: if it's not currently on screen, it will render on screen and vice versa. If in F3, then toggling on will only render that debug entry when F3 is on. + +The status of the entry can then be checked using `DebugScreenEntryList#isCurrentlyEnabled`. This will only check if the debug screen is in the currently on list and not check `DebugScreenEntry#isAllowed`. + +```java +// Lets create another entry +public static final ResourceLocation EXAMPLE_TOGGLE = DebugScreenEntries.register( + ResourceLocation.fromNamespaceAndPath("examplemod", "example_toggle"), + // We're using noop as nothing is being displayed as text + new DebugEntryNoop(); +); + +// To toggle: +Minecraft.getInstance().debugEntries.toggleStatus(EXAMPLE_TOGGLE); + +// To check if enabled: +if (Minecraft.getInstance().debugEntries.isCurrentlyEnabled(EXAMPLE_TOGGLE)) { + // ... +} +``` + +#### Profiles + +Profiles are defined presets that can be configured to the user's desire. Currently, profiles are hardcoded to either default or performance. To extend the system, you need to be able to dynamically add an entry to the `DebugScreenProfile` enum, make the `DebugScreenEntries#PROFILES` map mutable to add your profile and preset, and modify the debug option screen with your profile button. + +- `net.minecraft.SharedConstants` + - `DEBUG_SHUFFLE_MODELS` - A flag that likely shuffles the model loading order. + - `DEBUG_FLAG_PREFIX` - A prefix put in front of every debug flag. + - `USE_DEBUG_FEATURES` -> `DEBUG_ENABLED` + - `DEBUG_RENDER` is removed + - `DEBUG_WORLDGENATTEMPT` is removed + - `debugGenerateStripedTerrainWithoutNoise` is removed + - `DEBUG_RESOURCE_GENERATION_OVERRIDE` is removed + - `DEBUG_POI` - Enables the POI debug renderer. + - `DEBUG_PANORAMA_SCREENSHOT` - When enabled, allows the user to take a panorama screenshot. + - `DEBUG_CHASE_COMMAND` - When enabled, adds the chase command. + - `FAKE_MS_LATENCY` -> `DEBUG_FAKE_LATENCY_MS` + - `FAKE_MS_JITTER` -> `DEBUG_FAKE_JITTER_MS` + - `DEBUG_VERBOSE_COMMAND_ERRORS` - When enabled, outputs verbose errors through the chat box. + - `DEBUG_DEV_COMMANDS` - When enabled, adds the commands used for debugging the game. +- `net.minecraft.client.Minecraft` + - `debugEntries` - Returns a list of debug features and what should be shown on screen. + - `fpsString`, `sectionPath`, `sectionVisibility` are removed + - `debugRenderer` -> `LevelRenderer#debugRenderer` +- `net.minecraft.client.gui.Gui` + - `renderDebugOverlay` is now public + - `shouldRenderDebugCrosshair` is removed +- `net.minecraft.client.gui.components.DebugScreenOverlay` + - `drawGameInformation`, `drawSystemInformation` are removed + - `getGameInformation`, `getSystemInformation` are removed + - `toggleOverlay` is removed +- `net.minecraft.client.gui.components.debug` + - `DebugEntryBiome` - A debug entry displaying the biome the camera entity is within. + - `DebugEntryCategory` - A category that describes how a debug entry is displayed. + - `DebugEntryChunkGeneration` - A debug entry displaying the current chunk generation info. + - `DebugEntryChunkRenderStats` - A debug entry displaying the current section statistics. + - `DebugEntryChunkSourceStats` - A debug entry displaying the general metadata of the chunk sources. + - `DebugEntryEntityRenderStats` - A debug entry displaying the general metadata of the entity storage. + - `DebugEntryFps` - A debug entry displaying the frames per second and vsync info. + - `DebugEntryGpuUtilization` - A debug entry displaying the GPU utilization. + - `DebugEntryHeightmap` - A debug entry displaying the height maps at the current position. + - `DebugEntryLight` - A debug entry displaying the client light information. + - `DebugEntryLocalDifficulty` - A debug entry displaying the current world difficulty and time. + - `DebugEntryLookingAtBlock` - A debug entry displaying the block the camera is currently looking at. + - `DebugEntryLookingAtEntity` - A debug entry displaying the entity the camera is currently looking at. + - `DebugEntryLookingAtFluid` - A debug entry displaying the fluid the camera is currently looking at. + - `DebugEntryMemory` - A debug entry displaying the memory allocated and used by the game. + - `DebugEntryNoop` - A debug entry displaying nothing. + - `DebugEntryParticleRenderState` - A debug entry displaying the number of particles being rendered. + - `DebugEntryPosition` - A debug entry displaying the current position and rotation of the camera entity. + - `DebugEntryPostEffect` - A debug entry displaying the currently applied post effect. + - `DebugEntrySectionPosition` - A debug entry displaying the current section position. + - `DebugEntrySimplePerformanceImpactors` - A debug entry displaying the graphics mod, cloud status, and biome blend radius. + - `DebugEntrySoundMood` - A debug entry displaying the current sound played and player mood. + - `DebugEntrySpawnCounts` - A debug entry displaying the entity spawn counts per mob category. + - `DebugEntrySystemSpecs` - A debug entry displaying the specs of the running machine. + - `DebugEntryTps` - A debug entry displaying the general ticks per second. + - `DebugEntryVersion` - A debug entry displaying the current Minecraft version. + - `DebugScreenDisplayer` - An interface that the debug entries use to display elements to the screen. + - `DebugScreenEntries` - The debug entries registered by Minecraft. + - `DebugScreenEntry` - An element that shows up, if enabled, when the debug overlay is enabled. + - `DebugScreenEntryList` - The options information for what debug elements are displayed on screen. + - `DebugScreenEntryStatus` - The status of when a debug entry should be displayed. + - `DebugScreenProfile` - An enum denoting the profiles that the debug screen can set when deciding what entries to show. +- `net.minecraft.client.gui.screen.debug.DebugOptionsScreen` - A screen that allows the user to change the displayed debug entries for a profile. +- `net.minecraft.client.renderer.LevelRenderer` + - `getSectionStatistics` is now nullable + - `getEntityStatistics` is now nullable + - `gameTestBlockHighlightRenderer` - The renderer for the block highlight within a game test. +- `net.minecraft.client.renderer.debug.DebugRenderer` + - `switchRenderChunkborder` -> `DebugScreenEntries#CHUNK_BORDERS`, not one-to-one + - `toggleRenderOctree` -> `DebugScreenEntries#CHUNK_SECTION_OCTREE`, not one-to-one +- `net.minecraft.client.multiplayer` + - `DebugSampleSubscriber` -> `ClientDebugSubscriber`, not one-to-one + - `ClientPacketListener#createDebugValueAccess` - Creates the access to get the current debug values. +- `net.minecraft.client.renderer.debug` + - `BeeDebugRenderer#addOrUpdateHiveInfo`, `addOrUpdateBeeInfo`, `removeBeeInfo` are removed + - `BrainDebugRenderer` + - `addPoi`, `removePoi`, `$PoiInfo` are removed + - `setFreeTicketCount` is removed + - `addOrUpdateBrainDump`, `removeBrainDump` are removed + - `BreezeDebugRenderer` now implements `DebugRenderer$SimpleDebugRenderer` + - `render` now takes in a `DebugValueAccess` + - `clear`, `add` are removed + - `DebugRenderer` no longer takes in the `Minecraft` instance + - All field renderers have been removed from public access, instead being store in on of the `*Renderers` lists + - `worldGenAttemptRenderer` is removed + - `renderTextOverBlock` - Renders the given stream above the provided block position. + - `renderTextOverMob` - Renders the given string over the provided entity. + - `refreshRendererList` - Populates the renderer lists with the enabled debug renderers. + - `render`, `renderAfterTranslucents` have been merged into `render`, where a `boolean` determines whether to render the translucent or opaque renderers + - `$SimpleDebugRenderer` + - `render` now takes in a `DebugValueAccess` and `Frustum` + - `clear` is removed + - `EntityBlockIntersectionDebugRenderer` - A debug renderer for displaying the blocks the entity is intersecting with. + - `GameEventListenerRenderer` no longer takes in the `Minecraft` instance + - `trackGameEvent`, `trackListener` are removed + - `GameTestDebugRenderer` -> `GameTestBlockHighlightRenderer`, not one-to-one + - `addMarker` -> `highlightPos`, not one-to-one + - `GoalSelectorDebugRenderer#addGoalSelector`, `removeGoalSelector` are removed + - `NeighborsUpdateRenderer` no longer takes in the `Minecraft` instance + - `addUpdate` is removed + - `OctreeDebugRenderer` now implements `DebugRenderer$SimpleDebugRenderer` + - `PathfindingRenderer#addPath` is removed + - `PoiDebugRenderer` - A debug renderer for displaying the point of interests. + - `RaidDebugRenderer#setRaidCenters` is removed + - `RedstoneWireOrientationsRenderer` no longer takes in the `Minecraft` instance + - `addWireOrientation` is removed + - `StructureRenderer` no longer takes in the `Minecraft` instance + - `addBoundingBox` is removed + - `VillagerSectionsDebugRenderer#setVillageSection`, `setNotVillageSection` are removed + - `WorldGenAttemptRenderer` class is removed +- `net.minecraft.core.registries.BuiltInRegistries`, `Registries#DEBUG_SUBSCRIPTION` - A registry for subscriptions to debug handlers. +- `net.minecraft.gametest.framework` + - `GameTestAssertPosException#getMessageToShowAtBlock` now returns a `Component` + - `GameTestRunner#clearMarkers` is removed +- `net.minecraft.network.protocol.common.custom` + - All classes have been moved to `net.minecraft.util.debug` + - They are no longer payloads, instead just records containing the object info and an associated stream codec + - If the payload class had an associated object inner class, then that class was moved and the payload class removed + - Otherwise the payload class was added without the `*Payload` suffix, most of the time with an `*Info` suffix +- `net.minecraft.network.protocol.game` + - `ClientboundDebugBlockValuePacket` - A packet sent to the client about a debug value change on a block position. + - `ClientboundDebugChunkValuePacket` - A packet sent to the client about a debug value change on a chunk position. + - `ClientboundDebugEntityValuePacket` - A packet sent to the client about a debug value change on an entity. + - `ClientboundDebugEventPacket` - A packet sent to the client about the debug event fired. + - `ClientboundGameTestHighlightPosPacket` - A packet sent to the client about the game test position to highlight. + - `ClientGamePacketListener` + - `handleDebugChunkValue` - Handles the debug chunk position packet. + - `handleDebugBlockValue` - Handles the debug block position packet. + - `handleDebugEntityValue` - Handles the debug entity packet. + - `handleDebugEvent` - Handles the firing debug event. + - `handleGameTestHighlightPos` - Handles the provided position being highlighted. + - `DebugPackets` class is removed + - `ServerboundDebugSampleSubscriptionPacket` -> `ServerboundDebugSubscriptionRequestPacket`, not one-to-one + - `ServerGamePacketListener#handleDebugSampleSubscription` -> `handleDebugSubscriptionRequest`, not one-to-one +- `net.minecraft.server.MinecraftServer` + - `subscribeToDebugSample` is removed + - `debugSubscribers` - Returns a map of the tracked subscriptions to the list of players that have it enabled. +- `net.minecraft.server.level` + - `ChunkMap` + - `isChunkTracked` is now public + - `getChunks` is removed + - `ServerLevel#debugSynchronizers` - Returns the debugger handler and synchronizer for the level. + - `ServerPlayer` + - `requestDebugSubscriptions` - Sets the debuggers that the player is listening for. + - `debugSubscriptions` - Returns the debuggers that the player is listening for. +- `net.minecraft.util.debug` + - `DebugSubscription` - A tracked data point that can be listened or subscribed to. + - `DebugSubscriptions` - Vanilla debug subscriptions. + - `DebugValueAccess` - Accesses the values tracked by the debug subscription, used on the client for the debug renderers. + - `DebugValueSource` - Defines a source object that provides debug values to track, such as an entity. + - `LevelDebugSynchronizers` - Handles sending the subscription data across the network to the tracking clients. + - `ServerDebugSubscribers` - Handles the global state of players subscribed to the currently enabled subscriptions. + - `TrackingDebugSynchronizer` - Handles the list of players subscribed to a subscription. +- `net.minecraft.util.debugchart` + - `DebugSampleSubscriptionTracker` class is removed + - `RemoteDebugSampleType` now takes in a `DebugSubscription` + - `subscription` - Returns the subscription reported by the sample type. + - `RemoteSampleLogger` now takes in `ServerDebugSubscribers` instead of `DebugSampleSubscriptionTracker` +- `net.minecraft.world.entity` + - `Entity` now implements `DebugValueSource` + - `Mob#sendDebugPackets` is removed +- `net.minecraft.world.entity.ai.village.poi` + - `PoiManager#getFreeTickets` -> `getDebugPoiInfo`, not one-to-one + - `PoiSection#getDebugPoiInfo` - Returns the debug poi info for the given position. +- `net.minecraft.world.level.block.entity` + - `BlockEntity` now implements `DebugValueSource` + - `TestInstanceBlockEntity#markError`, `clearErrorMarkers`, `getErrorMarkers`, `$ErrorMarker` - Handles the error markers set by the test instance. +- `net.minecraft.world.level.chunk.LevelChunk` now implements `DebugValueSource` +- `net.minecraft.world.level.pathfinder.PathFinder#setCaptureDebug` - Sets whether the path should be captured for debugging. +- `net.minecraft.world.level.redstone.CollectingNeighborUpdater#setDebugListener` - Sets the listener for block location changes for debugging. + +## Feature Submissions: The Movie + +The entirety of the rendering pipeline, from entities to block entities to particles, has been reworked into a submission / render phase system known as features. This guide will go over the basics of the feature system itself followed by how each major type are implemented using it. + +### Submission and Rendering + +The feature system, like GUIs, is broken into two phases: submission and rendering. The submission phase is handled by the `SubmitNodeCollector`, which basically collects the data required to abstractly render an object to the screen. This is all done through the `submit*` methods, which generally take a `PoseStack` to place the object in 3D space, and any other required data such as the model, state, render type, etc. + +Here is a quick overview of what each method takes in: + +Method | Parameters +:---------------------:|:---------- +`submitHitbox` | A pose stack, render state of the entity, and the hitboxes render state +`submitShadow` | A pose stack, the shadow radius, and the shadow pieces +`submitNameTag` | A pose stack, an optional position, the Y offset, the text component, if the text should be seethrough (like when sneaking), light coordinates, and the camera render state +`submitText` | A pose stack, the XY offset, the text sequence, whether to add a drop shadow, the font display mode, light coordinates, color, background color, and outline color +`submitFlame` | A pose stack, render state of the entity, and a rotation quaternion +`submitLeash` | A pose stack and the leash state +`submitModel` | A pose stack, entity model, render state, render type, light coordinates, overlay coordinates, tint color, an optional texture, outline color, and an optional crumbling overlay +`submitModelPart` | A pose stack, model part, render type, light coordinates, overlay coordinates, an optional texture, whether to use item glint over entity glint if render type is not transparent, whether to render the glint overlay, tint color, an optional crumbling overlay, and an outline color +`submitBlock` | A pose stack, block state, light coordinates, overlay coordinates, and outline color +`submitMovingBlock` | A pose stack and the moving block render state +`submitBlockModel` | A pose stack, the render type, block state model, RGB floats, light coordinates, overlay coordinates, and outline color +`submitItem` | A pose stack, item display context, light coordinates, overlay coordinates, outline color, tint layers, quads, render type, and foil type +`submitCustomGeometry` | A pose stack, render type, and a function that takes in the current pose and `VertexConsumer` to create the mesh +`submitParticleGroup` | A `SubmitNodeCollector$ParticleGroupRenderer` + +Technically, the `submit*` methods are provided by the `OrderedSubmitNodeCollector`, of which the `SubmitNodeCollector` extends. This is because features can be submitted to different orders, which function similarly to strata in GUIs. By default, all submit calls are pushed onto order 0. Using `SubmitNodeCollector#order` with some integer and then calling the `submit*` method, you can have an object render before or after all features on a given order. This is stored as an AVL tree, where each order's data is stored in a `SubmitNodeCollection`. With the current default feature rendering order, this is only used in very specific circumstances, such as rendering a slime's outer body or equipment layers. + +```java +// Assume we have access to the `SubmitNodeCollector` collector + +// This will render in order 0 +collector.submitModel(...); + +// This will render before the `submitModel` call +collector.order(-1).submitShadow(...); + +// This will render after the `submitModel` call +collector.order(1).submitNameTag(...); +``` + +The render phase is handled through the `FeatureRenderDispatcher`, which renders the object using their submitted feature renderers. What are feature renderers? Quite literally an arbitrary method that loops through the node contents its going to push to the buffer. Currently, for a given order, the features push their vertices like so: shadows, models, model parts, flame animations, entity name tags, arbitrary text, hitboxes, leashes, items, blocks, custom render pipelines, and finally particles. Each order, starting from the smallest number to the largest, will rerun all of the feature renders until it reaches the end of the tree. All submissions are then cleared for next use. + +Most of the feature dispatchers are simply run a loop over its collection. Those that store the render type batch the render calls into one buffer. `ModelFeatureRenderer`, meanwhile, goes one step further, sorting its translucent models by distance from the camera and sends them to the buffer after all opaque models. + +### Entity Models + +So, how does this affect entities? Let's start with the root `Model` that makes up all entity models. `Model` now has a generic which is used to pass in the state of the backing object to `setupAnim`, which has also been moved to `Model`. This means that the base model class is rarely passed around, instead opting for some subtype, like `Model$Simple` for signs. Given that most `EntityModel`s already require a generic of `EntityRenderState`, this does not affect anything. + +The main change comes from how model part visibility work, such as armors and capes. Every single individual part (e.g. helmet, chestplate) now has their own separate model, meaning that the general part visibility system has been completely removed. You can still provide visibility through the mutable model part in `setupAnim`, but the general movement is to simply have parts that should be separate models as separate models. + +To facilitate this, `PartDefinition`s now has methods to selectively keep certain parts of models and remove the others. This is done through the `clear*` and `retain*` methods. Basically, all of these methods are doing are keeping the part pose while removing any cubes associated with the children queries. `retain*` allows for certain parts and potentially subparts to keep their cubes. This addition provides a twofold benefit: model layers can deterministically use `setupAnim` to setup the parts similarly to the base model, and the model texture will only need to contain the retained elements. + +Here is an example for creating the armor models for a creeper: + +```java +// Deformations for humanoid armor +private static final CubeDeformation OUTER_ARMOR_DEFORMATION = new CubeDeformation(1.0F); +private static final CubeDeformation INNER_ARMOR_DEFORMATION = new CubeDeformation(0.5F); + +// Creeper has the following parts: +// - head +// - body +// - right_hind_leg, left_hind_leg +// - right_front_leg, left_front_leg + +// We use separate meshes as we are basically isolating the parts we want to keep in each + +public static ArmorModelSet createCreeperArmor() { + // Helmet + + // Create mesh + MeshDefinition helmetMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + // Note that body and the legs still exist, they simply have no cubes + helmetMesh.getRoot().retainExactParts(Set.of("head")); + + // Chestplate + + // Create mesh + var chestplateMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + chestplateMesh.getRoot().retainExactParts(Set.of("body")); + + // Leggings + + // Create mesh + var leggingsMesh = CreeperModel.createBodyLayer(INNER_ARMOR_DEFORMATION); + // Only retain the desired parts + leggingsMesh.getRoot().retainExactParts(Set.of("right_hind_leg", "left_hind_leg", "right_front_leg", "left_front_leg")); + + // Boots + + // Create mesh + var bootsMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + bootsMesh.getRoot().retainExactParts(Set.of("right_hind_leg", "left_hind_leg", "right_front_leg", "left_front_leg")); + + // Store this all in an ArmorModelSet, which is basically just object holder and mapper + return new ArmorModelSet<>( + helmetMesh, + chestplateMesh, + leggingsMesh, + bootsMesh + ); +} + +// To register the layer definitions, basically the same process of using the ArmorModelSet +public static final ArmorModelSet CREEPER_ARMOR = new ArmorModelSet<>( + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "helmet"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "chestplate"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "leggings"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "boots") +); + +// In some method where you have access to the Map builder +ArmorModelSet creeperArmorLayers = createCreeperArmor().map(mesh -> LayerDefinition.create(mesh, 64, 32)); +CREEPER_ARMOR.putFrom(creeperArmorLayers, builder); +``` + +### Entity Renderer + +With the change to submission, the `EntityRenderer` and its associated `RenderLayer`s have also changed. Basically, you can assume almost every method that has the word `render` has been changed to `submit`, and `MultiBufferSource` and light coordinates integer have generally been replaced by `SubmitNodeCollector` and the associated entity render state. + +The new `submit` method that replaces `render` in `EntityRenderer` now takes in the render state of the entity, the `PoseStack`, the `SubmitNodeCollector`, and the `CameraRenderState`. When submitting any element, the location in 3D space is taken by getting the last pose on the `PoseStack` and storing that for future use. + +```java +// A basic entity renderer + +// We will assume all the classes listed exist +public class ExampleEntityRenderer extends MobRenderer { + + public ExampleEntityRenderer(EntityRendererProvider.Context ctx) { + super(ctx, ctx.bakeLayer(EXAMPLE_MODEL_LAYER), 0.5f); + } + + @Override + public void submit(ExampleEntityRenderState renderState, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState cameraState) { + super.submit(renderState, poseStack, collector, cameraState); + + // An example of submitting something + collector.submitCustomGeometry( + poseStack, // The current pose + RenderType.solid(), // The render type to use + ExampleEntityRenderer::addVertices // The method to write the geometry data + ); + } + + private static void addVertices(PoseStack.Pose pose, VertexConsumer consumer) { + // Add custom geometry + } +} + +// A render layer + +public class CreeperArmorLayer extends RenderLayer { + + private final ArmorModelSet modelSet; + private final EquipmentLayerRenderer equipment; + + public CreeperArmorLayer(RenderLayerParent parent, ArmorModelSet modelSet, EquipmentLayerRenderer equipment) { + super(parent); + this.modelSet = modelSet; + this.equipment = equipment; + } + + // We will assume we added headEquipment, chestEquipment, legsEquipment, feetEquipment to the CreeperRenderState somehow + @Override + public void submit(PoseStack poseStack, SubmitNodeCollector collector, int lightCoords, CreeperRenderState renderState, float yRot, float xRot) { + this.renderArmorPiece(poseStack, collector, renderState.chestEquipment, EquipmentSlot.CHEST, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.legsEquipment, EquipmentSlot.LEGS, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.feetEquipment, EquipmentSlot.FEET, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.headEquipment, EquipmentSlot.HEAD, lightCoords, renderState); + } + + // Taken from humanoid armor layer + private void renderArmorPiece(PoseStack poseStack, SubmitNodeCollector collector, ItemStack stack, EquipmentSlot slot, int lightCoords, CreeperRenderState renderState) { + Equippable equippable = stack.get(DataComponents.EQUIPPABLE); + if (equippable != null && equippable.assetId().isPresent() && equippable.slot() == slot) { + CreeperModel model = this.modelSet.get(slot); + EquipmentClientInfo.LayerType layer = slot == EquipmentSlot.LEGS + ? EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS + : EquipmentClientInfo.LayerType.HUMANOID; + this.equipmentRenderer.renderLayers( + layer, // The equipment layer to use + equippable.assetId().orElseThrow(), // The equipment asset to pull + model, // The armor model + renderState, // The entity render state + stack, // The armor stack + poseStack, // The pose stack + collector, // The collector to add the model data to + lightCoords, // The light coordinates + renderState.outlineColor // The outline color of the entity + ); + } + } +} + +// Then, to add it to the creeper renderer constructor +public CreeperRenderer(EntityRendererProvider.Context ctx) { + // ... + this.addLayer(new CreeperArmorLayer( + this, // The parent is the renderer itself + ArmorModelSet.bake( // Baking the model set + CREEPER_ARMOR, // The model layer locations + ctx.getModelSet(), // The model set to map the models from the layer locations + CreeperModel::new // The mapper for the root part to the model + ), + ctx.getEquipmentRenderer() // The renderer for the equipment + )); +} +``` + +### Block Entity Renderer + +`BlockEntityRenderer`s also use the new submission method, replacing almost every `render*` with `submit`. They have taken a play from entities, now having their own `BlockEntityRenderState` which is extracted from the `BlockEntity`. As such, `BlockEntityRenderer` now has a new generic `S` for the `BlockEntityRenderState`. + +The `BlockEntityRenderState`, by default, contains information about its position, block state, type, light coordinates, and the current break progress as a `ModelFeatureRenderer$CrumblingOverlay`. These are all populated through `BlockEntityRenderState#extractBase`, which is called in `BlockEntityRenderer#extractRenderState`. Like entities, the render state is first constructed via `BlockEntityRenderer#createRenderState` before the values are extracted from the block entity. `extractRenderState` does contain the partial tick and camera position, but this is not passed to the `BlockEntityRenderState` by default. + +As such, the `submit` method that takes over the `render` method takes in the render state, a `PoseStack` for the location in 3D space, the `SubmitNodeCollector` for pushing the elements to render, and the `CameraRenderState`. + +```java +// We will assume all the classes not specified here exist + +// A simple render state +public class ExampleRenderState extends BlockEntityRenderState { + public float partialTick; +} + +// A basic block entity renderer +public class ExampleBlockEntityRenderer implements BlockEntityRenderer { + + public ExampleBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) { + // Get anything you need from the context + } + + @Override + public ExampleRenderState createRenderState() { + // Create the render state used to submit the block entity to the feature renderer + return new ExampleRenderState(); + } + + @Override + public void extractRenderState(ExampleBlockEntity blockEntity, ExampleRenderState renderState, float partialTick, Vec3 cameraPos, @Nullable ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) { + // Extract the necessary rendering values from the block entity to the render state + // Always call super or BlockEntityRenderState#extractBase + super.extractRenderState(blockEntity, renderState, partialTick, cameraPos, crumblingOverlay); + + // Populate any desired values + renderState.partialTick = partialTick; + } + + + @Override + public void submit(ExampleRenderState renderState, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState cameraState) { + // An example of submitting something + collector.submitModel(..., renderState.breakProgress); + } +} +``` + +### Special Item Models + +Since special item models also make use of custom rendering, they have been updated to with the `submit` change, only replacing `MultiBufferSource` with the `SubmitNodeCollector`. + +```java +// A basic special item model + +// We will assume all the classes listed exist +public class ExampleSpecialModelRenderer implements NoDataSpecialModelRenderer { + + public ExampleSpecialModelRenderer() {} + + @Override + public void submit(ItemDisplayContext displayContext, PoseStack poseStack, SubmitNodeCollector collector, int lightCoords, int overlayCoords, boolean hasFoil, int outlineColor) { + // An example of submitting something + collector.submitModelPart(...); + } + + @Override + public void getExtents(Set extents) {} +} +``` + +### Particles + +Particles have been added to the submission process; however, there are multiple paths depending on how complicated your particle is. A few classes and general names have been reused for an additional purpose as well, sometimes making it difficult to understand how each part works. As such, this document will go over two methods of creating a particle: one more familiar with the old system, and one that explains the underlying nuances from the ground up. + +#### The Separation of Engines and Resources + +Before we discuss the two methods, first, let's go with the overarching changes. `ParticleEngine` has been functionally split up into two classes: `ParticleEngine`, which handle the actual ticking and extraction, not submission, of the render state; and `ParticleResources`, which is the reload listener that registers the `ParticleProvider` and optionally `ParticleResources$SpriteParticleRegistration` and reloads the `SpriteSet` from its `ParticleDescription`. This underlying behavior hasn't change (besides the whole extract and submission process), the methods have simply been moved. + +`ParticleProvider#createParticle` also now provides a `RandomSource`, which can be used as needed. + +As for the actual submission and rendering process, this is handled outside of `ParticleEngine`. More specifically, the `LevelRenderer` extracts all the particles to submit in `ParticlesRenderState` via `ParticleEngine#extract`. Then, in `LevelRenderer#addParticlesPass`, the resource handles are set to the particle `FramePass`, to which on execution the particles are submitted via `ParticlesRenderState#submit` and then rendered through the feature dispatcher via `ParticleFeatureRenderer`. + +#### A Single Quad + +Many particles in the old system were simply made up of a single quad with a texture(s) slapped on it. These particles are `SingleQuadParticle`s, which merges both the previous `SingleQuadParticle` and `TextureSheetParticle` into one. The `SingleQuadParticle` now takes in an initial `TextureAtlasSprite` to set the first texture, which can then be updated by overriding `Particle#tick` and calling `SingleQuadParticle#setSpriteFromAge` for a `SpriteSet` or directly with `setSprite`. The tint can also be modified in the tick using `setColor` and `setAlpha`. Some also set these directly in `SingleQuadParticle#extract`, but which to use depends on if you need to override the entire tick or not. + +To determine the `RenderType` that is used to render the quad, `SingleQuadParticle#getLayer` must be set to the desired `$Layer`. A `$Layer` is basically a record defining whether the quad can have translucency, what texture atlas it pulls from, and the render pipeline to use. Vanilla provides `TERRAIN`, `OPAQUE`, and `TRANSLUCENT` similar to the old `Particle#getRenderType` which it replaces. `TERRAIN` and `TRANSLUCENT` both allow transparency, and `OPAQUE` and `TRANSLUCENT` pull from the particle atlas while `TERRAIN` uses the block atlas. A custom `$Layer` can be created using the constructor. + +```java +public static final SingleQuadParticle.Layer EXAMPLE_LAYER = new SingleQuadParticle.Layer(true, TextureAtlas.LOCATION_PARTICLES, RenderPipelines.WEATHER_DEPTH_WRITE); +``` + +In addition to all this, you can also set how the particle is rotated by overriding `SingleQuadParticle#getFacingCameraMode`. `$FacingCameraMode` is a functional interface that sets the rotation of the particle whenever it is extracted. By default, this means that the texture will always face the camera. Any other method changes and additions are in the list below. + +From there, everything else is the same to create the `ParticleProvider` and register it. + +```java +// We will assume we have some SimpleParticleType EXAMPLE_QUAD for our particle +// Additionally, we will assume there is some particle description with our textures to use +public class ExampleQuadParticle extends SingleQuadParticle { + + private final SpriteSet spriteSet; + + // This can be package-private, protected, or public + // public should be used if the particle will be constructed outside of the provider + ExampleQuadParticle(ClientLevel level, double x, double y, double z, SpriteSet spriteSet) { + // We use first to set the initial particle texture + super(level, x, y, z, spriteSet.first()); + } + + @Override + public void tick() { + super.tick(); + // Update the particle image + this.setSpriteFromAge(spriteSet); + } + + @Override + public SingleQuadParticle.Layer getLayer() { + return EXAMPLE_LAYER; + } + + // Create the provider + public static class Provider implements ParticleProvider { + + private final SpriteSet spriteSet; + + public Provider(SpriteSet spriteSet) { + this.spriteSet = spriteSet; + } + + @Override + public Particle createParticle(SimpleParticleType options, ClientLevel level, double x, double y, double z, double xd, double yd, double zd, RandomSource random) { + // Create the particle + return new ExampleQuadParticle(level, x, y, z, this.spriteSet); + } + } +} + +// Register the provider to `ParticleResources#register` +// Assume access to ParticleResources resources and register has been made public +resources.register(EXAMPLE_QUAD, ExampleQuadParticle.Provider::new); +``` + +#### From the Ground Up + +What about rendering some more complex or custom? Well, in those instances, we need to take a deeper dive into how particles are extracted by the `ParticleEngine`. The `Particle` class, by itself actually does no extraction, submission, or rendering itself. It simply handles the physics update every tick. The actual extraction logic is handled through a `ParticleGroup`, while the submission is handled by a `ParticleGroupRenderState`. + +So, what is a `ParticleGroup`? Well, as the name implies, a particle group holds a group of particles and is responsible for keeping track of, ticking, and extracting the render state of its particles. The generic represents the type of `Particle` it can keep track of up to the maximum of 16,384 per group (though individual particles can set their own subgroup limit via `Particle#getParticleLimit`). All `SingleQuadParticle`s are part of the `QuadParticleGroup`. To extract the render state, the `ParticleEngine` calls `ParticleGroup#extractRenderState`, which takes in the current frustum, camera, and partial tick to return a `ParticleGroupRenderState`. + +`ParticleGroupRenderState` is sort of a mix between a render state, submission handler, and cache. It contains two methods: `submit`, which takes in the `SubmitNodeCollector` and submits the group; and `clear`, which clears all previous cached particle states. Technically, anything can be submitted using the collector, but particles have `SubmitNodeCollector$ParticleGroupRenderer`: an additional utility to help with caching and rendering. The group renderer contains two methods: `prepare`, to write the mesh data to a ring buffer; and `render`, which typically uses the cached buffer to write the data to the shared sequential buffer using the provided `RenderPass` and draw it to the screen. Only `QuadParticleRenderState` makes use of the cache and `ParticleGroupRenderer` as the render states are currently cleared immediately after rendering. + +To link the `ParticleGroup` to a `Particle` for use, we must set the `ParticleRenderType` using `Particle#getGroup`. `ParticleRenderType`, unlike the previous version, is simply a key for a `ParticleGroup`. This key is mapped to the group via `ParticleEngine#createParticleGroup`, and the submission/render order is determined by `ParticleEngine#RENDER_ORDER`. Both the method and the list must be patched for the particle to be properly managed by your group and extracted for submission. + +```java +// We will assume we have some SimpleParticleType EXAMPLE_ONE, EXAMPLE_TWO for our particles +// This example with construct two particles with the same base type to show how the group works + +// Create the particle type +public static final ParticleRenderType EXAMPLE_TYPE = new ParticleRenderType("examplemod:example_type"); + +// Create our particles +public abstract class ExampleParticle extends Particle { + + // You can handle passing to the particle group however you want + // Making the fields accessible or having a dedicated method + public final Model model; + + protected ExampleParticle(ClientLevel level, double x, double y, double z, Function> modelFactory) { + super(level, x, y, z); + this.model = modelFactory.apply(Minecraft.getInstance().getEntityModels()); + } + + @Override + public ParticleRenderType getGroup() { + // Set the particle type to our group + return EXAMPLE_TYPE; + } + + @FunctionalInterface + public interface ExampleParticleFactory

{ + + P create(ClientLevel level, double x, double y, double z); + } + + protected static

ParticleProvider createProvider(ExampleParticleFactory

factory) { + return (options, level, x, y, z, xd, yd, zd, random) -> factory.create(level, x, y, z); + } +} + +public class ExampleOneParticle extends ExampleParticle { + + ExampleOneParticle(ClientLevel level, double x, double y, double z) { + super(level, x, y, z, modelSet -> new Model.Simple(new ModelPart(Collections.emptyList(), Collections.emptyMap()), RenderType::entityCutoutNoCull)); + } + + public static ParticleProvider provider() { + return ExampleParticle.createProvider(ExampleOneParticle::new); + } +} + +public class ExampleTwoParticle extends ExampleParticle { + + private static final ParticleLimit LIMIT = new ParticleLimit(5); + + ExampleTwoParticle(ClientLevel level, double x, double y, double z) { + super(level, x, y, z, modelSet -> new Model.Simple(new ModelPart(Collections.emptyList(), Collections.emptyMap()), RenderType::entityCutoutNoCull)); + } + + @Override + public Optional getParticleLimit() { + // Limits the number of particles using the LIMIT subgroup to 5 + // Note that since ParticleLimit is a record, any with the same limit will be considered as the same key + return Optional.of(LIMIT); + } + + public static ParticleProvider provider() { + return ExampleParticle.createProvider(ExampleTwoParticle::new); + } +} + +// Register the providers to `ParticleResources#register` +// Assume access to ParticleResources resources and register has been made public +resources.register(EXAMPLE_ONE, ExampleOneParticle.provider()); +resources.register(EXAMPLE_TWO, ExampleTwoParticle.provider()); + +// Create the render state to submit all particles in the group +// Store whatever you need to submit to the node collector +public record ExampleGroupRenderState(List> models) implements ParticleGroupRenderState { + + @Override + public void submit(SubmitNodeCollector collector) { + // Submit every particle + for (var model : this.models) { + collector.submitModel(model, ...); + } + } +} + +// Create the particle group to keep track of the particles and create the render state +// Both EXAMPLE_ONE and EXAMPLE_TWO will be added to this group +public class ExampleParticleGroup extends ParticleGroup { + + public ExampleParticleGroup(ParticleEngine engine) { + super(engine); + } + + @Override + public ParticleGroupRenderState extractRenderState(Frustum frustum, Camera camera, float partialTick) { + // Create the particle group to submit the particles + return new ExampleGroupRenderState( + this.particles.stream().map(particle -> particle.model).toList() + ); + } +} + +// Link the ParticleRenderType to its ParticleGroup +// Assume we have access to ParticleEngine engine +// Assume that ParticleEngine#RENDER_ORDER is made mutable and public +// Assume we can patch ParticleEngine#createParticleGroup +engine.RENDER_ORDER.add(EXAMPLE_TYPE); + +// In ParticleEngine +private ParticleGroup createParticleGroup(ParticleRenderType renderType) { + if (renderType == EXAMPLE_TYPE) { + // this is referring to the ParticleEngine + return new ExampleParticleGroup(this); + } + // ... +} +``` + +### Atlas Handler Consolidation + +The atlas handler has had some of its logic modified to consolidate other sprites and change how to obtain a `TextureAtlasSprite`. + +First, map decorations, paintings, and GUI sprites are now proper atlases with their own sheets: `Sheets#MAP_DECORATIONS_SHEET`, `PAINTINGS_SHEET`, and `GUI_SHEET` respectively. + +Obtaining the `TextureAtlasSprite` from said sheets are now completely routed through the `MaterialSet`: a functional interface that takes in a `Material` (basically a sheet location and texture location), and returns the associated `TextureAtlasSprite`. The `MaterialSet` handles texture grabs for item models, block entity renderers, and entity renderers: + +```java +// Here is an example material to grab the apple texture from the appropriate sheet +public static final Material APPLE = new Material( + TextureAtlas.LOCATION_BLOCKS, // The sheet where the item textures are stored + ResourceLocation.fromNamespaceAndPath("minecraft", "item/apple") // The texture name according to the sprite contents +); +// You can also do the same using Sheets.ITEMS_MAPPER.defaultNamespaceApply("apple") + +// For some item model +public class ExampleUnbakedItemModel implements ItemModel.Unbaked { + + // ... + + @Override + public ItemModel bake(ItemModel.BakingContext ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } +} + +// For some special item model +public class ExampleUnbakedSpecialModel implements SpecialModelRenderer.Unbaked { + + // ... + + @Override + @Nullable + public SpecialModelRenderer bake(SpecialModelRenderer.BakingContext ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } +} + +// For some block entity renderer +public class ExampleBlockEntityRenderer implements BlockEntityRenderer { + + public ExampleBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } + + // ... +} + + +// For some entity renderer +public class ExampleEntityRenderer implements EntityRenderer { + + public ExampleEntityRenderer(EntityRendererProvider.Context ctx) { + TextureAtlasSprite appleTexture = ctx.getMaterials().get(APPLE); + // ... + } + + // ... +} +``` + +- `assets/minecraft/shaders/core` + - `blit_screen.json` -> `screenquad.json`, using no-format triangles instead of positioned quads + - `position_color_lightmap.*` are removed + - `position_color_tex_lightmap.*` are removed +- `com.mojang.blaze3d.vertex` + - `CompactVectorArray` - An holder that smashes a list of float vectors into a single sequential array. + - `MeshData$SortState#centroids` now returns a `CompactVectorArray` + - `VertexSorting` + - `byDistance` now takes in a `Vector3fc` instead of a `Vector3f` + - `sort` now takes in a `CompactVectorArray` instead of a `Vector3f[]` +- `net.minecraft.client.Minecraft` + - `getTextureAtlas` -> `AtlasManager#getAtlasOrThrow`, not one-to-one + - `getPaintingTextures`, `getMapDecorationTextures`, `getGuiSprites` -> `getAtlasManager`, not one-to-one +- `net.minecraft.client.animation.Keyframe` now has an overload that takes in the `preTarget` and `postTarget` instead of one simple `target`, taking in a `Vector3fc` instead of a `Vector3f` +- `net.minecraft.client.entity` + - `ClientAvatarEntity` - The client data of the avatar. + - `ClientAvatarState` - The movement state of the avatar. + - `ClientMannequin` - The client version of the `Mannequin` entity. +- `net.minecraft.client.gui` + - `GuiGraphics` + - `renderOutline` -> `submitOutline` + - `renderDeferredTooltip` -> `renderDeferredElements`, not one-to-one + - `submitBannerPatternRenderState` now takes in a `BannerFlagModel` instead of a `ModelPart` + `GuiSpriteManager` class is removed +- `net.minecraft.client.gui.render.GuiRenderer` now takes in the `SubmitNodeCollector` and `FeatureRenderDispatcher` + - `MIN_GUI_Z` is now public +- `net.minecraft.client.gui.render.pip` + - `GuiBannerResultRenderer` now takes in a `MaterialSet` + - `GuiSignRenderer` now takes in a `MaterialSet` +- `net.minecraft.client.gui.render.state.TiledBlitRenderState` - A render state for building a sprite using tiling, usually for tile or nine slice textures. +- `net.minecraft.client.gui.render.state.pip.GuiBannerResultRenderState` now takes in a `BannerFlagModel` instead of a `ModelPart` +- `net.minecraft.client.model` + - `AbstractPiglinModel#createArmorMeshSet` - Creates the model meshes for each of the humanoid armor slots. + - `ArmedModel` now has a generic of the `EntityRenderState` + - `translateToHand` now takes in the entity render state + - `ArmorStandArmorModel#createBodyLayer` -> `createArmorLayerSet`, not one-to-one + - `BellModel$State` - Represents the state of the backing object. + - `BookModel$State` - Represents the state of the backing object. + - `BreezeModel` + - `createBodyLayer` -> `createBaseMesh`, now private + - Replaced by `createBodyLayer`, `createWindLayer`, `createEyesLayer` + - `CopperGolemModel` - A model for the copper golem entity. + - `CopperGolemStatueModel` - A model for the coper golem statue. + - `CreakingModel` + - `NO_PARTS`, `getHeadModelParts` are removed + - `createEyesLayer` - Creates the eyes of the model. + - `EntityModel#setupAnim` -> `Model#setupAnim` + - `GuardianParticleModel` - The particle spawned from a guardian. + - `HeadedModel#translateToHead` - Transforms the pose stack to the head's position and rotation. + - `HumanoidArmorModel` -> `HumanoidModel#createArmorMeshSet`, not one-to-one + - `HumanoidModel#copyPropertiesTo` is removed + - `Model` now takes in a generic representing the render state + - `PlayerCapeModel` now extends `PlayerModel` + - `PlayerEarsModel` now extends `PlayerModel` + - `PlayerModel` render state has been broadened to `AvatarRenderState` + - Static fields are now `protected` + - `createArmorMeshSet` - Creates the model meshes for each of the humanoid armor slots. + - `SkullModelBase$State` - Represents the state of the backing object. + - `SpinAttackEffectModel` generic has been broadened to `AvatarRenderState` + - `VillagerLikeModel` now takes in a generic for the render state + - `hatVisible` is removed + - Replaced by `VillagerModel#createNoHatModel` + - `translateToArms` now takes in the render state + - `WardenModel` + - `createTendrilsLayer`, `createHeartLayer`, `createBioluminescentLayer`, `createPulsatingSpotsLayer` - Creates the layers used by the warden's `RenderLayer`s. + - `getTendrilsLayerModelParts`, `getHeartLayerModelParts`, `getBioluminescentLayerModelParts`, `getPulsatingSpotsLayerModelParts` are removed + - `ZombieVillagerModel` + - `createArmorLayer` -> `createArmorLayerSet`, not one-to-one + - `createNoHatLayer` - Creates the model without the hat layer. +- `net.minecraft.client.model.geom.ModelPart` + - `copyFrom` is removed + - `$Polygon#normal` is now a `Vector3fc` instead of a `Vector3f` + - `$Vertex` + - `pos` -> `x`, `y`, `z` + - `worldX`, `worldY`, `worldZ` - Returns the coordinates scaled down by a factor of 16. +- `net.minecraft.client.model.geom.builders.PartDefinition` + - `clearRecursively` - Clears all children parts and its sub-children. + - `retainPartsAndChildren` - Retains the specified parts from its root and any sub-children. + - `retainExactParts` - Retains only the top level part, clearing out all others and sub-children. +- `net.minecraft.client.particle` + - `AttackSweepParticle` now extends `SingleQuadParticle` + - `BaseAshSmokeParticle` now extends `SingleQuadParticle` and is `abstract` + - `BlockMarker` now extends `SingleQuadParticle` + - `BreakingItemParticle` now extends `SingleQuadParticle` + - The constructor takes in a `TextureAtlasSprite` instead of the `ItemStackRenderState` + - `$ItemParticleProvider#calculateState` -> `getSprite`, not one-to-one + - `BubbleColumnUpParticle` now extends `SingleQuadParticle` + - `BubbleParticle` now extends `SingleQuadParticle` + - `BubblePopParticle` now extends `SingleQuadParticle` + - `CampfireSmokeParticle` now extends `SingleQuadParticle` + - `CritParticle` now extends `SingleQuadParticle` + - `DragonBreathParticle` now extends `SingleQuadParticle` + - `$Provider` generic now uses a `PowerParticleOption` + - `DripParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `create*Particle` methods -> `$*Provider` classes + - `DustParticleBase` now extends `SingleQuadParticle` + - `ElderGuardianParticleGroup` - The particle group responsible for setting up and submitting the elder guardian particle. + - `ExplodeParticle` now extends `SingleQuadParticle` + - `FallingDustParticle` now extends `SingleQuadParticle` + - `FallingLeavesParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` instead of a `SpriteSet` + - `FireflyParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FireworkParticles` + - `$FlashProvider` generic now uses `ColorParticleOption` + - `$OverlayParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FlameParticle` now takes in a `TextureAtlasSprite` + - `FlyStraightTowardsParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FlyTowardsPositionParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `GlowParticle` now extends `SingleQuadParticle` + - `GustParticle` now extends `SingleQuadParticle` + - `HeartParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `HugeExplosionParticle` now extends `SingleQuadParticle` + - `ItemPickupParticle` now takes in the `EntityRenderState` instead of the `EntityRenderDispatcher` + - Fields are now all `protected` aside from the target entity + - `ItemPickupParticleGroup` - The particle group responsible for setting up and submitting the item pickup particle. + - `LavaParticle` now extends `SingleQuadParticle` + - `MobAppearanceParticle` -> `ElderGuardianParticle` + - `NoRenderParticleGroup` - The particle group that does nothing. + - `NoteParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `Particle` + - `rCol`, `gCol`, `bCol`, `alpha` -> `SingleQuadParticle#rCol`, `gCol`, `bCol`, `alpha` + - `roll`, `oRoll` -> `SingleQuadParticle#roll`, `oRoll` + - `setColor`, `setAlpha` -> `SingleQuadParticle#setColor`, `setAlpha` + - `render`, `renderCustom` -> `ParticleGroupRenderState#submit`, not one-to-one + - `getRenderType` -> `getGroup` + - The original purpose of this method has been moved to `SingleQuadParticle#getLayer` + - `getParticleGroup` -> `getParticleLimit`, not one-to-one + - `ParticleEngine` no longer implements `PreparableReloadListener` + - The constructor now takes in the `ParticleResources` instead of the `TextureManager` + - `close` is removed + - `updateCount` is now `protected` + - `render` -> `extract`, not one-to-one + - `destroy` -> `ClientLevel#addDestroyBlockEffect` + - `crack` -> `ClientLevel#addBreakingBlockEffect` + - `clearParticles` is now `public` + - `$MutableSpriteSet` -> `ParticleResources$MutableSpriteSet` + - `$SpriteParticleRegistration` -> `ParticleResources$SpriteParticleRegistration` + - `ParticleGroup` - A holder of particles for a specific `ParticleRenderType`, responsible for ticking and extracting the general render state. + - `ParticleProvider` + - `createParticle` now takes in the `RandomSource` + - `$Sprite#createParticle` now takes in the `RandomSource` and returns a `SingleQuadParticle` instead of a `TextureSheetParticle` + - `ParticleRenderType` no longer takes in the `RenderType` + - This record has been repurposed to represent a key for the particle groups + - `TERRAIN_SHEET` -> `SingleQuadParticle$Layer#TERRAIN` + - `PARTICLE_SHEET_OPAQUE` -> `SingleQuadParticle$Layer#OPAQUE` + - `PARTICLE_SHEET_TRANSLUCENT` -> `SingleQuadParticle$Layer#TRANSLUCENT` + - `CUSTOM` is replaced by a particle group that is not for `ParticleRenderType#SINGLE_QUADS` + - `ParticleResources` - Loads the particle providers, any necessary descriptions, and computes them into their desired sprite set. + - `PlayerCloudParticle` now extends `SingleQuadParticle` + - `PortalParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `QuadParticleGroup` - The particle group responsible for setting up and submitting single quad particles. + - `ReversePortalParticle` now takes in a `TextureAtlasSprite` + - `RisingParticle` now extends `SingleQuadParticle` + - `SculkChargeParticle` now extends `SingleQuadParticle` + - `SculkChargePopParticle` now extends `SingleQuadParticle` + - `SculkChargePopParticle` now extends `SingleQuadParticle` + - `ShriekParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `SimpleAnimatedParticle` now extends `SingleQuadParticle` and is `abstract` + - `SingleQuadParticle` now takes in a `TextureAtlasSprite` + - `sprite` - The texture of the particle. + - `render` -> `extract`, not one-to-one, now taking in the `QuadParticleRenderState` instead of a `VertexConsumer` + - `renderRotatedQuad` -> `extractRotatedQuad`, not one-to-one, now taking in the `QuadParticleRenderState` instead of a `VertexConsumer` + - `getU0`, `getU1`, `getV0`, `getV1` are no longer abstract + - `getLayer` - Sets the render layer of the single quad. + - `$Layer` - The layer the single quad should render in. + - `SnowflakeParticle` now extends `SingleQuadParticle` + - `SpellParticle` now extends `SingleQuadParticle` + - `InstantProvider` generic now uses `SpellParticleOption` + - `SplashParticle` now takes in a `TextureAtlasSprite` + - `SpriteSet#first` - Returns the first texture in the sprite set. + - `SuspendedParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `SuspendedTownParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `TerrainParticle` now extends `SingleQuadParticle` + - `TextureSheetParticle` class is removed, use `SingleQuadParticle` instead + - `TrailParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `TrialSpawnerDetectionParticle` now extends `SingleQuadParticle` + - `VibrationSignalParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `WakeParticle` now extends `SingleQuadParticle` + - `WaterCurrentDownParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `WaterDropParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` +- `net.minecraft.client.player.AbstractClientPlayer` fields are now stored within `ClientAvatarState` + - `elytraRot*` -> `*Cloak` + - `clientLevel` is removed + - `getDeltaMovementLerped` -> `addWalkedDistance`, not one-to-one + - `updateBob` - Updates the bobbing motion of the camera. +- `net.minecraft.client.renderer` + - `EndFlashState` - The render state of the end flashes. + - `GameRenderer` now takes in the `BlockRenderDispatcher` + - `getSubmitNodeStorage` - Gets the node submission for feature-like objects. + - `getFeatureRenderDispatcher` - Gets the dispatcher for rendering feature-like objects. + - `getLevelRenderState` - Gets the render state of dynamic features in a level. + - `ItemInHandRenderer` + - `renderItem` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `renderHandsWithItems` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource$BufferSource` + - `LevelRenderer` now takes in the `LevelRenderState` and `FeatureRenderDispatcher` + - `getSectionRenderDispatcher` is now nullable + - `tickParticles` is removed + - `addParticle` is removed + - `MapRenderer` now takes in an `AtlasManager` instead of a `MapDecorationTextureManager` + - `render` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `OrderedSubmitNodeCollector` - A submission handler for holding elements to be drawn in a given order to the screen whenever the features are dispatched. + - `OutlineBufferSource` no longer takes in any parameters + - `setColor` now takes in a single integer + - `ParticleGroupRenderState` - The render state for a group of particles. + - `ParticlesRenderState` - The render state for all particles. + - `QuadParticleRenderState` - The render group state for all single quad particles. + - `RenderPipelines` + - `GUI_TEXT` - The pipeline for text in a gui. + - `GUI_TEXT_INTENSITY` - The pipeline for text intensity when not colored in a gui. + - `RenderStateShard#TRANSLUCENT_TARGET`, `PARTICLES_TARGET` are removed + - `RenderType` + - `pipeline` - The `RenderPipeline` the type uses. + - `opaqueParticle`, `translucentParticle` are removed + - `sunriseSunset`, `celestial` are removed + - `ScreenEffectRenderer` now takes in a `MaterialSet` + - `renderScreenEffect` now takes in a `SubmitNodeCollector` + - `ShapeRenderer` + - `renderLineBox` now takes in a `PoseStack$Pose` instead of a `PoseStack` + - `renderFace` now takes in a `Matrix4f` instead of a `PoseStack` + - `Sheets` + - `GUI_SHEET`, `MAP_DECORATIONS_SHEET`, `PAINTINGS_SHEET` - Atlas textures. + - `BLOCK_ENTITIES_MAPPER` - A mapper for block textures onto block entities. + - `*COPPER*` - Materials for copper chests. + - `chooseMaterial` now takes in a `ChestRenderState$ChestMaterialType` instead of a `BlockEntity` and `boolean` + - `SkyRenderer` + - `END_SKY_LOCATION` is now private + - `renderSunMoonAndStars` no longer takes in the buffer source + - `renderEndFlash` no longer takes in the buffer source + - `renderSunriseAndSunset` no longer takes in the buffer source + - `SpecialBlockModelRenderer` + - `vanilla` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `renderByBlock` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource`, and an outline color + - `SubmitNodeCollection` - An implementation of `OrderedSubmitNodeCollector` that holds the submitted features in separate lists. + - `SubmitNodeCollector` - An `OrderedSubmitNodeCollector` that provides a method to change the current order that an element will be rendered in. + - `SubmitNodeStorage` - A storage of collections held by some order. + - `SkyRenderer` + - `renderEndFlash` - Renders the end flashes. + - `initTextures` - Gets the texture for the used elements. + - `extractRenderState` - Extracts the `SkyRenderState` from the current level. + - `WeatherEffectRenderer` + - `render` now takes in the `WeatherRenderState` instead of an `int`, `float`, and `Level` + - Those fields have moved to `extractRenderState` + - `extractRenderState` - Extracts the `WeatherRenderState` from the current level. + - `$ColumnInstance` is now public + - `WorldBorderRenderer` + - `render` now takes in the `WorldBorderRenderState` instead of the `WorldBorder` + - `extract` - Extracts the `WorldBorderRenderState` from the current world border. +- `net.minecraft.client.renderer.block` + - `BlockRenderDispatcher` now takes in a `MaterialSet` + - `MovingBlockRenderState` - A render state for a moving block that implements `BlockAndTintGetter`. + - `LiquidBlockRenderer#setupSprites` now take in the `BlockModelShaper` and `MaterialSet` +- `net.minecraft.client.renderer.blockentity` + - Most methods here that take in the `MultiBufferSource` have been replaced by a `SubmitNodeCollector`, and a `ModelFeatureRenderer$CrumblingOverlay` if the method is not used for item rendering + - Most methods change their name from `render*` to `submit*`, with the main submit method now using a `BlockEntityRenderState` + - All `BlockEntityRenderer`s now have a `BlockEntityRenderState` generic + - `AbstractEndPortalRenderer` - A block entity renderer for the end portal. + - `AbstractSignRenderer` + - `getSignModel` now returns a `Model$Simple` + - `renderSign` -> `submitSign`, now takes in a `Model$Simple` and no longer takes in a tint color + - `BannerRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `renderPatterns` -> `submitPatterns` now takes in the `MaterialSet` and `ModelFeatureRenderer$CrumblingOverlay`, the `ModelPart` has been replaced with the `Model` and its render state, a `boolean` for whether to use the entity glint, and an outline color + - The overload with two additional `boolean`s has been removed + - `renderSpecial` -> `submitSpecial`, now takes in the outline color + - `BeaconRenderer#renderBeaconBeam` -> `submitBeaconBeam`, no longer takes in the game time `long` + - `BedRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `renderSpecial` -> `submitSpecial`, now takes in the outline color + - `BlockEntityRenderDispatcher` now takes in the `MaterialSet` and `PlayerSkinRenderCache` + - `render` -> `submit`, now takes in the `BlockEntityRenderState` instead of a `BlockEntity`, no longer takes in the partial tick `float`, and takes in the `CameraRenderState` + - `getRenderer` now has an overload that can get the renderer from its `BlockEntityRenderState` + - `tryExtractRenderState` - Gets the `BlockEntityRenderState` from its `BlockEntity` + - `level`, `camera`, `cameraHitResult` is removed + - `prepare` now only takes in the `Camera` + - `setLevel` is removed + - `BlockEntityRenderer` now has another generic `S` representing the `BlockEntityRenderState` + - `render` -> `submit`, taking in the `BlockEntityRenderState`, the `PoseStack`, the `SubmitNodeCollector`, and the `CameraRenderState` + - `createRenderState` - Creates the render state object. + - `extractRenderState` - Extracts the render state from the block entity. + - `BlockEntityRendererProvider$Context` is now a record, taking in a `MaterialSet` and `PlayerSkinRenderCache` + - It now has another generic `S` representing the `BlockEntityRenderState` + - `CopperGolemStatueBlockRenderer` - A block entity renderer for the copper golem statue. + - `DecoratedPotRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `render` overload -> `submit`, now takes in the outline color + - `HangingSignRenderer` + - `createSignModel` now returns a `Model$Simple` + - `renderInHand` now takes in a `MaterialSet` + - `ShelfRenderer` - A block entity renderer for a shelf. + - `ShulkerBoxRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `render` overload -> `submit`, now takes in the outline color + - `SignRenderer` + - `createSignModel` now returns a `Model$Simple` + - `renderInHand` now takes in a `MaterialSet` + - `SkullBlockRenderer#submitSkull` - Submits the skull model to the collector. + - `SpawnerRenderer#renderEntityInSpawner` -> `submitEntityInSpawner`, now takes in the `CameraRenderState` + - `TestInstanceREnderer` now takes in the `BlockEntityRendererProvider$Context` +- `net.minecraft.client.renderer.blockentity.state` + - `BannerRenderState` - The render state for the banner block entity. + - `BeaconRenderState` - The render state for the beacon block entity. + - `BedRenderState` - The render state for the bed block entity. + - `BellRenderState` - The render state for the bell block entity. + - `BlockEntityRenderState` - The base render state for all block entities. + - `BlockEntityWithBoundingBoxRenderState` - The render state for a block entity with a custom bounding box. + - `BrushableBlockRenderState` - The render state for a brushable block entity. + - `CampfireRenderState` - The render state for the campfire block entity. + - `ChestRenderState` - The render state for the chest block entity. + - `CondiutRenderState` - The render state for the conduit block entity. + - `CopperGolemStatueRenderState` - The render state for the copper golem block entity. + - `DecoratedPotRenderState` - The render state for the decorated pot block entity. + - `EnchantTableRenderState` - The render state for the enchantment table block entity. + - `EndGatewayRenderState` - The render state for the end gateway block entity. + - `EndPortalRenderState` - The render state for the end portal block entity. + - `LecternRenderState` - The render state for the lectern block entity. + - `PistonHeadRenderState` - The render state for the piston head block entity. + - `ShelfRenderState` - The render state for the shelf block entity. + - `ShulkerBoxRenderState` - The render state for the shulker box block entity. + - `SignRenderState` - The render state for the sign block entity. + - `SkullBlockRenderState` - The render state for the skull block entity. + - `SpawnerRenderState` - The render state for the spawner block entity. + - `TestInstanceRenderState` - The render state for the test instance block entity. + - `VaultRenderState` - The render state for the vault block entity. +- `net.minecraft.client.renderer.culling.Frustum` + - `offset` - Offsets the position. + - `pointInFrustum` - Checks whether the provided coordinate is within the frustum. +- `net.minecraft.client.renderer.entity` + - Most methods here that take in the `MultiBufferSource` and light coordinates integer have been replaced by `SubmitNodeCollector` and a render state param + - Most methods change their name from `render*` to `submit*` + - `AbstractBoatRenderer#renderTypeAdditions` -> `submitTypeAdditions` + - `AbstractMinecartRenderer#renderMinecartContents` -> `submitMinecartContents` + - `AbstractSkeletonRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `AbstractZombieRenderer` takes in a `ArmorModelSet` instead of a model + - `ArmorModelSet` - A holder that maps some object to each humanoid armor slot. Typically holds the layer definitions, which are then baked into their associated models. + - `BreezeRenderer#enable` is removed + - `CopperGolemRenderer` - The renderer for the copper golem entity. + - `DisplayRenderer#renderInner` -> `submitInner` + - `EnderDragonRenderer#renderCrystalBeams` -> `submitCrystalBeams` + - `EntityRenderDispatcher` now takes in the `AtlasManager` + - `prepare` no longer takes in the `Level` + - `setRenderShadow`, `setRenderHitBoxes`, `shouldRenderHitBoxes` are removed + - `extractEntity` - Creates the render state from the entity and the partial tick. + - `render` -> `submit`, now takes in the `CameraRenderState` + - `setLevel` -> `resetCamera`, not one-to-one + - `getPlayerRenderer` - Gets the `AvatarRenderer` from the given client player. + - `overrideCameraOrientation`, `distanceToSqr`, `cameraOrientation` are removed + - `EntityRenderer` + - `NAMETAG_SCALE` is now public + - `render(S, PoseStack, MultiBufferSource, int)` -> `submit(S, PoseStack, SubmitNodeCollector, CameraRenderState)` + - `renderNameTag` -> `submitNameTag`, now takes in a `CameraRenderState` + - `finalizeRenderState` - Extracts the information of the render state as a last step after `extractRenderState`, such as shadows. + - `EntityRendererProvider$Context` now takes in the `PlayerSkinRenderCache` and `AtlasManager` + - `getModelManager` is removed + - `getMaterials` - Returns a mapper of material to atlas sprite. + - `getPlayerSkinRenderCache` - Gets the render cache of player skins. + - `getAtlas` - Returns the atlas for that location. + - `EntityRenderers#createPlayerRenderers` now returns a map of `PlayerModelType`s to `AvatarRenderer`s + - `ItemEntityRenderer` + - `renderMultipleFromCount` -> `submitMultipleFromCount` + - `renderMultipleFromCount(PoseStack, MultiBufferSource, int, ItemClusterRenderState, RandomSource)` -> `renderMultipleFromCount(PoseStack, SubmitNodeCollector, int, ItemClusterRenderState, RandomSource)` + - `ItemRenderer` no longer takes in the `ItemModelResolver` + - `getArmorFoilBuffer` -> `getFoilRenderTypes`, not one-to-one + - `renderStatic` methods are removed + - `MobRenderer#checkMagicName` - Returns whether the custom name matches the given string. + - `PiglinRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `TntMinecartRenderer#renderWhiteSolidBlock` -> `submitWhiteSolidBlock`, now takes in an outline color + - `ZombieRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `ZombifiedPiglinPiglinRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` +- `net.minecraft.client.renderer.entity.layers` + - `ArrowLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `BeeStingerLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `BlockDecorationLayer` - A layer that handles a block model transformed by an entity. + - `BreezeWindLayer` now takes in the `EntityModelSet` instead of the `EntityRendererProvider$Context` + - `CapeLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `CustomHeadLayer` now takes in the `PlayerSkinRenderCache` + - `Deadmau5EarsLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `EquipmentLayerRenderer#renderLayers` now takes in the render state, `SubmitNodeCollector`, outline color, and an initial order instead of a `MultiBufferSource` + - `HumanoidArmorLayer` now takes in `ArmorModelSet`s instead of models + - `setPartVisibility` is removed + - `ItemInHandLayer#renderArmWithItem` -> `submitArmWithItem` + - `LivingEntityEmissiveLayer` now takes in a function for the texture instead of a `ResourceLocation` and a model instead of the `$DrawSelector` + - `$DrawSelector` is removed + - `ParrotOnShoulderLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `PlayerItemInHandLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `RenderLayer` + - `renderColoredCutoutModel`, `coloredCutoutModelCopyLayerRender` now takes in a `Model` instead of an `EntityModel`, a `SubmitNodeCollector` instead of a `MultiBufferSource`, and an integer representing the order layer for rendering + - `render` -> `submit`, taking in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `SimpleEquipmentLayer` now takes in an order integer + - `SpinAttackEffectLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `StuckInBodyLayer` now has an additional generic for the render state, also taking in the render state in the constructor + - `numStuck` now takes in an `AvatarRenderState` instead of the `PlayerRenderState` + - `VillagerProfessionLayer` now takes in two models +- `net.minecraft.client.renderer.entity.player.PlayerRenderer` -> `AvatarRenderer` + - `render*Hand` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` +- `net.minecraft.client.renderer.entity.state` + - `CopperGolemRenderState` - The render state for the copper golem entity. + - `DisplayEntityRenderState#cameraYRot`, `cameraXRot` - The rotation of the camera. + - `EntityRenderState` + - `NO_OUTLINE` - A constant that represents the color for no outline. + - `outlineColor` - The outline color of the entity. + - `lightCoords` - The packed light coordinates used to light the entity. + - `shadowPieces`, `$ShadowPiece` - Represents the relative coordinates of the shadow(s) the entity is casting. + - `FallingBlockRenderState` fields and implementations have all been moved to `MovingBlockRenderState` + - `LivingEntityRenderState` + - `appearsGlowing` -> `EntityRenderState#appearsGlowing`, now a method + - `customName` is removed + - `PaintingRenderState#lightCoords` -> `lightCoordsPerBlock` + - `PlayerRenderState` -> `AvatarRenderState` + - `useItemRemainingTicks`, `swinging` are removed + - `showDeadMouseEars` -> `showExtraEars` + - `SheepRenderState` + - `id` is removed + - `isJebSheep` is now a field instead of a method + - `WitherSkullRenderState#xRot`, `yRot` -> `modeState`, not one-to-one +- `net.minecraft.client.renderer.feature` + - `BlockFeatureRenderer` - Renders the submitted blocks, block models, or falling blocks. + - `CustomFeatureRenderer` - Renders the submitted geometry via a passed function. + - `FeatureRenderDispatcher` - Dispatches all features to render from the submitted node collector objects. + - `FlameFeatureRenderer` - Renders the submitted entity on fire animation. + - `HitboxFeatureRenderer` - Renders the submitted entity hitbox. + - `ItemFeatureRenderer` - Renders the submitted items. + - `LeashFeatureRenderer` - Renders the submitted leash attached to entities. + - `ModelFeatureRenderer` - Renders the submitted `Model`s. + - `ModelPartFeatureRenderer` - Renders the submitted `ModelPart`s. + - `NameTagFeatureRenderer` - Renders the submitted name tags. + - `ParticleFeatureRenderer` - Renders the submitted particles. + - `ShadowFeatureRenderer` - Render the submitted entity shadow. + - `TextFeatureRenderer` - Renders the submitted text. +- `net.minecraft.client.renderer.item` + - `ItemModel$BakingContext` now takes in a `MaterialSet` and `PlayerSkinRenderCache`, and implements `SpecialModelRenderer$BakingContext` + - `ItemStackRenderState#render` -> `submit`, taking in a `SubmitNodeCollector` instead of a `MultiBufferSource` and an outline color +- `net.minecraft.client.renderer.special` + - Most methods here that take in the `MultiBufferSource` have been replaced by `SubmitNodeCollector` + - `ChestSpecialRenderer` now takes in a `MaterialSet` + - `*COPPER*` - Textures for the copper chest. + - `ConduitSpecialRenderer` now takes in a `MaterialSet` + - `CopperGolemStatueSpecialRenderer` - A special renderer for the copper golem statue as an item. + - `HangingSignSpecialRenderer` now takes in a `MaterialSet` and a `Model$Simple` instead of a `Model` + - `NoDataSpecialModelRenderer#render` -> `submit`, now takes in an outline color + - `PlayerHeadSpecialRenderer` now takes in the `PlayerSkinRenderCache` + - `ShieldSpecialRenderer` now takes in a `MaterialSet` + - `SpecialModelRenderer` + - `render` -> `submit`, now takes in an outline color + - `$BakingContext` - The context used to bake a special item model. + - `$Unbaked#bake` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `SpecialModelRenderers#createBlockRenderers` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `StandingSignSpecialRenderer` now takes in a `MaterialSet` and a `Model$Simple` instead of a `Model` +- `net.minecraft.client.renderer.state` + - `BlockBreakingRenderState` - The render state for how far the current block has been broken. + - `BlockOutlineRenderState` - The render state for the outline of a block via its `VoxelShape`s. + - `CameraRenderState` - The render state of the camera. + - `LevelRenderState` - The render state of the dynamic features in a level. + - `ParticleGroupRenderState` - The render state for a group of particles. + - `ParticlesRenderState` - The render state for all particles. + - `QuadParticleRenderState` - The render group state for all single quad particles. + - `SkyRenderState` - The render state of the sky, including the moon and stars. + - `WeatherRenderState` - The render state of the current weather. + - `WorldBorderRenderState` - The render state of the world border. +- `net.minecraft.client.renderer.texture` + - `SkinTextureDownloader` is now an instance class rather than a static method holder, taking in a `Proxy`, `TextureManager`, and the main thread `Executor` + - Most methods that were previously static are now instance methods + - `SpriteContents` now takes in an optional `AnimationMetadataSection` and `MetadataSectionType$WithValue` list instead of a `ResourceMetadata` + - `metadata` -> `getAdditionalMetadata`, not one-to-one + - `SpriteLoader` + - `DEFAULT_METADATA_SECTIONS` is removed + - `stitch` is now private + - `runSpriteSuppliers` is now private + - `loadAndStitch(ResourceManager, ResourceLocation, int, Executor)` isn removed + - `loadAndStitch` now takes a set of `MetadataSectionType`s instead of a collection + - `$Preparations` + - `waitForUpload` is removed + - `getSprite` - Returns the atlas sprite for a given resource location. + - `TextureAtlasSprite#isAnimated` -> `SpriteContents#isAnimated` +- `net.minecraft.client.renderer.texture.atlas.SpriteResourceLoader#create` now takes a set of `MetadataSectionType`s instead of a collection +- `net.minecraft.client.resources` + - `MapDecorationTextureManager` class is removed + - `PaintingTextureManager` class is removed + - `PlayerSkin$Model` -> `PlayerModelType`, not one-to-one + - The constructor not takes in the legacy service name + - `byName` -> `byLegacyServicesName` + - `SkinManager` now takes in `Services` instead of a `MinecraftSessionService`, and a `SkinTextureDownloader` + - `lookupInsecure` -> `createLookup`, now taking in a boolean of whether to check for insecure skins + - `getOrLoad` -> `get` + - `TextureAtlasHolder` class is removed +- `net.minecraft.client.resources.model` + - `AtlasIds` -> `net.minecraft.data.AtlasIds` + - `AtlasSet` -> `AtlasManager`, not one-to-one + - `forEach` - Iterates through each of the atlas sheets. + - `Material` + - `sprite` -> `MaterialSet#get` + - `buffer` now takes in a `MaterialSet` + - `MaterialSet` - A map of material to its atlas sprite. + - `ModelBakery` now takes in a `MaterialSet` and `PlayerSkinRenderCache` + - `ModelManager` is no longer `AutoCloseable` + - The constructor takes in the `PlayerSkinRenderCache`, `AtlasManager` instead of the `TextureManager`, and the max mipmap levels integer + - `getAtlas` -> `MaterialSet#get` + - `updateMaxMipLevel` -> `AtlasManager#updateMaxMipLevel` +- `net.minecraft.core.particles` + - `ParticleGroup` -> `ParticleLimit` + - `ParticleTypes` + - `DRAGON_BREATH` now uses a `PowerParticleOption` + - `EFFECT` now uses a `SpellParticleOption` + - `FLASH` now uses a `ColorParticleOption` + - `INSTANT_EFFECT` now uses a `SpellParticleOption` + - `PowerParticleOption` - A particle option for the dragon's breath. + - `SpellParticleOption` - A particle option for potion effects. + +## The Font Glyph Pipeline + +Glyphs have been partially reworked in the backend to both unify both characters and their effects to a single renderable and add a baking flow, albeit delayed. This will provide a brief overview of this new flow. + +Let's start from the top when the assets are reloaded, causing the `FontManager` to run. The font definitions are loaded and passed to their appropriate `GlyphProviderDefinition`, which for this example with immediately unpack into a `GlyphProvider$Loader`. The loader reads whatever information it needs (most likely a texture) and maps it to an associated codepoint as an `UnbakedGlyph`. An `UnbakedGlyph` represents a single character containing its `GlyphInfo` with the position metadata and a `bake` method to write it to a texture. `bake` takes in a `UnbakedGlyph$Stitcher`, which itself takes in a `GlyphBitmap` to correctly position and upload the glyph along with the `GlyphInfo` for any offset adjustments. Then, after and resolving and finalizing, the `FontSet`s are created using `FontSet#reload`. This resets the textures and cache and calls `FontSet#selectProviders` to store the active list of `GlyphProvider`s and populates the `glyphsByWidth` by mapping the character advance to a list of matching codepoints. At this point, all of the loading has been done. While the glyphs are stored in their unbaked format, they are not baked and cached until that specific character is rendered. + +Now, let's move onto the `FontDescription`. A `FontDescription` provides a one-to-one map to a `GlyphSource`, which is responsible for obtaining the glyphs. Vanilla provides three `FontDescription`s: `$Resource` for mapping to the `FontSet` (the font JSON name) as mentioned above, `$AtlasSprite` to interpret an atlas as a bunch of glyphs, and `$PlayerSprite` for rendering the player head and hat. For a given `Component`, the `FontDescription` used can be set as its `Style` via `Style#withFont`. + +So, let's assume you are drawing text to the screen using `FontDescription#DEFAULT`, which uses the defined `assets/minecraft/font/default.json`. Eventually, this will either call `Font#drawInBatch` or `drawInBatch8xOutline`. Then, whether through the `StringSplitter` or directly, the `GlyphSource` is obtained from the `FontDescription`. Then, `GlyphSource#getGlyph` is called. For the `FontDescription$AtlasSprite` and `$PlayerSprite`, this just returns a wrapper around the texture in question. For the `$Resource` though, this internally calls `FontSet#getGlyph`, which stores the `UnbakedGlyph` as part of a `FontSet$DelayedBake`, which it then immediately resolves to the `BakedGlyph` by calling `UnbakedGlyph#bake` to write the glyph to some texture. + +A `BakedGlyph` contains two methods: the `GlyphInfo` for the position metadata like before, and a method called `createGlyph`, which returns a `TextRenderable`: a renderer to draw the glyph to the screen. `TextRenderable` also has a subinterface called `PlainTextRenderable` for help with texture sprites. Internally, all resource `BakedGlyph`s are `BakedSheetGlyph`s, as the `UnbakedGlyph$Stitcher#stitch` called just wraps around `GlyphStitcher#stitch`. You can think of the `BakedSheetGlyph` as a view onto a 256x256 `FontTexture`s, where if there is not enough space on one `FontTexture`, then a new `FontTexture` is created. + +`BakedSheetGlyph` also implements `EffectGlyph`, which is likely supposed to render some sort of effect on the text. This functionality, while it is currently implemented as just another object, is only used for the white glyph, which goes unused. + +### Object Info + +`ObjectInfo`s are the server side implementations to construct the `FontDescription` used to render an arbitrary object through the glyph pipeline. Each info takes in the `FontDescription` and a regular `String` to display a simple description. Additionally, it takes in a `MapCodec` to encode and decode from the object contents. + +Note that for custom `FontDescription`s to map to a source properly, you will need to somehow modify `FontManager$CachedFontProvider#getGlyphSource` or implement a custom `Font$Provider`. + +```java +// A basic font description +public static record BlockDescription(Block block) implements FontDescription {} + +// A simple object info +public record BlockInfo(Block block) implements ObjectInfo { + // The codec to send the information over the network + public static final MapCodec MAP_CODEC = BuiltInRegistries.BLOCK.byNameCodec().fieldOf("block"); + + @Override + public FontDescription fontDescription() { + // The font description to render + return new BlockDescription(this.block); + } + + @Override + public String description() { + // Just a text description of the object + return Objects.toString(BuiltInRegistries.BLOCK.getKey(this.block)); + } + + @Override + public MapCodec codec() { + return MAP_CODEC; + } +} + +// Create the `GlyphSource` and `PlainTextRenderable` used to render the object +public record BlockRenderable(...) implements PlainTextRenderable { + // ... +} + +public static GlyphSource create(Block block) { + return new SingleSpriteSource(...); +} +``` + +The `ObjectInfo` also needs to be rendered to `ObjectInfos#ID_MAPPER`: + +```java +// Assumes the the mapper has been made public +ObjectInfos.ID_MAPPER.put("examplemod:block", BlockInfo.MAP_CODEC); +``` + +### Component Contents + +Component contents also now use an id mapper instead of holding the id on the type. This means that creating a custom component is done by somehow hooking into `ComponentSerialization#bootstrap` and registering the map codec of your `ComponentContents` implementation to the mapper. + +### Data Sources + +Data sources has received a similar treatment to component contents, now using an id mapper instead of holding the id on the type. The data source is then registered by registering to `DataSources#ID_MAPPER` the map codec of your `DataSource`. Note that the mapper field is private, so you will probably need to use an available workaround. + +- `com.mojang.blaze3d.font` + - `GlyphInfo` + - `bake` -> `UnbakedGlyph#bake`, now takes in a `UnbakedGlyph$Stitcher` instead of a function + - The function behavior is replaced by `UnbakedGlyph$Stitcher#stitch` + - `$SpaceGlyphInfo` -> `GlyphInfo#simple` and `EmptyGlyph`, not one-to-one + - `$Stitched` -> `UnbakedGlyph`, not one-to-one + - `GlyphProvider#getGlyph` now returns an `UnbakedGlyph` + - `SheetGlyphInfo` -> `GlyphBitmap` +- `net.minecraft.client.gui` + - `Font` no longer takes in a function and boolean, instead a `Font$Provider` + - `random` is now private + - `$GlyphVisitor` + - `acceptGlyph` now takes in a `TextRenderable` instead of a `BakedGlyph$GlyphInstance` + - `acceptEffect` now only takes in a `TextRenderable` + - `$PreparedTextBuilder#accept` now has an override that takes in a `BakedGlyph` instead of its codepoint + - `$Provider` - A simple interface for providing the glyph source based on its description, along with the empty glyph. + - `GlyphSource` - An interface that holds the baked glyphs based on its codepoint. +- `net.minecraft.client.gui.font` + - `AtlasGlyphProvider` - A glyph provider based off a texture atlas. + - `FontManager` now takes in the `AtlasManager` and `PlayerSkinRenderCache` + - `FontSet` now takes in a `GlyphStitcher` instead of a `TextureManager` and no longer takes in the name + - `name` is removed + - `source` - Returns the glyph source depending given whether only non-fishy glyphs should be seen. + - `getGlyphInfo`, `getGlyph` -> `getGlyph`, now package-private, not one-to-one + - `getRandomGlyph` now takes in a `RandomSource` and a codepoint instead of the `GlyphInfo`, returning a `BakedGlyph` + - `whiteGlyph` now returns an `EffectGlyph` + - `$GlyphSource` - A source that can get the glyphs to bake. + - `FontTexture#add` now takes in a `GlyphInfo` and `GlyphBitmap`, returning a `BakedSheetGlyph` + - `GlyphStitcher` - A class that creates `BakedGlyph`s from its glyph information. + - `PlainTextRenderable` - An implementation of `TextRenderable` that determines how a sprite is rendered. + - `PlayerGlyphProvider` - A glyph provider for rendering the player head and hat. + - `SingleSpriteSource` - A glyph source that only contains one glyph, such as a texture. + - `TextRenderable` - Represents how a text representation, like a glyph in a font, is rendered. +- `net.minecraft.client.gui.font.glyphs` + - `BakedGlyph` is now an interface that creates the renderable object + - It original purpose has been moved to `BakedSheetGlyph` + - `EffectGlyph` - An interface that creates the renderable effect of some glyph. + - `EmptyGlyph` now implements `UnbakedGlyph` instead of extending `BakedGlyph` + - The constructor takes in the text advance of the glyph. + - `SpecialGlyphs#bake` now returns a `BakedSheetGlyph` + - This method is technically new. +- `net.minecraft.client.gui.font.providers` + - `BitmapProvider$Glyph` now implements `UnbakedGlyph` instead of `GlyphInfo$Stitched` + - `UnihexProvider$Glyph` now implements `UnbakedGlyph` instead of `GlyphInfo$Stitched` +- `net.minecraft.client.gui.render.state` + - `GlyphEffectRenderState` is removed + - Use `GlyphRenderState` + - `GlyphRenderState` now takes in a `TextRenderable` instead of a `BakedGlyph$Instance` +- `net.minecraft.network.chat` + - `Component#object` - Creates a mutable component with object contents. + - `ComponentContents#type` -> `codec`, dropping the string id + - `$Type` is removed + - `ComponentSerialization` + - `createLegacyComponentMatcher` no longer requires a `StringRepresentable` generic, instead taking in a id mapper using `String` keys + - `$FuzzyCodec` now takes in a collection of map codecs instead of a list + - `FontDescription` - An identifier that describes a font, typically as a location or sprite. + - `Style` is now final + - `getFont` now returns a `FontDescription` + - `withFont` now takes in a `FontDescription` instead of a `ResourceLocation` + - `DEFAULT_FONT` is removed +- `net.minecraft.network.chat.contents` + - `BlockDataSource` -> `.data.BlockDataSource` + - `DataSource` -> `.data.DataSource` + - `type` -> `codec`, dropping the string id + - `EntityDataSource` -> `.data.EntityDataSource` + - `*Contents` + - `CODEC` -> `MAP_CODEC` + - `TYPE` is removed + - `ObjectContents` - An arbitrary piece of content that can be written as part of a component, like a sprite. + - `StorageDataSource` -> `.data.StorageDataSource` +- `net.minecraft.network.chat.contents.data.DataSources` - All vanilla-registered data sources. +- `net.minecraft.network.chat.contents.objects` + - `AtlasSprite` - An object info for a sprite in a texture atlas. + - `ObjectInfo` - Information relating the references for an arbitrary object through the glyph pipeline. + - `ObjectInfos` - All vanilla object infos. + - `PlayerSprite` - An object info for a player head and hat texture. + +## The JSON-RPC Management Servers + +Minecraft has introduced support for remotely managing dedicated servers through a JSON-RPC websocket. This can be enabled through the `management-server-enabled` property, which listens for a server on `localhost:25585` by default. The entire system handles not only constructing the network requests sent via `JsonElement`s, but also the schemas each request uses. These schemas can then be generated through the `JsonRpcApiSchema` data provider. + +There are two types of RPC methods supported by the system: `IncomingRpcMethod`s for requests from the management server, and `OutgoingRpcMethod`s to either notify or request information from the management server. Both of these are static registry objects, but rather than implementing the interfaces, they are typically constructed and registered through their associated builders. + +### Schemas + +`Schema`s, as the name implies, are the specification of the JSON objects. They are constructed in a similar fashion `JsonElement`s. Most are constructed as `Schema#record`s, with their field and types being populated via `withField`, before being stored in a `SchemaComponent`, which maps a reference name to the schema. Then the `Schema`s can be obtained via `asRef` or `asArray` to get the object or array implementation, respectively. The `SchemaComponent`s themselves and registered to the list `Schema#SCHEMA_REGISTRY` for reference resolving. + +```json5 +// An example json for changing the weather: +{ + "weather": "clear|rain|thunder", + "duration": -1, +} +``` + +Here is what the associated schema component would look like: + +```java +public static final SchemaComponent WEATHER_SCHEMA = new SchemaComponent( + // The reference name + // While we can use colon, it would need to be percent encoded as defined by RFC 3986 + "examplemod_weather", + // The schema to use + Schema.record() + .withField("weather", Schema.ofEnum(List.of("clear", "rain", "thunder"))) + .withField("duration", Schema.INT_SCHEMA) +); + +// Register the schema to the registry +Schema.getSchemaRegistry().add(WEATHER_SCHEMA); +``` + +Note that schemas currently cannot specify whether an individual property is optional or not. + +### `IncomingRpcMethod` + +`IncomingRpcMethod`s are constructed and registered through the `method` builder. These methods take in the handler function to update the minecraft server, a codec for the result, and an optional codec for the parameters sent from the management server. From there, the builder contains methods towards the discovery service and how to execute the method. `$IncomingRpcMethodBuilder#response` and `param` define the parameters and response sent by the management server. `description` is used by the discovery service for the schemas. `undiscoverable` hides the route by default. Finally, `notOnMainThread` tells the method that it can run off the main thread. Once the desired methods are called, then either `build` or `register` can be used to construct the object, taking in the route endpoint as a namespace and path. + +The methods passed in take in the `MinecraftApi` for communicating with the dedicated server through specified 'services', and the current `ClientInfo` connection. It also takes in the parameter object if it exists. + +```java +// Construct the dto object +public record WeatherDto(String weather, int duration) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.STRING.fieldOf("weather").forGetter(WeatherDto::weather), + Codec.INT.fieldOf("duration").forGetter(WeatherDto::duration), + ) + .apply(instance, WeatherDto::new) + ); + + // Create the incoming method handler + public static WeatherDto handleWeather(MinecraftApi api, WeatherDto params, ClientInfo info) { + // Note that the api makes the server private since it expects the + // logic to be handled through one of the middle layer services. + // We will assume the `server` field was made public somehow. + if (params.weather().equals("clear")) { + api.server.overworld().setWeatherParameters(params.duration(), 0, false, false); + } else if (params.weather().equals("rain")) { + api.server.overworld().setWeatherParameters(0, params.duration(), true, false); + } else if (params.weather().equals("thunder")) { + api.server.overworld().setWeatherParameters(0, params.duration(), true, true); + } + + return params; + } +} + +// Construct and register the method endpoint +IncomingRpcMethod.method( + // The handler method + WeatherDto::handleWeather, + // The codec for the parameters + WeatherDto.CODEC, + // The codec for the result + WeatherDto.CODEC +) + // Sets the description of the route + .description("Sets the weather") + // The parameters + .param(new ParamInfo( + // The name of the object + "weather", + // The schema + WEATHER_SCHEMA.asRef() + )) + // The response + .response(new ResultInfo( + // The name of the object + "weather", + // The schema + WEATHER_SCHEMA.asRef() + )) + // Build and register the route + .register( + BuiltInRegistries.INCOMING_RPC_METHOD, + // The endpoint namespace + "examplemod", + // The endpoint path + "weather/update" + ); +``` + +### `OutgoingRpcMethod` + +`OutgoingRpcMethod`s are constructed and registered through the `notification` or `request` builder. Notifications typically only send parameters with no returned result, while requests provide a result as well. In either case, they just take in codecs for the params or result when present. `$OutgoingRpcMethod#response` and `param` define the parameters and response sent by the minecraft server. `description` is used by the discovery service for the schemas. Once the desired methods are called, then `register` can be used to construct the object, taking in the route endpoint as a namespace and path and wrapping it in a `Holder$Reference`. + +Currently, vanilla only broadcasts notifications through the `NotificationService`: a remote logger for specific method actions, like player join or changing game rule. While there are results, they must be read via `Connection#sendRequest` and handled asynchronously. + +```java +// Construct the outgoing method +// Since the minecraft server will be sending these, we need to hold the object +public static final Holder.Reference SOMETHING_HAPPENED = OutgoingRpcMethod.notification() + .description("Something happened!") + .register("examplemod", "something"); + +// Send notification, assume we have access to the `ManagementServer` managementServer +managementServer.forEachConnection(connection -> connection.sendNotification(SOMETHING_HAPPENED)); +``` + +- `net.minecraft.SharedConstants#RPC_MANAGEMENT_SERVER_API_VERSION` - The API version for JSON RPC server management. +- `net.minecraft.core.registries` + - `BuiltInRegistries`, `Registries` + - `INCOMING_RPC_METHOD` - Registry for queries to the RPC service. + - `OUTGOING_RPC_METHOD` - Registry for broadcasts from the RPC service. +- `net.minecraft.server` + - `MinecraftServer` + - `notificationManager` - Returns the current notification manager. + - `onGameRuleChanged` - Handles what happens when the game rule of the current server changes. + - `getOperatorUserPermissionLevel` -> `operatorUserPermissionLevel` + - `isLevelEnabled` -> `isAllowedToEnterPortal`, not one-to-one + - `setPvpAllowed` replaced by `GameRules#RULE_PVP` + - `setFlightAllowed` replaced by `DedicatedServerProperties#allowFlight` + - `isCommandBlockEnabled` is no longer abstract + - `isSpawnerBlockEnabled` - Returns whether spawner blocks can spawn entities. + - `getPlayerIdleTimeout` -> `playerIdleTimeout` + - `kickUnlistedPlayers` no longer takes in the `CommandSourceStack` + - `pauseWhileEmptySeconds` -> `pauseWhenEmptySeconds` + - `getSpawnProtectionRadius` -> `DedicatedServer#spawnProtectionRadius` + - `isUsingWhiteList` - Handles enabling whitelist users for the server. + - `setAutoSave`, `isAutoSave` - Handles whether the server should auto save every so often. +- `net.minecraft.server.dedicated` + - `DedicatedServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` + - `setAllowFlight` - Sets whether the players can fly in the server. + - `setDifficulty` - Sets the game difficulty of the server. + - `viewDistance`, `setViewDistance` - Handles the view distance of the server (renderable chunks). + - `simulationDistance`, `setSimulationDistance` - Handles the simulation distance of the server (logic running chunks). + - `setMaxPlayers` - Sets the maximum number of players that can join the server. + - `setSpawnProtectionRadius` - Sets the radius of chunks that should be under spawn protection. + - `setRepliesToStatus` - Sets whether the game uses the legacy query handler. + - `setHidesOnlinePlayers` - Sets whether online players should be hidden from other players. + - `setOperatorUserPermissionLevel` - Sets the permission level of operator users. + - `statusHeartbeatInterval`, `setStatusHeartbeatInterval` - Handles the interval that the management server will check the minecraft server is still alive. + - `entityBroadcastRangePercentage`, `setEntityBroadcastRangePercentage` - Handles the broadcast range scalar for entity tracking. + - `forceGameMode`, `setForceGameMode` - Handles forcing all game modes for the users. + - `gameMode`, `setGameMode` - Sets the default game mode of the server. + - `setAcceptsTransfers` - Sets whether the server accepts client transfers from other servers. + - `setPauseWhenEmptySeconds` - Sets the number of seconds that the server should wait until it stops ticking when there are no players. + - `DedicatedServerProperties` + - `pvp` replaced by `GameRules#RULE_PVP` + - `allowFlight`, `motd`, `forceGameMode`, `enforceWhitelist`, `difficulty`, `gameMode`, `spawnProtection`, `opPermissionLevel`, `viewDistance`, `simulationDistance`, `enableStatus`, `hideOnlinePlayers`, `entityBroadcastRangePercentage`, `pauseWhenEmptySeconds`, `acceptsTransfers` are now mutable properties + - `allowNether` replaced by `GameRules#RULE_ALLOW_NETHER` + - `spawnMonsters` replaced by `GameRules#RULE_SPAWN_MONSTERS` + - `enabledCommandBlock` replaced by `GameRules#RULE_COMMAND_BLOCKS_ENABLED` + - `managementServerEnabled` - Returns whether a management server is enabled. + - `managementServerHost` - Returns the host the management server is communicating on. + - `managementServerPort` - Returns the port the management server is communicating on. + - `statusHeartbeatInterval` - Returns the heartbeat interval the management server sends to make sure the minecraft server is still alive. + - `MANAGEMENT_SERVER_TLS_ENABLED_KEY`, `MANAGEMENT_SERVER_TLS_KEYSTORE_KEY`, `MANAGEMENT_SERVER_TLS_KEYSTORE_PASSWORD_KEY` - TLS keystore setup for communication with the management server. + - `managementServerSecret` - The authorization token secret. + - `managementServerTlsEnabled` - If TLS should be used as the communication protocol. + - `managementServerTlsKeystore` - Specifies the filepath used for the TLS keystore. + - `managementServerTlsKeystorePassword` - Specifies the password for the keystore file. + - `Settings#getMutable` - Gets a mutable property for the settings key and default. +- `net.minecraft.server.jsonrpc` + - `Connection` - The inbound handler for json elements sent by the management server. + - `IncomingRpcMethod` - A definition and handler for the incoming message sent by the management server. + - `IncomingRpcMethods` - All vanilla incoming RPC handlers. + - `JsonRPCErrors` - An enum of errors that can be thrown when attempting to read, parse, or execute the method. + - `JsonRpcLogger` - A general logger for things performed by the minecraft server, whether communication or logic. + - `JsonRpcNotificationService` - A notification service that broadcasts to all connected minecraft servers. + - `JsonRPCUtils` - A utility for request objects and errors. + - `ManagementServer` - A basic websocket comms for the minecraft server to communicate with the management server. + - `OutgoingRpcMethod` - A definition and handler for outgoing requests to the management server. + - `OutgoingRpcMethods` - All vanilla outgoing RPC handlers. + - `PendingRpcRequest` - A pending request made by the minecraft server to the management server. +- `net.minecraft.server.jsonrpc.api` + - `MethodInfo` - Defines a method that is handled by the management server, either inbound or outbound. + - `ParamInfo` - Defines the parameters a specific method takes in. + - `PlayerDto` - A data transfer object representing the player. + - `ReferenceUtil` - A utility for creating a local reference URI. + - `ResultInfo` - Defines the response a specific method returns. + - `Schema` - An implementation of the json schema used the discovery service, parameters, and results. + - `SchemaComponent` - A reference definition of some component within a schema. +- `net.minecraft.server.jsonrpc.dataprovider.JsonRpcApiSchema` - A data provider that generates the json schema from the discovery service. +- `net.minecraft.server.jsonrpc.internalapi` + - `GameRules` - An api that gets the current game rule value. + - `MinecraftAllowListService` - A minecraft middle layer that handles communication from the management server about the allow list. + - `MinecraftAllowListServiceImpl` - The allow list implementation. + - `MinecraftApi` - A minecraft api that handles all the services that communicate with the management server. + - `MinecraftBanListService` - A minecraft middle layer that handles communication from the management server about the ban list. + - `MinecraftBanListServiceImpl` - The ban list implementation. + - `MinecraftExecutorService` - A minecraft middle layer that submits an arbitrary runnable or supplier to execute on the server. + - `MinecraftExecutorServiceImpl` - The executor implementation. + - `MinecraftGameRuleService` - A minecraft middle layer that handles communication from the management server about the game rules. + - `MinecraftExecutorServiceImpl` - The executor implementation. + - `MinecraftOperatorListService` - A minecraft middle layer that handles communication from the management server about the operator commands. + - `MinecraftOperatorListServiceImpl` - The operator list implementation. + - `MinecraftPlayerListService` - A minecraft middle layer that handles communication from the management server about the player list. + - `MinecraftPlayerListServiceImpl` - The player list implementation. + - `MinecraftServerSettingsService` - A minecraft middle layer that handles communication from the management server about the server settings. + - `MinecraftServerSettingsServiceImpl` - The server settings implementation. + - `MinecraftServerStateService` - A minecraft middle layer that handles communication from the management server about the current server state and send messages. + - `MinecraftServerStateServiceImpl` - The server state implementation. +- `net.minecraft.server.jsonrpc.methods` + - `AllowlistService` - A service that handles communication from the management server about the allow list. + - `BanlistService` - A service that handles communication from the management server about the player ban list. + - `ClientInfo` - An identifier for the current minecraft server connection to the management server. + - `DiscoveryService` - A service that displays the schemas of all services supported by the management server. + - `EncodeJsonRpcException` - An exception thrown when attempting to encode the json packet. + - `GameRulesService` - A service that handles communication from the management server about the game rules. + - `IllegalMethodDefinitionException` - An exception thrown when the method definition provided is illegal. + - `InvalidParameterJsonRpcException` - An exception thrown when the parameters to the method are invalid. + - `InvalidRequestJsonRpcException` - An exception thrown when the request is invalid. + - `IpBanlistService` - A service that handles communication from the management server about the ip ban list. + - `Message` - A data transfer object representing a literal or translatable component. + - `MethodNotFoundJsonRpcException` - An exception thrown when a 404 error occurs, indicating that the method doesn't exist. + - `OperatorService` - A service that handles communication from the management server about the operator commands. + - `PlayerService` - A service that handles communication from the management server about the player list. + - `RemoteRpcErrorException` - An exception thrown when something goes wrong on the management server. + - `ServerSettingsService` - A service that handles communication from the management server about the server settings. + - `ServerStateService` - A service that handles communication from the management server about the current server state and send messages. +- `net.minecraft.server.jsonrpc.security` + - `AuthenticationHandler` - Handles the validation of the authentication token bearer in the request. + - `JsonRpcSslContextProvider` - Provides the keystore context for the TLS communication. + - `SecurityConfig` - Handles the secret key, from checking basic validaty to generating a new one. +- `net.minecraft.server.jsonrpc.websocket` + - `JsonToWebSocketEncoder` - A message to message encoder for a json. + - `WebSocketToJsonCodec` - A message to message decoder for a json. +- `net.minecraft.server.notifications` + - `EmptyNotificationService` - A notification service that does nothing. + - `NotificationManager` - A manager for handling multiple notification services. + - `NotificationService` - A service that defines prospective actions taken by a listener, like a management server. +- `net.minecraft.server.players` + - `BanListEntry` + - `getReason` can now be `null` + - `getReasonMessage` - Returns the translatable component of the ban reason. + - `IpBanList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `PlayerList` now takes in the `NotificationService` instead of the max players + - `maxPlayers` is removed + - `op` now has an override for the permission level and bypass limit boolean + - `setUsingWhiteList` -> `MinecraftServer#setUsingWhiteList` + - `getPlayer` - Gets a player by their name. + - `ServerOpList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `StoredUserEntry#getUser` is now public + - `StoredUserList` now takes in the `NotificationService` + - `add`, `remove` now return a boolean if successful + - `remove(StoredUserEntry)` is removed + - `clear` - Clears all stored users. + - `UserBanList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `UserWhiteList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + +## Input Handling Consolidation + +Input handling has previously passed around the raw values, each in their own separate argument, provided by GLFW. However, a good bit of the handling logic is redundant, as specific keys are commonly checked, or all values are passed around in a game of hot potato from one method to the next. With this in mind, the input handlers in `GuiEventListener` and other calls, are now handled through event objects. These objects still contain the info GLFW passed through; however, now they have a lot of common checks through the super `InputWithModifiers` interface. + +There are two types of events: `KeyEvent`s for key presses, and `MouseButtonEvent`s for mouse presses. Key, scancode, and modifiers are wrapped into the `KeyEvent`. Button, modifiers, and the XY screen position are wrapped into the `MouseButtonEvent`. As such, it is generally a drag-and-drop replacement of just removing any of the parameters mentioned above and replacing them with their appropriate event. + +### Key Mapping Categories + +Key mappings have changed slightly, no longer taking in a raw string for its category, and instead using a `KeyMapping$Category` record, which is essentially a namspaced string. Categories can be created using `KeyMapping$Category#register`; otherwise, an error will be thrown whenever the mapping is used as part of a comparator. + +```java +public static final KeyMapping.Category EXAMPLE = KeyMapping.Category.register(ResourceLocation.withNamespaceAndPath("examplemod", "example")); +``` + +### Double-Click Expansion + +`GuiEventListener#mouseClicked` now takes in whether the click was in fact a double-click as a boolean. + +```java +// For some Screen subclass (or AbstractWidget or any GUI object rendering) + +@Override +public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + // ... + return false; +} +``` + +- `com.mojang.blaze3d.platform.InputConstants` + - `MOD_SHIFT`, `MOD_ALT`, `MOD_SUPER`, `MOD_CAPS_LOCK`, `MOD_NUM_LOCK` - Modifier keys to transform a key input. + - `KEY_LWIN`, `KEY_RWIN` -> `KEY_LSUPER`, `KEY_RSUPER` + - `getKey` now takes in a `KeyEvent` instead of the key and scancode `int`s + - `isKeyDown`, `setupKeyboardCallbacks`, `setupMouseCallbacks`, `grabOrReleaseMouse`, `updateRawMouseInput` now take in a `Window` instead of the `long` handle +- `net.minecraft.client` + - `KeyboardHandler` + - `keyPress` is now private + - `setup` now takes in a `Window` instead of the `long` handle + - `KeyMapping` now takes in a `$Category` instead of a `String` + - `shouldSetOnIngameFocus` - Returns whether the key is mapped to some value on the keyboard. + - `restoreToggleStatesOnScreenClosed` - Restores the toggled keys to its state during in-game actions. + - `key` is now protected + - `release` is now protected + - `CATEGORY_*` -> `$Category#*` + - Key can be obtained via `$Category#id` + - Component is available through `$Category#label` + - `getCategory` now returns a `$Category` instead of a `String` + - `matches` now takes in a `KeyEvent` instead of the key and scancode `int`s + - `matchesMouse` now takes in a `MouseButtonEvent` instead of the button `int` + - `Minecraft#ON_OSX` -> `InputQuirks#ON_OSX` + - `MouseHandler#setup` now takes in a `Window` instead of the `long` handle + - `ToggleKeyMapping` now has an overload that takes in an input type + - The constructor now takes in a `KeyMapping$Category` instead of a `String`, and a `boolean` that represents if the previous state of the key binding should be restored +- `net.minecraft.client.gui.components` + - `AbstractButton#onPress` now takes in an `InputWithModifiers` + - `AbstractScrollArea#updateScrolling` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `AbstractWidget` + - `onClick` now takes in a `MouseButtonEvent` instead of the XY positions and whether the button was double-clicked + - `onRelease` now takes in a `MouseButtonEvent` instead of the XY positions + - `onDrag` now takes in a `MouseButtonEvent` instead of the XY positions + - `isValidClickButton` now takes in the `MouseButtonInfo` instead of the button `int` + - `CommandSuggestions` + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `$SuggestionsList` + - `mouseClicked` no longer takes in the button `int` + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `MultilineTextField#keyPressed` now takes in a `KeyEvent` instead of the key `int` +- `net.minecraft.client.gui.components.events.GuiEventListener` + - `DOUBLE_CLICK_THRESHOLD_MS` -> `MouseHandler#DOUBLE_CLICK_THRESHOLD_MS` + - `mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions, and whether the button was double-clicked + - `mouseReleased` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `mouseDragged` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `keyReleased` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `charTyped` now takes in a `CharacterEvent` instead of the codepoint `char` and modifiers `int` +- `net.minecraft.client.gui.font.TextFieldHelper` + - `charTyped` now takes in a `CharacterEvent` instead of the codepoint `char` + - `keyPressed` now takes in a `KeyEvent` instead of the key `int` +- `net.minecraft.client.gui.navigation.CommonInputs` class is removed + - `selected` -> `InputWithModifiers#isSelection` + - `confirm` -> `InputWithModifiers#isConfirmation` +- `net.minecraft.client.gui.screens.Screen` + - `hasControlDown` -> `Minecraft#hasControlDown`, `InputWithModifiers#hasControlDown` + - `hasShiftDown` -> `Minecraft#hasShiftDown`, `InputWithModifiers#hasShiftDown` + - `hasAltDown` -> `Minecraft#hasAltDown`, `InputWithModifiers#hasAltDown` + - `isCut` -> `InputWithModifiers#isCut` + - `isPaste` -> `InputWithModifiers#isPaste` + - `isCopy` -> `InputWithModifiers#isCopy` + - `isSelectAll` -> `InputWithModifiers#isSelectAll` +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen` + - `hasClickedOutside` no longer takes in the button `int` + - `checkHotbarKeyPressed` now takes in a `KeyEvent` instead of the key and modifiers `int` +- `net.minecraft.client.gui.screens.options.controls.KeyBindsList$CategoryEntry` now takes in a `KeyMapping$Category` instead of the `Component` +- `net.minecraft.client.gui.screens.recipebook` + - `hasClickedOutside` no longer takes in the button `int` + - `RecipeBookPage#mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions, and whether the button was double-clicked +- `net.minecraft.client.input` + - `CharacterEvent` - Some kind of input interaction generates a codepoint with the currently active modifiers. + - `InputQuirks` - A utility for quirks between operating systems when handling inputs. + - `InputWithModifiers` - Defines an input with the currently active modifiers, along with some common input checks. + - `KeyEvent` - Some kind of input interaction generates a key by the scancode with the currently active modifiers. + - `MouseButtonEvent` - Some kind of input interaction generates a button at the XY position. + - `MouseButtonInfo` - Some kind of input interaction generates a button with the currently active modifiers. + +## `Level#isClientSide` now private + +The `Level#isClientSide` field is now private, so all queries must be made to the method version: + +```java +// For some Level level +level.isClientSide(); +``` + +- `net.minecraft.world.level.Level#isClientSide` field is now private + +## 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. + +### Item Owner + +Minecraft has further abstracted the holder of an item in item models to its own interface: `ItemOwner`. An `ItemOwner` is defined by three things: the `level` the owner is in, the `position` of the owner, and the Y rotation (in degrees) of the owner to indicate the facing direction. `ItemOwner`s are implemented on every `Entity`; however, their position can be offset by using `ItemOwner#offsetFromOwner` or creating a `ItemOwner$OffsetFromOwner`. + +Currently, only the new shelf block uses the offset owner so that compasses are not randomly spinning when placed. + +- `net.minecraft.client.renderer.entity.ItemRenderer#renderStatic` now takes in an optional `ItemOwner` instead of a `LivingEntity` +- `net.minecraft.client.renderer.item` + - `ItemModel#update` now takes in an `ItemOwner` instead of a `LivingEntity` + - `ItemModelResolver#updateForTopItem`, `appendItemLayers` now takes in an `ItemOwner` instead of a `LivingEntity` +- `net.minecraft.client.renderer.item.properties.numeric` + - `NeedleDirectionHelper#get`, `calculate` now takes in an `ItemOwner` instead of a `LivingEntity` + - `RangeSelectItemModelProperty#get` now takes in an `ItemOwner` instead of a `LivingEntity` + - `Time$TimeSource#get` now takes in an `ItemOwner` instead of a `Entity` +- `net.minecraft.world.entity` + - `Entity` now implements `ItemOwner` + - `ItemOwner` - Represents the owner of the item being rendered. + +### Container User + +As this new version of Minecraft introduces the copper golem (a vanilla mob that can interact with inventories), the concept of an entity that can use a container has been abstracted into its own interface: `ContainerUser`. `ContainerUser`s are expected to be implemented on some `LivingEntity` subclass. Since the actual inventory logic is handled elsewhere, `ContainerUser` only has two methods: `hasContainerOpen`, which checks whether the living entity is currently opening some container (e.g., barrel, chest); and `getContainerInteractionRange`, which determines the radius in blocks that the entity can interact with some container. + +- `net.minecraft.world.Container` + - `startOpen`, `stopOpen` now take in a `ContainerUser` instead of a `Player` + - `getEntitiesWithContainerOpen` - Returns the list of `ContainerUser`s that are interacting with this container. +- `net.minecraft.world.entity.ContainerUser` - Typically an entity that can interact with and open a container. +- `net.minecraft.world.entity.player.Player` now implements `ContainerUser` +- `net.minecraft.world.level.block.entity.EnderChestBlockEntity#startOpen`, `stopOpen` now take in a `ContainerUser` instead of a `Player` + +### Name And Id + +Unless a `GameProfile` is needed, Minecraft now passes around a `NameAndId` for every player instead. As the name implies, `NameAndId` contains the UUID and name of the player, as that is usually all that's necessary for most logic involving a player entity. + +- `net.minecraft.commands.arguments.GameProfileArgument` + - `getGameProfiles` now return a collections of `NameAndId`s + - `$Result#getNames` now return a collections of `NameAndId`s +- `net.minecraft.network.codec.ByteBufCodecs#PLAYER_NAME` - A 16 byte string stream codec of the player name. +- `net.minecraft.network.protocol.status.ServerStatus$Players#Sample` now is a list of `NameAndId`s rather than `GameProfile`s +- `net.minecraft.server` + - `MinecraftServer` + - `getProfilePermissions` now takes in a `NameAndId` instead of a `GameProfile` + - `isSingleplayerOwner` now takes in a `NameAndId` instead of a `GameProfile` + - `ANONYMOUS_PLAYER_PROFILE` is now a `NameAndId` + - `Services` now takes in a `UserNameToIdResolver` instead of a `GameProfileCache`, and a `ProfileResolver` +- `net.minecraft.server.players` + - `GameProfileCache` -> `UserNameToIdResolver`, `CachedUserNameToIdResolver`; not one-to-one + - `getAsync` is removed + - `add(GameProfile)` is removed + - `NameAndId` - An object that holds the UUID and name of a profile. + - `PlayerList` + - `load` -> `loadPlayerData`, not one-to-one + - `canPlayerLogin` now takes in a `NameAndId` instead of a `GameProfile` + - `disconnectAllPlayersWithProfile` now takes in a `UUID` instead of a `GameProfile` + - `op`, `deop` now take in a `NameAndId` instead of a `GameProfile` + - `isWhiteListed`, `isOp` now take in a `NameAndId` instead of a `GameProfile` + - `canBypassPlayerLimit` now takes in a `NameAndId` instead of a `GameProfile` + - `ServerOpList` now takes in `NameAndId` as its first generic + - `canBypassPlayerLimit` now takes in a `NameAndId` instead of a `GameProfile` + - `ServerOpListEntry` now takes in `NameAndId` as its generic and for the constructor + - `UserBanList` now takes in `NameAndId` as its first generic + - `isBanned` now takes in a `NameAndId` instead of a `GameProfile` + - `UserBanListEntry` now takes in `NameAndId` as its generic and for the constructor + - `UserWhiteList` now takes in `NameAndId` as its first generic + - `isWhiteListed` now takes in a `NameAndId` instead of a `GameProfile` + - `UserWhiteListEntry` now takes in `NameAndId` as its generic and for the constructor +- `net.minecraft.world.entity.player.Player#nameAndId` - Returns the name and id of the player. +- `net.minecraft.world.level.storage.PlayerDataStorage#load(Player, ProblemReporter)` -> `load(NameAndId)`, returns an `Optional` + +### Typed Entity Data + +Data components for storing block and entity data have been changed from using `CustomData` to the type safe variant `TypedEntityData`. `TypedEntityData` is pretty much the same as `CustomData`, storing a `CompoundTag`, except that it is represented by some `IdType` generic like `EntityType` or `BlockEntityType`. All of the methods within `CustomData` relating to block entities and entities have moved to `TypedEntityData`. + +Spawn eggs use the `TypedEntityData` to store the `EntityType` that it will spawn. The logic of spawning is still tied to the `SpawnEggItem` subclass. + +- `net.minecraft.core.component.DataComponents#ENTITY_DATA`, `BLOCK_ENTITY_DATA` are now `TypeEntityData` with `EntityType` and `BlockEntityType` ids, respectively +- `net.minecraft.world.entity.EntityType#updateCustomEntityTag` now takes in a `TypedEntityData` instead of `CustomData` +- `net.minecraft.world.item.Item$Properties#spawnEgg` - Adds the `ENTITY_DATA` component with the entity type. +- `net.minecraft.world.item.component` + - `CustomData` + - `CODEC_WITH_ID` is removed + - `COMPOUND_TAG_CODEC` - A codec for a flattened compound tag. + - `parseEntityId`, `parseEntityType` are removed + - `loadInto` -> `TypedEntityData#loadInto` + - `update`, `read`, `size` are removed + - `contains` -> `TypedEntityData#contains` + - `getUnsafe` -> `TypedEntityData#getUnsafe` + - `TypedEntityData` - A custom data that provides a type-safe identifier. +- `net.minecraft.world.level.Spawner#appendHoverText`, `getSpawnEntityDisplayName` now take in a `TypedEntityData` instead of a `CustomData` +- `net.minecraft.world.level.block.entity.BeehiveBlockEntity$Occupant#entityData` is now a `TypedEntityData` + +### Reload Listener Shared State + +`PreparableReloadListener` now have an option to share their data between other reload listeners through the use of the `PreparableReloadListener#prepareSharedState`. `prepareSharedState` is ran on the main thread before `reload` is called, which can store arbitrary values to some `$SharedKey` as basically a dictionary lookup. Then, once `reload` is called, the stored data can be obtained and used via the key. Normally, the shared values used are some kind of `CompletableFuture` and joined within. + +```java +public class FirstExampleListener implements PreparableReloadListener { + + // Create the key to write the shared data to + public static final PreparableReloadListener.StateKey> EXAMPLE = new PreparableReloadListener.StateKey<>(); + + @Override + public void prepareSharedState(PreparableReloadListener.SharedState state) { + // Add the data to the shared state + state.set(EXAMPLE, CompletableFuture.allOf()); + } + + @Override + public CompletableFuture reload(PreparableReloadListener.SharedState state, Executor tasksExecutor, PreparableReloadListener.PreparationBarrier barrier, Executor reloadExecutor) { + // Use the shared state + var example = state.get(EXAMPLE); + } +} + + +public class SecondExampleListener implements PreparableReloadListener { + + @Override + public CompletableFuture reload(PreparableReloadListener.SharedState state, Executor tasksExecutor, PreparableReloadListener.PreparationBarrier barrier, Executor reloadExecutor) { + // Use the shared state in a different listener + var example = state.get(FirstExampleListener.EXAMPLE); + } +} +``` + +- `net.minecraft.server.packs.resources` + - `PreparableReloadListener` + - `reload` now takes in a `PreparableReloadListener$SharedState` instead of a `ResourceManager` + - `prepareSharedState` - A method called before the reload listener is reloaded to share data between reloading listeners. + - `$SharedState` - A general dictionary that can provide resources between reload listeners, though they should typically be in the form of `CompletableFuture`s. + - `$StateKey` - A key into the shared state. + - `SimpleReloadInstance$StateFactory#create` now takes in a `PreparableReloadListener$SharedState` instead of a `ResourceManager` + +### Ticket Flags + +`TicketType` has been updated to take a bit flag representing the flag's properties rather than a boolean and enum. + +```java +// This needs to be registered to BuiltInRegistries#TICKET_TYPE +public static final TicketType EXAMPLE = new TicketType( + 20L, // The number of ticks before the ticket is timed out and removed, set to 0 if the ticket should never time out + // The bit flags to set, see below for replacements and explanations of the new flags + TicketType.FLAG_SIMULATION | TicketType.FLAG_LOADING +); +``` + +- `net.minecraft.server.level.TicketType` now takes in a bitmask of flags rather than a boolean and ticket use + - `FLAG_PERSIST`, `persist` replace the boolean + - `FLAG_LOADING` replaces `$TicketUse#LOADING` + - `FLAG_SIMULATION` replaces `$TicketUse#SIMULATION` + - `FLAG_KEEP_DIMENSION_ACTIVE`, `shouldKeepDimensionActive` - When set, prevents the level from unloading. + - `FLAG_CAN_EXPIRE_IF_UNLOADED`, `canExpireIfUnloaded` - When set, the ticket expires if the chunk is unloaded. + - `START` -> `PLAYER_SPAWN`, `SPAWN_SEARCH` + - `$TicketUse` class is removed +- `net.minecraft.world.level.TicketStorage` + - `shouldKeepDimensionActive` - Checks if the dimension active flag is set on any tickets in the storage. + - `removeTicketIf` now takes a `$TicketPredicate` instead of a `BiPredicate` + - `$TicketPredicate` - Tests the ticket at a given chunk position. + +### Respawn Data + +The respawn logic has been consolidated into a single object known as `LevelData$RespawnData`. The respawn data holds the global position (a level key and block position) and the rotation of the entity. All calls to the original angle and position methods have been replaced by `Level#setRespawnData` or `getRespawnData`, which delegates to the `MinecraftServer` and eventually the level data. + +- `net.minecraft.client.multiplayer.ClientLevel#setDefaultSpawnPos` -> `Level#setRespawnData` +- `net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket` is now a record + - The parameters have been replaced with a `LevelData$RespawnData` object +- `net.minecraft.server.MinecraftServer` + - `findRespawnDimension` - Gets the default `ServerLevel` that the player should respawn in. + - `setRespawnData` - Sets the default spawn position. + - `getRespawnData` - Gets the default spawn position. +- `net.minecraft.server.level` + - `ServerLevel#setDefaultSpawnPos` -> `Level#setRespawnData` + - `ServerPlayer$RespawnConfig` now takes in a `LevelData$RespawnData` instead of the dimension, position, and angle + - Fields are still accessible from the respawn data +- `net.minecraft.world.level.Level#getSharedSpawnPos`, `getSharedSpawnAngle` -> `getRespawnData`, `getWorldBorderAdjustedRespawnData`, not one-to-one +- `net.minecraft.world.level.storage` + - `LevelData` + - `getSpawnPos`, `getSpawnAngle` -> `getRespawnData`, not one-to-one + - `$RespawnData` - Defines the global position, yaw, and pitch of where to respawn the players by default. + - `WritableLevelData#setSpawn` now only takes in the `LevelData$RespawnData` + +### The 'On Shelf' Transform + +Models now have a new transform for determining how an item sits on a shelf called `on_shelf`. + +- `net.minecraft.client.renderer.block.model.ItemTransforms#fixedFromBottom` - A transform that expects the item to be sitting on some fixed bottom, like a shelf. +- `net.minecraft.world.item.ItemDisplayContext#ON_SHELF` - When an item is placed on a shelf. + +### Client Asset Split + +`ClientAsset` has been reworked to better specify what the asset is referencing. Currently, vanilla adds `ClientAsset$Texture` to specify that the asset is a texture, which further subclasses to `$DownloadedTexture` for textures downloaded from the internet, and `$ResourceTexture` for textures accessible from some existing resource on the disk. + +- `net.minecraft.advancements.DisplayInfo` now takes in an optional `ClientAsset$ResourceTexture` for the background instead of a `ClientAsset` +- `net.miencraft.client.renderer.texture.SkinTextureDownloader#downloadAndRegisterSkin` now returns a future for the `ClientAsset$Texture` instead of a `ResourceLocation` +- `net.minecraft.client.resources` + - `PlayerSkin` -> `net.minecraft.world.entity.player.PlayerSkin` + - The constructor now takes in `ClientAsset$Texture`s instead of `ResourceLocation` and `String`s + - `texture`, `textureUrl` -> `body` + - `capeTexture` -> `cape` + - `elytraTexture` -> `elytra` + - `insecure` - Constructs a `PlayerSkin` with `insecure` set to false. + - `with` - Builds a `PlayerSkin` from its `$Patch`. + - `$Patch` - A packed object representing the skin in other files or when sending across the network. + - `SkinManager$TextureCache#getOrLoad` now returns a future for the `ClientAsset$Texture` instead of a `ResourceLocation` +- `net.minecraft.core.ClientAsset` is now an interface instead of a record + - Original implementation moved to `$ResourceTexture` + - `id` still exists as a method + - `texturePath` -> `$Texture#texturePath` + - `CODEC`, `DEFAULT_FIELD_CODEC`, `STREAM_CODEC` -> `$ResourceTexture#*` + - `$DownloadedTexture` - A texture downloaded from the internet. + - `$Texture` - A client asset which defines a texture. +- `net.minecraft.world.entity.animal.CatVariant#assetInfo` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.animal.frog.FrogVariant#assetInfo` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.animal.wolf.WolfVariant$AssetInfo#*` now take in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.variant.ModelAndTexture#asset` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` + +### Cursor Types + +The current cursor on screen can now change to a native `CursorType`, via `GLFW#glfwCreateStandardCursor` in a GUI via `GuiGraphics#requestCursor`, or `Window#selectCursor` anywhere else. Note that `Window#setAllowCursorChanges` must be true, which can be set through the options menu. + +- `com.mojang.blaze3d.platform.Window` + - `setAllowCursorChanges` - Sets whether the cursor can be changed to a different standard shape. + - `selectCursor` - Sets the current cursor to the specified type. +- `com.mojang.blaze3d.platform.cursor` + - `CursorType` - A definition of a GLFW standard cursor shape. + - `createStandardCursor` - Creates a standard cursor from its shape, name, and fallback. + - `CursorTypes` - Blaze3d's cursor types. +- `net.minecraft.client.Options#allowCursorChanges` - Sets whether the cursor can be changed to a different standard shape. +- `net.minecraft.client.gui.GuiGraphics` + - `requestCursor` - Requests the cursor to submit to be rendered. + - `applyCursor` - Applies the cursor change for rendering. + +### New Tags + +- `minecraft:block` + - `wooden_shelves` + - `copper_chests` + - `lightning_rods` + - `copper` + - `copper_golem_statues` + - `incorrect_for_copper_tool` + - `chains` + - `lanterns` + - `bars` +- `minecraft:entity_types` + - `cannot_be_pushed_onto_boats` + - `accepts_iron_golem_gift` + - `candidate_for_iron_golem_gift` +- `minecraft:item` + - `wooden_shelves` + - `copper_chests` + - `lightning_rods` + - `copper` + - `copper_golem_statues` + - `copper_tool_materials` + - `repairs_copper_armor` + - `chains` + - `lanterns` + - `bars` + - `shearable_from_copper_golem` + +### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds#isGlOnDx12` - Returns whether the renderer is using DirectX 12. +- `com.mojang.blaze3d.opengl.GlStateManager#incrementTrackedBuffers` - Increments the number of buffers used by the game. +- `com.mojang.blaze3d.systems.TimerQuery#isRecording` - Returns whether there is a query that's currently active. +- `net.minecraft.SharedConstants#RESOURCE_PACK_FORMAT_MINOR`, `DATA_PACK_FORMAT_MINOR` - The minor component of the pack version. +- `net.minecraft.advancements.critereon.MinMaxBounds` + - `bounds` - Returns the bounds of the value. + - `$FloatDegrees` - A bounds for a float representing the degree of some angle. +- `net.minecraft.client` + - `Minecraft` + - `isOfflineDevelopedMode` - Returns whether the game is in offline developer mode. + - `canSwitchGameMode` - Whether the player entity exists and has a game mode. + - `playerSkinRenderCache` - Returns the cache holding the player's render texture. + - `canInterruptScreen` - Whether the current screen can be closed by another screen. + - `packetProcessor` - Returns the processor that schedules and handles packets. + - `Options` + - `invertMouseX` - When true, inverts the X mouse movement. + - `toggleAttack` - When true, sets the attack key to be toggleable. + - `toggleUse` - When true, sets the use key to be toggleable. + - `sprintWindow` - Time window in ticks where double-tapping the forward key activates sprint. + - `saveChatDrafts` - Returns whether the message being typed in chat should be retained if the box is closed. + - `keySpectatorHotbar` - A key that pulls up the spectator hotbar menu. + - `ToggleKeyMapping#shouldRestoreStateOnScreenClosed` - Whether the previous toggle state should be restored after screen close. +- `net.minecraft.client.animation.definitions.CopperGolemAnimation` - The animations for the copper golem. +- `net.minecraft.client.data.models.BlockModelGenerators` + - `and` - ANDs the given conditions together. + - `createShelf` - Creates a shelf block state from a base and a particle texture. + - `addShelfPart` - Adds a variant for a model for all the shelf's states. + - `forEachHorizontalDirection` - Performs an operation for a pair of directions and rotations. + - `shelfCondition` - Constructs a condition based on the state of the shelf. + - `createCopperGolemStatues` - Creates all copper golem statues. + - `createCopperGolemStatue` - Creates a copper golem statue for the provided block, copper block, and weathered state. + - `createCopperChests` - Creates all copper chests. + - `createCopperLantern` - Creates a lantern and hanging lantern. + - `createCopperChain` - Creates a chain. + - `createCopperChainItem` - Creates a chain item model. +- `net.minecraft.client.data.models.model` + - `ModelTemplate` + - `SHELF_*` - Model templates for constructing a shelf into a multipart. + - `LIGHTNING_ROD` - Model template for a lightning rod. + - `CHAIN` - Model template for a chain. + - `BARS_*` - Model templates for constructing a bars-like block. + - `TexturedModel#CHAIN` - A model provider for a chain. + - `TextureMapping#bars` - A texture mapping for a bars-like block. + - `TextureSlot#BARS` - A reference to the `#bars` texture. +- `net.minecraft.client.gui` + - `Gui#renderDeferredSubtitles` - Renders the subtitles on screen. + - `GuiGraphics#getSprite` - Gets a `TextureAtlasSprite` from its material. +- `net.minecraft.client.gui.components` + - `AbstractScrollArea#isOverScrollbar` - Returns whether the current cursor position is over the scroll bar. + - `AbstractSelectionList` + - `sort` - Sorts the entries within the list. + - `swap` - Swaps the position of two entries in the list + - `clearEntriesExcept` - Removes all entries that don't match the provided element. + - `getNextY` - Returns the Y component to render the scrolled component. + - `entriesCanBeSelected` - Whether the entries in the list can be selected. + - `scrollToEntry` - Scrolls the bar such that the selected entry is on screen. + - `removeEntries` - Removes all entries that are in the provided list. + - `$Entry` + - `set*` - Sets the component size. + - `getContent*` - Get the content size and positions. + - `ChatComponent` + - `saveAsDraft`, `discardDraft` - Handles the draft message in the chat box. + - `createScreen`, `openScreen`, `preserveCurrentChatScreen`, `restoreChatScreen` - Handles screen behavior depending on the draft chat option. + - `$ChatMethod` - Defines what type of message is the chat. + - `$Draft` - Defines a draft message in the chat box. + - `EditBox` + - `DEFAULT_HINT_STYLE` - The style of the default hints. + - `SEARCH_HINT_STYLE` - The style of the searchable hints, such as in a recipe book. + - `$TextFormatter` - An interface used to format the string in the box. + - `FittingMultiLineTextWidget#minimizeHeight` - Sets the height of the widget to the inner height and padding. + - `FocusableTextWidget$BackgroundFill` - An enum that represents when the background should be filled. + - `ItemDisplayWidget#renderTooltip` - Submits the tooltip to render. + - `MultiLineLabel$Align` - Handles the alignment of the label. + - `MultilineTextField#selectWordAtCursor` - Selects the word whether the cursor is currently located. + - `SpriteIconButton$Builder#withTooltip` - Sets the tooltip to display the message. + - `StringWidget` + - `setMaxWidth` - Sets the max width of the string and how to handle the extra width. + - `$TextOverflow` - What to do if the text is longer than the max width. +- `net.minecraft.client.gui.components.events.GuiEventListener#shouldTakeFocusAfterInteraction` - When true, sets the element as focused when clicked. +- `net.minecraft.client.gui.screens` + - `ChatScreen` + - `isDraft` - Whether there is a message that hasn't been sent in the box. + - `exitReason` - The reason the chat screen was closed. + - `shouldDiscardDraft` - Whether the current draft message should be discarded. + - `$ChatConstructor` - A constructor for the chat screen based on the draft state. + - `$ExitReason` - The reason the chat screen was closed. + - `FaviconTexture#isClosed` - Returns whether the texture has been closed. + - `LevelLoadingScreen` + - `update` - Updates the current load tracker and reason. + - `$Reason` - The reason for changing the level loading screen. + - `Overlay#tick` - Ticks the overlay. + - `Screen` + - `panoramaShouldSpin` - Returns whether the rendered panorama should spin its camera. + - `setNarrationSuppressTime` - Sets until when the narration should be suppressed for. + - `isInGameUi` - Returns whether the screen is opened while playing the game, not the pause menu. + - `isAllowedInPortal` - Whether this screen can be open during the portal transition effect. + - `canInterruptWithAnotherScreen` - Whether this screen can be closed by another screen, defaults to 'close on escape' screens. +- `net.minecraft.client.gui.screens.inventory.AbstractCommandBlockScreen#addExtraControls` - Adds any extra widgets to the command block screen. +- `net.minecraft.client.gui.screens.multiplayer` + - `CodeOfConductScreen` - A screens that displays the code of conduct text for a server. + - `ServerSelectionList$Entry` + - `matches` - Returns whether the provided entry matches this one. + - `join` - Handles how the client joins to the server entry. +- `net.minecraft.client.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#ITEM_HEIGHT` - The height of each entry in the list. +- `net.minecraft.client.gui.screens.worldselection.WorldSelectionList` + - `returnToScreen` - Returns to the previous screen after reloading the world list. + - `$Builder` - Creates a new `WorldSelectionList`. + - `$Entry#getLevelSummary` - Returns the summary of the selected world. + - `$EntryType` - A enum representing what type of world the entry is. + - `$NoWorldsEntry` - An entry where there are no worlds to select from. +- `net.minecraft.client.main.GameConfig$GameData#offlineDeveloperMode` - Whether the game is offline and is ran for development. +- `net.minecraft.client.multiplayer` + - `ClientCommonPacketListenerImpl` + - `seenPlayers` - All players that have been seen, regardless of if they are currently online, by this player. + - `seenInsecureChatWarning` - If the player has seen the insecure chat warning. + - `$CommonDialogAccess` - A dialog access used by the client network. + - `ClientConfigurationPacketListenerImpl#DISCONNECTED_MESSAGE` - The message to display on disconnect because of not accepting the code of conduct. + - `ClientExplosionTracker` - Tracks the explosions made on the client, specifically to handle particles. + - `ClientLevel` + - `endFlashState` - Handles the state of the flashes of light that appear in the end. + - `trackExplosionEffects` - Tracks an explosion to handle its particles. + - `ClientPacketListener` + - `getSeenPlayers` - Returns all players seen by this player. + - `getPlayerInfoIgnoreCase` - Gets the player info for the provided profile name. +- `net.minecraft.client.player.LocalPlayerResolver` - A profile resolver for the local player. +- `net.minecraft.client.resources.WaypointStyle#ICON_LOCATION_PREFIX` - The prefix for waypoint icons. +- `net.minecraft.client.server.IntegratedServer#MAX_PLAYERS` - The maximum number of players allowed in an locally hosted server. +- `net.minecraft.client.sounds` + - `DirectionalSoundInstance` - A sound that changes position based on the direction of the camera. + - `SoundEngineExecutor#startUp` - Creates the thread to run the engine on. + - `SoundPreviewHandler` - A utility for previewing how some event would sound like with the given settings. +- `net.minecraft.core` + - `BlockPos#betweenCornersInDirection` - An iterable that iterates through the provided bounds in the direction provided by the vector. + - `Direction#axisStepOrder` - Returns a list of directions that the given vector should be checked in. +- `net.minecraft.core.particles.ExplosionParticleInfo` - The particle that used as part of an explosion. +- `net.minecraft.data.loot.BlockLootSubProvider#createCopperGolemStatueBlock` - The loot table for a copper golem statue. +- `net.minecraft.data.loot.packs` + - `VanillaBlockInteractLoot` - A sub provider for vanilla block loot from entity interaction. + - `VanillaChargedCreeperExplosionLoot` - A sub provider for vanilla entity loot from charged creeper explosions. + - `VanillaEntityInteractLoot` - A sub provider for vanilla entity loot from entity interaction. +- `net.minecraft.data.recipes.RecipeProvider#shelf` - Constructs a shelf recipe from one item. +- `net.minecraft.data.worldgen.BiomeDefaultFeatures#addNearWaterVegetation` - Adds the vegetation when near a body of water. +- `net.minecraft.gametest.framework.GameTestHelper#getTestDirection` - Gets the direction that the test is facing. +- `net.minecraft.network` + - `FriendlyByteBuf#readLpVec3`, `writeLpVec3` - Handles syncing a compressed `Vec3`. + - `LpVec3` - A vec3 network handler that compresses and decompresses a vector into at most two bytes and two integers. + - `PacketProcessor` - A processor for packets to be scheduled and handled. +- `net.minecraft.network.chat.CommonComponents#GUI_COPY_TO_CLIPBOARD` - The message to display when copying a chat to the clipboard. +- `net.minecraft.network.protocol.configuration` + - `ClientboundCodeOfConductPacket` - A packet the sends the code of conduct of a server to the joining client. + - `ClientConfigurationPacketListener#handleCodeOfConduct` - Handles the code of conduct sent from the server. + - `ServerboundAcceptCodeOfConductPacket` - A packet that sends the acceptance response of a client reading the code of conduct from a server. + - `ServerConfigurationPacketListener#handleAcceptCodeOfConduct` - Handles the acceptance of the code of conduct from the client. +- `net.minecraft.network.syncher.EntityDataSerializers` + - `WEATHERING_COPPER_STATE` - The weather state of the copper on the golem. + - `COPPER_GOLEM_STATE` - The logic state of the copper golem. + - `RESOLVABLE_PROFILE` - The resovlable profile of an entity. +- `net.minecraft.server.MinecraftServer` + - `selectLevelLoadFocusPos` - Returns the loading center position of the server, usually the shared spawn position. + - `getLevelLoadListener` - Returns the listener used to track level loading. + - `getCodeOfConducts` - Returns a map of file names to their code of conduct text. + - `enforceGameTypeForPlayers` - Sets the game type of all players. + - `packetProcessor` - Returns the packet processor for the server. +- `net.minecraft.server.commands.FetchProfileCommand` - Fetches the profile of a given user. +- `net.minecraft.server.dedicated.DedicatedServerProperties#codeOfConduct` - Whether the server has a code of conduct. +- `net.minecraft.server.level` + - `ChunkLoadCounter` - Keeps track of chunk loading when a level is loading or the player spawns. + - `ChunkMap` + - `getLatestStatus` - Returns the latest status for the given chunk position. + - `isTrackedByAnyPlayer` - Checks whether the entity is tracked by any player. + - `forEachEntityTrackedBy` - Loops through each entity tracked by the given player. + - `forEachReadyToSendChunk` - Loops through each chunk that is ready to be sent to the client. + - `ServerChunkCache` + - `hasActiveTickets` - Checks whether the current level has any active tickets keeping it loaded. + - `addTicketAndLoadWithRadius` - Adds a ticket to some location and loads the chunk and radius around that location. + - `ServerEntity$Synchronizer` - Handles sending packets to tracking entities. + - `ServerLevel#isSpawningMonsters` - Returns whether the server can spawn monsters. + - `ServerPlayer$SavedPosition` - Holds the current position of the player on disk. +- `net.minecraft.server.level.progress.ChunkLoadStatusView` - A status view for the loading chunks. +- `net.minecraft.server.network.ConfigurationTask#tick` - Calls the task every tick until it returns true, then finishes the task. +- `net.minecraft.server.network.config` + - `PrepareSpawnTask` - A configuration task that finds the spawn of the player. + - `ServerCodeOfConductConfigurationTask` - A configuration task that sends the code of conduct to the client. +- `net.minecraft.server.packs.OverlayMetadataSection` + - `codecForPackType` - Constructs a codec for the section given the pack type. + - `forPackType` - Gets the metadata section type from the pack type. +- `net.minecraft.server.packs.metadata.MetadataSectionType#withValue`, `$WithValue` - Holds a metadata section along with its provided value. +- `net.minecraft.server.packs.metadata.pack` + - `PackFormat` - Represents the major and minor revision of a pack. + - `PackMetadataSection#forPackType` - Gets the metadata section type from the pack type. +- `net.minecraft.server.packs.repository.PackCompatibility#UNKNOWN` - The compatibility of the pack with the game is unknown as the major version is set to the max integer value. +- `net.minecraft.server.packs.resources.ResourceMetadata#getTypedSection`, `getTypedSections` - Gets the metadata sections for the provided types. +- `net.minecraft.server.players.ProfileResolver` - Resolves a game profile from its name or UUID. +- `net.minecraft.util` + - `ExtraCodecs` + - `gameProfileCodec` - Creates a codec for a `GameProfile` given the UUID codec. + - `$LateBoundIdMapper#values` - Returns a set of values within the mapper. + - `InclusiveRange#map` - Maps a range from one generic to another. + - `Mth#ceilLong` - Returns the double rounded up to the nearest long. +- `net.minecraft.util.random` + - `Weighted#streamCodec` - Constructs a stream codec for the weighted entry. + - `WeightedList#streamCodec` - Constructs a stream codec for the weighted list. +- `net.minecraft.util.thread.BlockableEventLoop#shouldRunAllTasks` - Returns if there are any blocked tasks. +- `net.minecraft.world.Nameable#getPlainTextName` - Returns the string of the name component. +- `net.minecraft.world.entity` + - `Avatar` - An entity that makes up the base of a player. + - `EntityReference` + - `getEntity` - Returns the entity given the type class and the level. + - Static `getEntity`, `getLivingEntity`, `getPlayer` - Returns the entity given its `EntityReference` and level. + - `EntityType` + - `MANNEQUIN` - The mannequin entity type. + - `STREAM_CODEC` - The stream codec for an entity type. + - `$Builder#notInPeaceful` - Sets the entity to not spawn in peaceful mode. + - `Entity` + - `canInteractWithLevel` - Whether the entity can interact with the current level. + - `isInShallowWater` - Returns whether the player is in water but not underwater. + - `getAvailableSpaceBelow` - Returns the amount of space in the Y direction between the entity and the collider, offset by the given value. + - `collectAllColliders` - Returns all entity collisions. + - `InsideBlockEffectType#CLEAR_FREEZE` - A in-block effect that clears the frozen ticks. + - `LivingEntity` + - `dropFromEntityInteractLootTable` - Drops loot from a table from an entity interaction. + - `shouldTakeDrowningDamage` - Whether the entity should take damage from drowning. + - `Mob#WEARING_ARMOR_UPGRADE_MATERIAL_CHANCE`, `WEARING_ARMOR_UPGRADE_MATERIAL_ATTEMPTS` - Constants for the armor material upgrade. + - `PositionMoveRotation#withRotation` - Creates a new object with the provided XY rotation. + - `Relative` + - `rotation` - Gets the set of relative rotations from the XY booleans. + - `position` - Gets the set of relative positions from the XYZ booleans. + - `direction` - Gets the set of relative deltas from the XYZ booleans. +- `net.minecraft.world.entity.ai.Brain#isBrainDead` - Returns whether the brain does not have any memories, snesors, or behaviors. +- `net.minecraft.world.entity.ai.behavior.TransportItemsBetweenContainers` - A behavior where an entity will move items between visited containers. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `VISITED_BLOCK_POSITIONS` - Important block positions visited. + - `TRANSPORT_ITEMS_COOLDOWN_TICKS` - How many ticks to wait before transporting items. + - `UNREACHABLE_TRANSPORT_BLOCK_POSITIONS` - Holds a list of positions that are impossible to get to. +- `net.minecraft.world.entity.ai.navigation.GroundPathNavigation#setCanPathToTargetsBelowSurface` - Sets whether the entity can target other entities that are underneath a non-air block below the starting position. +- `net.minecraft.world.entity.animal.coppergolem` + - `CopperGolem` - The copper golem entity. + - `CopperGolemAi` - The brain logic for the copper golem. + - `CopperGolemOxidationLevel` - A record holding the source events and textures for a given oxidation level. + - `CopperGolemOxidationLevels` - All vanilla oxidation levels. + - `CopperGolemState` - The current logic state the copper golem is in. +- `net.minecraft.world.entity.decoration` + - `HangingEntity#canCoexist` - Whether any other hanging entities are in the same position as this one. By default, makes sure that the entities are not the same entity type and not facing the same direction. + - `Mannequin` - An avatar that does not have a connected player. +- `net.minecraft.world.entity.player` + - `Player` + - `isMobilityRestricted` - Returns whether the player has the blindness effect. + - `handleShoulderEntities` - Handles the entities on the player's shoulders. + - `extractParrotVariant`, `convertParrotVariant`, `*ShoulderParrot*` - Handles the parrot on the player's shoulders. + - `PlayerModelPart#CODEC` - The codec for the model part. +- `net.minecraft.world.entity.raid.Raids#getRaidCentersInChunk` - Returns the number of raid centers in the given chunk. +- `net.minecraft.world.entity.vehicle.MinecartFurnace#addFuel` - Adds fuel to the furnace to push the entity. +- `net.minecraft.world.item` + - `BucketItem#getContent` - Returns the fluid held in the bucket. + - `Item$TooltipContext#isPeaceful` - Returns true if the difficulty is set to peaceful. + - `ToolMaterial#COPPER` - The copper tool material. + - `WeatheringCopperItems` - A record of items that represent each of the weathering copper states. +- `net.minecraft.world.item.equipment` + - `ArmorMaterials#COPPER` - The copper armor material. + - `EquipmentAssets#COPPER` - The key reference to the copper equipment asset. + - `ResolvableProfile` + - `skinPatch` - Returns the player skin reference. + - `$Static` - Uses the already resolved game profile. + - `$Dynamic` - Dynamically resolves the game profile on use. + - `$Partial` - Represents part of the game profile depending on whatever information is provided to the component. +- `net.minecraft.world.level` + - `BaseCommandBlock$CloseableCommandBlockSource` - A command source typically for a command block. + - `ChunkPos#contains` - Whether the given block position is in the chunk. + - `GameRules#RULE_SPAWNER_BLOCKS_ENABLED` - Whether spawner blocks should spawn entities. + - `Level` + - `getEntityInAnyDimension` - Gets the entity by UUID. + - `getPlayerInAnyDimension` - Gets the player by UUID. + - `hasEntities` - Returns whether the provided bounds has entities matching the type and predicate. + - `palettedContainerFactory` - Returns the factory used to create paletted containers. +- `net.minecraft.world.level.border.WorldBorder$Settings#toWorldBorder` - Constructs a world border from the settings. +- `net.minecraft.world.level.block` + - `Block#dropFromBlockInteractLootTable` - Drops the loot when interacting with a block. + - `ChestBlock` + - `chestCanConnectTo` - Returns whether the chest can merge with another block. + - `getConnectedBlockPos` - Gets the connected block position of the chest. + - `getOpenChestSound`, `getCloseChestSound` - Returns the sounds played on chest open / close. + - `getChestType` - Returns the type of the chest based on the surrounding chests. + - `ChiseledBookShelfBlock#FACING`, `SLOT_*_OCCUPIED` - The block state properties of the chiseled bookshelf. + - `CopperChestBlock` - The block for the copper chest. + - `CopperGolemStatueBlock` - The block for the copper golem statue. + - `SelectableSlotContainer` - A container whose slot can be selected based on in-game interaction. + - `ShelfBlock` - A block for the shelf. + - `SideChainPartBlock` - A helper for providing how the chain of a shelf should be displayed. + - `WeatheringCopper$WeatherState` + - `BY_ID` - The mapper of enum ordinal to state. + - `STREAM_CODEC` - The stream codec for the state. + - `next` - Gets the next state in the ordinal. + - `previous` - Gets the previous state in the ordinal. + - `WeatheringCopperBarsBlock` - The block for weathering copper bars. + - `WeatheringCopperBlocks` - A record of blocks that represent each of the weathering copper states. + - `WeatheringCopperChainBlock` - The block for weathering copper chains. + - `WeatheringCopperChestBlock` - The block for the weathering copper chest. + - `WeatheringCopperGolemStatueBlock` - The block for the weathering copper golem statue. + - `WeatheringLanternBlock` - The block for weathering lanterns. + - `WeatheringLightningRodBlock` - The block for the weathering lightning rod. +- `net.minecraft.world.level.block.entity` + - `BaseContainerBlockEntity#isLocked` - Returns whether the block entity has a lock. + - `CopperGolemStatueBlockEntity` - The block entity for the copper golem statue. + - `ListBackedContainer` - A container that is baked by a list of items. + - `ShelfBlockEntity` - The block entity for the shelf. +- `net.minecraft.world.level.block.entity.vault.VaultConfig#playerDetector` - Returns the detector used to detect specific entities. +- `net.minecraft.world.level.block.state.BlockBehaviour#shouldChangedStateKeepBlockEntity`, `$BlockStateBase#shouldChangedStateKeepBlockEntity` - Returns whether the block entity should be kept if the block is changed to a different block. +- `net.minecraft.world.level.block.state.properties.SideChainPart` - The location of where the chain of an object is connected to. +- `net.minecraft.world.level.chunk` + - `Configuration` - Configures what type of pallete should be created. + - `PalettedContainerFactory` - A factory for constructing paletted containers using the provided strategies. + - `PalettedContainerRO#bitsPerEntry` - Returns the number of bits needed to represent an entry. + - `PaletteResize#noResizeExpected` - Returns a resizer that throws an exception. +- `net.minecraft.world.level.levelgen` + - `Beardifier#EMPTY` - An instance with no pieces or junctions. + - `DensityFunction#invert` - Inverts the density output by putting the result one over the value. + - `DensityFunctions#findTopSurface` - Finds the top surface between the two bounds. + - `NoiseChunk#maxPreliminarySurfaceLevel` - Returns the largest preliminary surface level. + - `NoiseRouterData#NOISE_ZERO` - A constant containing the base noise level for layer zero in the overworld. +- `net.minecraft.world.level.levelgen.blending.Blender#isEmpty` - Returns whether there is no blending data present. +- `net.minecraft.world.level.levelgen.structure.BoundingBox` + - `encapsulating` - Returns the smallest box that includes the given boxes. + - `STREAM_CODEC` - The stream codec for the bounding box. +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure$MaxDistance` - The maximum horizontal and vertical distance the jigsaw can expand to. +- `net.minecraft.world.level.pathfinder.Path#STREAM_CODEC` - The stream codec of the path. +- `net.minecraft.world.level.portal.TeleportTransition#createDefault` - Creates the default teleport transition. +- `net.minecraft.world.level.storage.loot.LootContext` + - `$BlockEntityTarget` - Specifies targets when interacting with a block entity. + - `$EntityTarget` + - `TARGET_ENTITY` - The entity being targeted by another, typically the object dropping the loot. + - `INTERACTING_ENTITY` - The entity interacting with the object dropping the loot. + - `$ItemStackTarget` - Specifies targets when interacting or using an item stack. +- `net.minecraft.world.level.storage.loot.parameters` + - `LootContextParams` + - `TARGET_ENTITY` - The entity being targeted by another, typically the object dropping the loot. + - `INTERACTING_ENTITY` - The entity interacting with the object dropping the loot. + - `LootContextParamSets` + - `ENTITY_INTERACT` - An entity being interacted with. + - `BLOCK_INTERACT` - A block being interacted with. +- `net.minecraft.world.phys.Vec3#X_AXIS`, `Y_AXIS`, `Z_AXIS` - The unit vector in the positive direction of each axis. +- `net.minecraft.world.phys.shapes.CollisionContext` + - `alwaysCollideWithFluid` - Whether the collision detector should always collide with a fluid in its path. + - `emptyWithFluidCollisions` - Returns an empty collision context while checking for any fluid collisions. +- `net.minecraft.world.waypoints.PartialTickSupplier` - Gets the partial tick given the provided entity. + +### List of Changes + +- `com.mojang.blaze3d.buffers.GpuBuffer#size` is now private +- `com.mojang.blaze3d.opengl` + - `DirectStateAccess` + - `bufferSubData`, `mapBufferRange`, `unmapBuffer`, `flushMappedBufferRange` now take in the buffer usage bit mask + - `create` now takes in the `GraphicsWorkarounds` + - `GlStateManager#_texImage2D`, `_texSubImage2D` now takes in a `ByteBuffer` instead of an `IntBuffer` + - `VertexArrayCache#bindVertexArray` can now take in a nullable `GlBuffer` +- `com.mojang.blaze3d.platform` + - `ClipboardManager#getClipboard`, `setClipboard` now take in a `Window` instead of the `long` handle + - `MacosUtil#exitNativeFullscreen`, `clearResizableBit`, `getNsWindow` now take in a `Window` instead of the `long` handle + - `Window#getWindow` -> `handle` +- `com.mojang.blaze3d.systems` + - `CommandEncoder#writeToTexture` now takes in a `ByteBuffer` instead of an `IntBuffer` + - `RenderSystem#flipFrame` now takes in a `Window` instead of the `long` handle + - `TimerQuery#getInstance` now returns the raw instance rather than an optional-wrapped instance +- `com.mojang.blaze3d.vertex` + - `PoseStack$Pose#set` is now public + - `VertexConsumer#addVertexWith2DPose` no longer takes in the z component +- `net.minecraft` + - `CrashReportCategory#formatLocation` now has an overload that doesn't take in the `LevelHeightAccessor` + - `DetectedVersion#createFromConstants` -> `createBuiltIn`, now public, taking in the id, name, and optional stable `boolean` + - `SharedConstants#*_PACK_FORMAT` -> `*_PACK_FORMAT_MAJOR` + - `WorldVersion` + - `packVersion` now returns a `PackFormat` + - `$Simple` now takes in a `PackFormat` for the `resourcePackVersion` and `datapackVersion` +- `net.minecraft.advancements.critereon` + - `MinMaxBounds` now requires its generic to be `Comparable` + - `min`, `max` are now default + - `unwrapPoint` -> `$Bounds#asPoint` + - `fromReader` is now public + - `$Doubles`, `$Ints` now take in `$Bounds` for its values + - `WrappedMinMaxBounds` -> `MinMaxBounds$Bounds`, not one-to-one +- `net.minecraft.client` + - `Minecraft` + - `setLevel` no longer takes in the `ReceivingLevelScreen$Reason` + - `cameraEntity` is now private + - `openChatScreen` is now public, taking in the `ChatComponent$ChatMethod` + - `setCamerEntity` can now take in a null entity + - `forceSetScreen` -> `setScreenAndShow` + - `getMinecraftSessionService` -> `services`, now returning a `Service` instance + - The `MinecraftSessionService` can be obtained via `Service#sessionService` + - `Options#invertYMouse` -> `invertMouseY` + - `User` no longer takes in the user type +- `net.minecraft.client.data.models.BlockModelGenerators` + - `condition` now has an overload that takes in an enum or boolean property + - `createLightningRod` now takes in the regular and waxed blocks + - `createIronBars` -> `createBarsAndItem`, `createBars`; not one-to-one +- `net.minecraft.client.gui.GuiGraphics#submitSignRenderState` now takes in a `Model$Simple` instead of a `Model` +- `net.minecraft.client.gui.components` + - `AbstractScrollArea#renderScrollbar` now takes in the current XY position of the cursor. + - `AbstractSelectionList` no longer takes in the header height + - `itemHeight` -> `defaultEntryHeight` + - `addEntry`, `addEntryToTop` now takes in the height of the element + - `removeEntryFromTop` no longer returns anything + - `updateSizeAndPosition` can now take in an X component + - `renderItem` now takes in the entry instead of five integers + - `renderSelection` now takes in the entry instead of four integers + - `removeEntry` no longer returns anything + - `$Entry` now implements `LayoutElement` + - `render`, `renderBack` -> `renderContent` + - `ContainerObjectSelectionList` no longer takes in the headerh height + - `EditBox#setFormatter` -> `addFormatter`, not one-to-one + - `FocusableTextWidget` now takes in a `$BackgroundFill` instead of a boolean + - `MultiLineLabel` + - `renderCentered`, `renderLeftAligned`, `renderLeftAlignedNoShadow` -> `render`, not one-to-one + - `getStyleAtCentered`, `getStyleAtLeftAligned` -> `getStyle`, not one-to-one + - `ObjectSelectionList` no longer takes in the headerh height + - `SpriteIconButton` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `sprite` is now a `WidgetSprites` + - `$Builder#sprite` now has an overload that takes in a `WidgetSprites` + - `$CenteredIcon` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `$TextAndIcon` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `WidgetSprites` now has an overload with a single `ResourceLocation` +- `net.minecraft.client.gui.components.spectator.SpectatorGui#onMouseMiddleClick` -> `onHotbarActionKeyPressed` +- `net.minecraft.client.gui.render.state` + - `GuiElementRenderState#buildVertices` no longer takes in the `z` component + - `GuiRenderState#forEachElement` now takes in a `Consumer` instead of a `GuiRenderState$LayeredElementConsumer` +- `net.minecraft.client.gui.render.state.pip.GuiSignRenderState` now takes in a `Model$Simple` instead of a `Model` +- `net.minecraft.client.gui.screens` + - `ChatScreen` now takes in a boolean representing whether the message is a draft + - `initial` is now protected + - `EditServerScreen` -> `ManageServerScreen` + - `InBedChatScreen` now takes in the initial text and whether there is a draft mesage in the box + - `LevelLoadingScreen` now takes in a `LevelLoadTracker` and `LevelLoadingScreen$Reason` + - `PauseScreen#disconnectFromWorld` -> `Minecraft#disconnectFromWorld` + - `ReceivingLevelScreen` has been merged into `LevelLoadingScreen` + - `Screen` + - `renderWithTooltip` -> `renderWithTooltipAndSubtitles` + - `$NarratableSearchResult` is now a record + - `isValidCharacterForName` now takes in a codepoint `int` instead of a `char` +- `net.minecraft.client.gui.screens.achievement.StatsScreen` + - `initLists`, `initButtons` merged into `onStatsUpdated` + - `$ItemRow#getItem` is now protected +- `net.minecraft.client.gui.screens.dialog.DialogScreen$WarningScreen#create` now takes in a `DialogConnectionAccess` +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientActivePlayersTooltip$ActivePlayersTooltip#profiles` now is a list of `PlayerSkinRenderCache$RenderInfo`s instead of `ProfileResult`s +- `net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen` + - `*_BUTTON_WIDTH` are now private + - `join` is now public +- `net.minecraft.client.gui.screens.options.OptionsScreen#CONTROLS` is now public +- `net.minecraft.client.gui.screens.packs` + - `PackSelectionModel` now takes in a `Consumer` instead of a `Runnable` + - `$EntryBase` is now public + - `TransferableSelectionList` now is a list of `$Entry`s instead of `$PackEntry`s + - `$PackEntry` is no longer static and extends `$Entry` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldScreen#openFresh`, `testWorld`, `createFromExisting` now take in a `Runnable` instead of a `Screen` + - `WorldSelectionList` now has a package-private constructor + - `getScreen` now returns a basic `Screen` + - `$WorldListEntry` is now static + - `canJoin` -> `canInteract`, not one-to-one +- `net.minecraft.client.gui.spectator.PlayerMenuItem` now only takes in the `PlayerInfo` +- `net.minecraft.client.main.GameConfig$UserData` no longer takes in the `PropertyMap`s +- `net.minecraft.client.multiplayer` + - `ClientHandshakePacketListenerImpl` now takes in a `LevelLoadTracker` + - `CommonListenerCookie` now takes in a `LevelLoadTracker`, map of seen players, and whether the insecure chat warning has been shown + - `LevelLoadStatusManager` -> `LevelLoadTracker`, not one-to-one + - `CLOSE_DELAY_MS` -> `LEVEL_LOAD_CLOSE_DELAY_MS`, now public + - `TransferState` now takes in a map of seen players and whether the insecure chat warning has been shown +- `net.minecraft.client.multiplayer.chat.ChatListener#clearQueue` -> `flushQueue` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#forceBrightLightmap` -> `hasEndFlashes`, not one-to-one + - `LevelEventHandler` now takes in a `ClientLevel` instead of the `Level` and `LevelRenderer` + - `LevelRenderer` + - `prepareCullFrustum` is now private + - `renderLevel` now takes in an additional `Matrix4f` for the frustum +- `net.minecraft.client.resources.WaypointStyle#validate` is now public +- `net.minecraft.client.server.IntegratedServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` +- `net.minecraft.client.sounds` + - `SoundEngine#updateCategoryVolume` no longer takes in the gain + - `SoundEngineExecutor#flush` -> `shutDown`, not one-to-one + - `SoundManager#updateSourceVolume` no longer takes in the gain +- `net.minecraft.commands.arguments.coordinates` + - `LocalCoordinates` is now a record + - `WorldCoordinate` is now a record + - `WorldCoordinates` is now a record +- `net.minecraft.commands.arguments.selector.EntitySelectorParser` + - `getDistance`, `getLevel` can now be `null` + - `*Rot*` methods now return or use `MinMaxBounds$FloatDegrees` + - Return values can be `null` +- `net.minecraft.core.Registry` + - `getRandomElementOf` -> `HolderGetter#getRandomElementOf` + - `registerForHolder` now has an additional generic, making the `Holder$Reference` returned hold the actual object type instead of the registry type +- `net.minecraft.core.component.PatchedDataComponentMap#set` now has an overload that takes in a `TypedDataComponent` +- `net.minecraft.data.worldgen.TerrainProvider` methods now use a `BoundedFloatFunction` generic instead of `ToFloatFunction` +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `spawn` now has overloads that take in some number of entities to spawn + - `setBlock` now has overloads to take in a direction for block facing + - `fail` now has an overload that takes in a string + - `GameTestRunner` now takes in whether the level should be cleared for more space to spawn between batches + - `$Builder#haltOnError` no longer takes in any parameters +- `net.minecraft.nbt.NbtUtils#addDataVersion`, `addCurrentDataVersion` now has an overload that takes in a `Dynamic` instead of a `CompoundTag` or `ValueOutput` +- `net.minecraft.network` + - `FriendlyByteBuf#readSectionPos`, `writeSectionPos` -> `SectionPos#STREAM_CODEC` + - `VarInt#MAX_VARINT_SIZE` is now public +- `net.minecraft.network.protocol.PacketUtils#ensureRunningOnSameThread` now takes in a `PacketProcessor` instead of a `BlockableEventLoop` +- `net.minecraft.network.protocol.game` + - `ClientboundAddEntityPacket#getXa`, `getYa`, `getZa` -> `getMovement` + - `ClientboundExplodePacket` now takes in a radius, block count, and the block particles to display + - `ClientboundPlayerRotationPacket` now takes in whether the XY rotation is relative + - `ClientboundSetEntityMotionPacket#getXa`, `getYa`, `getZa` -> `getMovement` +- `net.minecraft.server` + - `SPAWN_POSITION_SEARCH_RADIUS` is now public + - `MinecraftServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` + - `createLevels` no longer takes in a `ChunkProgressListener` + - `getSessionService`, `getProfileKeySignatureValidator`, `getProfileRepository`, `getProfileCache` -> `services`, not one-to-one + - `getProfileCache` is now `nameToIdCache`, not one-to-one + - `updateMobSpawningFlags` is now public +- `net.minecraft.server.level` + - `ChunkMap` no longer takes in the `ChunkProgressListener` + - `getTickingGenerated` -> `allChunksWithAtLeastStatus`, not one-to-one + - `broadcast`, `broadcastAndSend` -> `sendToTrackingPlayers`, `sendToTrackingPlayersFiltered`, `sendToTrackingPlayersAndSelf`; not one-to-one + - `PlayerRespawnLogic` -> `PlayerSpawnFinder`, not one-to-one + - `ServerChunkCache` no longer takes in the `ChunkProgressListener` + - `broadcastAndSend` -> `sendToTrackingPlayersAndSelf`, not one-to-one + - `broadcast` -> `sendToTrackingPlayers`, not one-to-one + - `ServerEntity` now takes in a `$Synchronizer` instead of the brodcast method references + - `ServerEntityGetter#getNearestEntity` now has an overload that takes in a `TagKey` of entities instead of a class + - `ServerLevel` no longer takes in the `ChunkProgressListener` + - `waitForChunkAndEntities` -> `waitForEntities`, not one-to-one + - `tickCustomSpawners` no longer takes in the tick friendlies `boplean` +- `net.minecraft.server.level.chunk` + - `ChunkAccess` now takes in a `PalettedContainerFactory` instead of a `Registry` +- `net.minecraft.server.level.progress` + - `ChunkProgressListener` -> `LevelLoadListener`, not one-to-one + - `ChunkProgressListenerFactory` -> `MinecraftServer#createChunkLoadStatusView`, not one-to-one + - `LoggerChunkProgressListener` -> `LoggingLevelLoadListener`, not one-to-one + - `ProcessorChunkProgressListener`, `StoringChunkProgressListener` -> `LevelLoadProgressListener`, not one-to-one +- `net.minecraft.server.packs` + - `AbstractPackResources#getMetadataFromStream` now takes in a `PackLocationInfo` + - `OverlayMetadataSection` + - `TYPE` -> `CLIENT_TYPE`, `SERVER_TYPE` + - `overlaysForVersion` now takes in a `PackFormat` instead of an integer + - `$OverlayEntry` now takes in an `InclusiveRange` instead of an `InclusiveRange` + - `isApplicable` now takes in a `PackFormat` instead of an integer +- `net.minecraft.server.packs.metadata.pack.PackMetadataSection` now takes in an `InclusiveRange` instead of the raw pack format and integer pack. + - `CODEC` -> `FALLBACK_CODEC`, now private + - `TYPE` -> `CLIENT_TYPE`, `SERVER_TYPE`, `FALLBACK_TYPE` +- `net.minecraft.server.packs.repository` + - `Pack#readPackMetadata` now takes in a `PackFormat` and `PackType` instead of an integer + - `PackCompatibility#forVersion` now takes in `PackFormat`s instead of integers +- `net.minecraft.util` + - `CubicSpline` methods and inner classes now use `BoundedFloatFunction` instead of `ToFloatFunction` + - `ExtraCodecs` + - `GAME_PROFILE_WITHOUT_PROPERTIES` -> `AUTHLIB_GAME_PROFILE`, now a `Codec` and public + - `GAME_PROFILE` -> `STORED_GAME_PROFILE`, now a `MapCodec` + - `StringRepresentable#createNameLookup` now can take in an arbitrary object and return a string + - The base overload that takes in the object array uses `getSerializedName` + - `StringUtil#isAllowedChatCharacter` now takes in an `int` codepoint instead of a `char` + - `ToFloatFunction` -> `BoundedFloatFunction` + - This still exists as a standard interface to convert some object to a `float` +- `net.minecraft.world.entity` + - `AgeableMob#finalizeSpawn` is now nullable + - `Entity` + - `startRiding(Entity)` is now final + - `startRiding(Entity, boolean)` now takes in an additional boolean of whether to trigger the game event and criteria triggers + - `killedEntity` now takes in the `DamageSource` + - `moveOrInterpolateTo` now has overloads that take in an XY rotation, a `Vec3` position, or all three as optionals + - `lerpMotion` now takes in a `Vec3` instead of three doubles + - `forceSetRotation` now takes in whether the XY rotation is relative + - `teleportSetPosition` now has an overload that takes in both the starting and end position + - `EntityReference` is now private, constructed using the `of` static constructors + - `getEntity` now takes in a `UUIDLookup` instead of a `UUIDLookup` + - `get` now takes in a `Level` instead of a `UUIDLookup` + - `EntityType` now takes in whether the entity is allowed in peaceful mode + - `create`, `loadEntityRecursive` now has an overload that takes in an `EntityType` + - `LivingEntity` + - `shouldDropLoot` now takes in the `ServerLevel` + - `dropFromLootTable` now has overloads to take in a specific loot table key and how the items should be dispensed + - `getSlotForHand` -> `InteractionHand#asEquipmentSlot` + - `Mob#shouldDespawnInPeaceful` -> `EntityType#isAllowedInPeaceful`, not one-to-one + - `Pose` now implements `StringRepresentable`, has an associated `Codec` +- `net.minecraft.world.entity.ai.village.poi` + - `PoiManager#add` now returns a `PoiRecord` + - `PoiSection#add` now returns a `PoiRecord` +- `net.minecraft.world.entity.animal.Animal#usePlayerItem` -> `Mob#usePlayerItem` +- `net.minecraft.world.entity.animal.armadillo.Armadillo#brushOffScute` now takes in an `Entity` and `ItemStack` +- `net.minecraft.world.entity.player` + - `Player` now extends `Avatar` instead of `LivingEntity` + - `DATA_SHOULDER_*` -> `DATA_SHOULDER_PARROT_*`, now private + - `oBob`, `bob` -> `ClientAvatarState#bob0`, `bob` + - `*Cloak*` -> `ClientAvatarState#*Cloak*` + - `setEntityOnShoulder` -> `ServerPlayer#setEntityOnShoulder` + - `*ShoulderEntity*` -> `ServerPlayer#*ShoulderEntity*` + - `setMainArm` -> `Avatar#setMainArm` + - `CROUCH_BB_HEIGHT`, `SWIMMING_BB_WIDTH`, `SWIMMING_BB_HEIGHT`, `STANDING_DIMENSIONS` have been moved to `Avatar` + - `POSES` -> `Avatar#POSES`, now protected + - `PlayerModelPart` now implements `StringRepresentable` +- `net.minecraft.world.entity.projectile.Projectile` + - `deflect` now takes in an `EntityReference` of the owner instead of the `Entity` itself + - `onDeflection` no longer takes in the direct `Entity` + - `checkLeftOwner` now checks if the projectile is outside the collision range only when `leftOwner` and `leftOwnerChecked` are both false + - The original logic pertaining to this method has been moved to `isOutsideOwnerCollisionRange`, which is still private +- `net.minecraft.world.entity.vehicle.MinecartBehavior#lerpMotion` now takes in a `Vec3` instead of three doubles +- `net.minecraft.world.item` + - `ItemStack#set` now has an overload that takes in a `TypedDataComponent` + - `SpawnEggItem` no longer takes in the `EntityType` + - `spawnsEntity` no longer takes in the `HolderLookup$Provider` + - `getType` no longer takes in the `HolderLookup$Provider` +- `net.minecraft.world.item.component` + - `Bees#STREAM_CODEC` now requires a `RegistryFriendlyByteBuf` + - `ResolvableProfile` is now a sealed class with a protected constructor, created through the static `createResolved`, `createUnresolved` + - `pollResolve`, `resolve`, `isResolved` -> `resolveProfile`, not one-to-one +- `net.minecraft.world.item.enchantment.effects.ExplodeEffect` now takes in a list of block particles to display +- `net.minecraft.world.level` + - `BaseCommandBlock` no longer implements `CommandSource` + - `createCommandSourceStack` now takes in a `CommandSource` + - `BaseSpawner#getoSpin` -> `getOSpin` + - `CustomSpawner#tick` no longer takes in the tick friendlies `boolean` + - `GameRules` + - `availableRules` is now public + - `$BooleanValue#create` is now public + - `$IntegerValue#create` is now public + - `Level` no longer implements `UUIDLookup` + - `explode` now takes in a weighter list of explosion particles to display + - `neighborUpdater` is now a `CollectingNeighborUpdater` + - `tickBlockEntities` is now public + - `ServerExplosion#explode` now returns the number of blocks exploded +- `net.minecraft.world.level.border` + - `BorderChangeListener` + - `onBorderSizeSet` -> `onSetSize` + - `onBorderSizeLerping` -> `onLerpSize` + - `onBorderCenterSet` -> `onSetCenter` + - `onBorderSetWarningTime` -> `onSetWarningTime` + - `onBorderSetWarningBlocks` -> `onSetWarningBlocks` + - `onBorderSetDamagePerBlock` -> `onSetDamagePerBlock` + - `onBorderSetDamageSafeZone` -> `onSetSafeZone` + - `WorldBorder` now extends `SavedData` + - `getLerpRemainingTime` -> `getLerpTime` + - `*DamageSafeZone` -> `*SafeZone` + - `DEFAULT_SETTINGS` -> `$Settings#DEFAULT` + - `createSettings` has been replaced with the `$Settings` constructor + - `$BorderExtent#getLerpRemainingTime` -> `getLerpTime` + - `$Settings` is now a record, meaning all getters now use the record format +- `net.minecraft.world.level.block` + - `BeehiveBlock#dropHoneycomb(Level, BlockPos)` -> `dropHoneyComb(ServerLevel, ItemStack, BlockState, BlockEntity, Entity, BlockPos)` + - `CaveVines#use` entity is no longer nullable + - `ChestBlock` now takes in an open and close sound + - `ChiseledBookShelfBlock` now implements `SelectableSlotContainer` + - `BOOKS_PER_ROW` is now private +- `net.minecraft.world.level.block.entity` + - `ChiseledBookShelfBlockEntity` now implements `ListBackedContainer` + - `count` -> `ListBackedContainer#count` + - `ContainerOpenersCounter` + - `isOwnContainer` is now public + - `incrementOpeners`, `decrementOpeners` now takes in a `LivingEntity` instead of a `Player` + - `getPlayersWithContainerOpen` -> `getEntitiesWithContainerOpen`, now public, not one-to-one +- `net.minecraft.world.level.block.state.BlockBehaviour` + - `getAnalogOutputSignal`, `$BlockStateBase#getAnalogOutputSignal` now takes in the direction the signal is coming from + - `$Properties#noCollission` -> `noCollision` +- `net.minecraft.world.level.block.state.properties.BlockStateProperties#CHISELED_BOOKSHELF_SLOT_*_OCCUPIED` -> `SLOT_*_OCCUPIED` +- `net.minecraft.world.level.chunk` + - `GlobalPalette#create` -> `Configuration#createPalette` + - `HashMapPalette` no longer takes in the `IdMap` + - `create` no longer takes in the `IdMap` and `PaletteResize` + - `LevelChunkSection` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `LinearPalette` no longer takes in the `IdMap` + - `create` no longer takes in the `IdMap` and `PaletteResize` + - `Palette` + - `idFor`, `read`, `write`, `getSerializedSize` now takes in an `IdMap` + - `copy` no longer takes in the `PaletteResize` + - `$Factory#create` no longer takes in the `IdMap` and `PaletteResize` + - `PalettedContainer` no longer takes in the `IdMap` + - `codec*` no longer takes in the `IdMap` + - `unpack` is now `public`, visible for testing + - `$Configuration` -> `Configuration$Simple` + - `$Strategy` -> `Strategy` + - `getConfiguration` now takes in an `int` instead of an `IdMap`, now protected + - `PalettedContainerRO` + - `pack` no longer takes in the `IdMap` + - `$PackedData` now takes in the bits per entry `int` + - `$Unpacker#read` no longer takes in the `IdMap` + - `PaletteResize` is now `public` + - `ProtoChunk` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `SingleValuePalette` no longer takes in the `IdMap` and `PaletteResize` + - `create` no longer takes in the `IdMap` and `PaletteResize` +- `net.minecraft.world.level.chunk.storage.SerializableChunkData#containerFactory` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `parse` now takes in a `PalettedContainerFactory` instead of a `RegistryAccess` +- `net.minecraft.world.level.entity.UUIDLookup#getEntity` -> `lookup` +- `net.minecraft.world.level.gameevent` + - `BlockPositionSource` is now a record + - `EntityPositionSource#getUuid` is now public +- `net.minecraft.world.level.levelgen` + - `Beardifier` now takes in lists instead of iterators and a nullable `BoundingBox` + - `DensityFunctions%Coordinate` now implements `BoundedFloatFunction` instead of `ToFloatFunction` + - `NoiseRouter#initialDensityWithoutJaggedness` -> `preliminarySurfaceLevel` +- `net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement#addPieces` now takes in a `JigsawStructure$MaxDistance` instead of an integer +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure` now takes in a `JigsawStructure$MaxDistance` instead of an integer +- `net.minecraft.world.level.pathfinder.Path` is now final +- `net.minecraft.world.level.portal.TeleportTransition#missingRespawnBlock` no longer takes in the `Entity` to get the respawn data from +- `net.minecraft.world.level.storage` + - `PrimaryLevelData` now takes in an optional wrapped `WorldBorder$Settings` + - `ServerLevelData#*WorldBorder` -> `*LegacyWorldBorderSettings`, now dealing with optional wrapped `WorldBorder$Settings` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction` + - `copyComponents` has been split to `copyComponentsFromEntity`, `copyComponentsFromBlockEntity` + - `$Source` is now an interface + - Original implementation is in `$BlockEntitySource` + - `getReferencedContextParams` -> `contextParam`, not one-to-one + - `CopyNameFunction` + - `copyName` now takes in a `$Source` instead of a `$NameSource` + - `$NameSource` -> `$Source`, now a record, not one-to-one +- `net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider` + - `CODEC` -> `MAP_CODEC`, not one-to-one + - `$Getter` -> `$Source` + - `get` now has an overload that takes in the generic + - `getReferencedContextParams` -> `contextParam`, not one-to-one +- `net.minecraft.world.phys.shapes.EntityCollisionContext` now takes in a `boolean` instead of a `Predicate` + - `EMPTY` -> `$Empty`, not one-to-one +- `net.minecraft.world.waypoints.TrackedWaypoint` + - `STREAM_CODEC` is now final + - `yawAngleToCamera` now takes in a `PartialTickSupplier` + - `pitchDirectionToCamera` now takes in a `PartialTickSupplier` + +### List of Removals + +- `com.mojang.blaze3d.audio.Listener#setGain`, `getGain` +- `com.mojang.blaze3d.opengl` + - `GlShaderModule#compile` + - `GlStateManager` + - `_glUniform1`, `_glUniform2`, `_glUniform3`, `_glUniform4` + - `_glUniformMatrix4` + - `glActiveTexture`, `_getActiveTexture` +- `com.mojang.blaze3d.pipeline.RenderTarget#viewWidth`, `viewHeight` +- `com.mojang.blaze3d.systems.RenderSystem` + - `getQuadVertexBuffer` + - `setModelOffset`, `resetModelOffset`, `getModelOffset` +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat#BLIT_SCREEN` + - `VertexConsumer#setWhiteAlpha` +- `net.minecraft` + - `SharedConstants#VERSION_STRING` + - `Util#getVmArguments` +- `net.miencraft.advancements.critereon.MinMaxBounds$BoundsFactory`, `$BoundsFromReaderFactory` +- `net.minecraft.client` + - `Camera#FOG_DISTANCE_SCALE` + - `Minecraft` + - `getProgressListener` + - `getProfileKeySignatureValidator`, `canValidateProfileKeys` + - `Options#RENDER_DISTANCE_TINY`, `RENDER_DISTANCE_NORMAL` + - `User#getType`, `$Type` +- `net.minecraft.client.gui.components` + - `AbstractSelectionList` + - `headerHeight`, associated constructor has been removed + - `setSelectedIndex`, `getFirstElement`, `getEntry` + - `isSelectedItem` + - `renderHeader`, `renderDecorations` + - `ensureVisible` + - `remove` + - `OptionsList#getMouseOver` + - `StringWidget#alignLeft`, `alignCenter`, alignRight` +- `net.minecraft.client.gui.render.state.GuiRenderState` + - `down`, `$Node#down` + - `$LayeredElementConsumer` +- `net.minecraft.client.gui.screens.LevelLoadingScreen#renderChunks` +- `net.minecraft.client.gui.screens.achievement.StatsScreen#setActiveList` +- `net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen` + - `BUTTON_ROW_WIDTH`, `FOOTER_HEIGHT` + - `setSelected` + - `joinSelectedServer` +- `net.minecraft.client.main.GameConfig$UserData#userProperties`, `profileProperties` +- `net.minecraft.client.renderer.chunk.ChunkSectionLayer#outputTarget` +- `net.minecraft.client.resources.SkinManager#getInsecureSkin` +- `net.minecraft.gametest.framework.GameTestTicker#startTicking` +- `net.minecraft.network.syncher.EntityDataSerializers#COMPOUND_TAG` +- `net.minecraft.server.MinecraftServer#getSpawnRadius` +- `net.minecraft.server.dedicated.DedicatedServer#storeUsingWhiteList` +- `net.minecraft.server.level` + - `ServerChunkCache#getTickingGenerated` + - `ServerPlayer#loadGameTypes` +- `net.minecraft.server.packs.resources.ResourceMetadata` + - `copySections` + - `$Builder` +- `net.minecraft.world.entity.Entity` + - `spawnAtLocation(ServerLevel, ItemLike, int)` + - `getServer` +- `net.minecraft.world.entity.decoration.HangingEntity#HANGING_ENTITY` +- `net.minecraft.world.entity.item.ItemEntity#copy` +- `net.minecraft.world.entity.monster` + - `Creeper#canDropMobsSkull`, `increaseDroppedSkulls` + - `Zombie#getSkull` +- `net.minecraft.world.entity.player.Player` + - `getScoreboard` + - `isModelPartShown` +- `net.minecraft.world.entity.vehicle.MinecartTNT#explode(double)` +- `net.minecraft.world.item.Item#verifyComponentsAfterLoad` +- `net.minecraft.world.level` + - `BlockGetter#MAX_BLOCK_ITERATIONS_ALONG_TRAVEL` + - `GameRules#RULE_SPAWN_CHUNK_RADIUS` +- `net.minecraft.world.level.border` + - `BorderChangeListener$DelegateBorderChangeListener` + - `WorldBorder` + - `closestBorder` + - `$DistancePerDirection` + - `$Settings#read`, `write` +- `net.minecraft.world.level.block.FletchingTableBlock` +- `net.minecraft.world.level.block.entity.SkullBlockEntity` + - `CHECKED_MAIN_THREAD_EXECUTOR` + - `setup`, `clear` + - `fetchGameProfile` + - `setOwner` +- `net.minecraft.world.level.portal.TeleportTransition(ServerLevel, Entity, TeleportTransition.PostTeleportTransition)` +- `net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider` + - `BLOCK_ENTITY` + - `$Getter#getId` diff --git a/src/detailed-primers/26.1-from-1.21.11.md b/src/detailed-primers/26.1-from-1.21.11.md new file mode 100644 index 0000000..ae2310f --- /dev/null +++ b/src/detailed-primers/26.1-from-1.21.11.md @@ -0,0 +1,5034 @@ +# Minecraft 1.21.11 -> 26.1 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.11 to 26.1. This does not look at any specific mod loader, just the changes to the vanilla classes. + +This primer is licensed under the [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Shnupbups for some grammatical fixes +- @cassiancc for information about Java 25 IDE support +- @boq for information regarding IME support +- @lolothepro for a typo + +## 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](https://misode.github.io/versions/?id=26.1&tab=changelog). + +## Java 25 and Deobfuscation + +26.1 introduces two new changes into the general pipeline. + +First, the Java Development Kit has been upgraded from 21 to 25. Vanilla makes use of these new features, such as [JEP 447](https://openjdk.org/jeps/447), which allows statements before `super` within constructors. For users within the modding scene, please make sure to update accordingly, or take advantage of your IDE or build tool features. Microsoft's OpenJDK can be found [here](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-25). + +You may need to update your IDE to support Java 25. If using Eclipse, you will need at least either 2025-12, or 2025-09 with the Java 25 Support marketplace plugin. If using IntelliJ IDEA, you will need at least 2025.2. + +Vanilla has also returned to being deobfuscated, meaning that all value types now have the official names provided by Mojang. There are still some things that are not captured due to the Java compilation process, such as inlining primitive and string constants, but the majority are now provided. This will only have a change for users or mod loaders who used a different value type mapping set from the official mappings. + +## Loot Type Unrolling + +Loot pool entries, item functions, item conditions, nbt providers, number providers, score providers, int providers, and float providers no longer use a wrapping object type to act as the registered instance. Now, the registries directly take in the `MapCodec` used for the serialization and deserialization process. As such, the `*Type` classes or records that held the codec have been removed. Additionally, `getType` is now renamed to `codec`, taking in the registered `MapCodec`. + +```java +// The following is an example with LootItemFunctions, but can roughly apply to the other instances as well + +public record NoopItemFunction() implements LootItemFunction { + public static final NoopItemFunction INSTANCE = new NoopItemFunction(); + // The map codec used as the registry object + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + // Replaces getType + @Override + public MapCodec codec() { + // Return the registry object + return MAP_CODEC; + } +} + +// Register the map codec to the appropriate registry +Registry.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, Identifier.fromNamespaceAndPath("examplemod", "noop"), NoopItemFunction.MAP_CODEC); +``` + +- `net.minecraft.core.registries.BuiltInRegistries`, `Registries` + - `LOOT_POOL_ENTRY_TYPE` now holds a `LootPoolEntryContainer` map codec instead of a `LootPoolEntryType` + - `LOOT_FUNCTION_TYPE` now holds a `LootItemFunction` map codec instead of a `LootItemFunctionType` + - `LOOT_CONDITION_TYPE` now holds a `LootItemCondition` map codec instead of a `LootItemConditionType` + - `LOOT_NUMBER_PROVIDER_TYPE` now holds a `NumberProvider` map codec instead of a `LootNumberProviderType` + - `LOOT_NBT_PROVIDER_TYPE` now holds a `NbtProvider` map codec instead of a `LootNbtProviderType` + - `LOOT_SCORE_PROVIDER_TYPE` now holds a `ScoreboardNameProvider` map codec instead of a `LootScoreProviderType` + - `FLOAT_PROVIDER_TYPE` now holds a `FloatProvider` map codec instead of a `FloatProviderType` + - `INT_PROVIDER_TYPE` now holds a `IntProvider` map codec instead of a `IntProviderType` +- `net.minecraft.util.valueproviders` now renames `CODEC` fields to `MAP_CODEC` + - `FloatProvider` subtypes are now all records + - `IntProvider` subtypes, except for `WeightedListInt`, are now all records + - `FloatProvider` is now an `interface` from a `class` + - `CODEC` -> `FloatProviders#CODEC` + - `codec` -> `FloatProviders#codec` + - `getType` -> `codec`, not one-to-one + - `getMinValue` -> `min` + - `getMaxValue` -> `max` + - `FloatProviders` - All vanilla float providers to register. + - `FloatProviderType` interface is removed + - Singleton fields have all been removed, use map codecs in each class instead + - `codec` -> `FloatProvider#codec` + - `IntProvider` is now an `interface` from a `class` + - `CODEC` -> `IntProviders#CODEC` + - `NON_NEGATIVE_CODEC` -> `IntProviders#NON_NEGATIVE_CODEC` + - `POSITIVE_CODEC` -> `IntProviders#POSITIVE_CODEC` + - `codec` -> `IntProviders#codec` + - `validateCodec` -> `IntProviders#validateCodec` + - `getMinValue` -> `minInclusive` + - `getMaxValue` -> `maxInclusive` + - `getType` -> `codec`, not one-to-one + - `IntProviders` - All vanilla int providers to register. + - `IntProviderType` interface is removed + - Singleton fields have all been removed, use map codecs in each class instead + - `codec` -> `IntProvider#codec` +- `net.minecraft.world.level.storage.loot.entries` now renames `CODEC` fields to `MAP_CODEC` + - `LootPoolEntries` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot pool entries. + - `LootPoolEntryContainer#getType` -> `codec`, not one-to-one + - `LootPoolEntryType` record is removed +- `net.minecraft.world.level.storage.loot.functions` now renames `CODEC` fields to `MAP_CODEC` + - `LootItemFunction#getType` -> `codec`, not one-to-one + - `LootItemFunctions` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot item functions. + - `LootItemFunctionType` record is removed +- `net.minecraft.world.level.storage.loot.predicates` now renames `CODEC` fields to `MAP_CODEC` + - `LootItemCondition#getType` -> `codec`, not one-to-one + - `LootItemConditions` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot item conditions. + - `LootItemConditionType` record is removed +- `net.minecraft.world.level.storage.loot.providers.nbt` now renames `CODEC` fields to `MAP_CODEC` + - `LootNbtProviderType` record is removed + - `NbtProvider` now implements `LootContextUser` + - `getType` -> `codec`, not one-to-one + - `NbtProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the nbt providers. + - `LootItemConditionType` record is removed +- `net.minecraft.world.level.storage.loot.providers.number` now renames `CODEC` fields to `MAP_CODEC` + - `LootNumberProviderType` record is removed + - `NumberProvider#getType` -> `codec`, not one-to-one + - `NumberProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the number providers. +- `net.minecraft.world.level.storage.loot.providers.score` now renames `CODEC` fields to `MAP_CODEC` + - `LootScoreProviderType` record is removed + - `ScoreProvider` now implements `LootContextUser` + - `getType` -> `codec`, not one-to-one + - `ScoreProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the score providers. + +## Validation Overhaul + +The validation handler used to collect and then report problems with data-generated content has been overhauled. This is not, and has never been a replacement for field validation. The validation handler is specifically for more easily handling validation between multiple pieces of information that may not be exposed to a single field, such as whether a loot provider can be used for the given context params. + +All validated objects implement either `Validatable`, or `CriterionTriggerInstance` specifically for advancement criteria. Both of these methods provide one method: `validate`, which is used to check the validity of an object. `validate` takes in a `ValidationContext`, which essentially holds the `ProblemReporter` used to collect issues, the current context params, and a reference resolver. `CriterionTriggerInstance` provides a `ValidationContextSource`, but this can be transformed to a `ValidationContext` using one of the `context` methods, providing the context params to check against. If the specific object cannot be validated, then `ValidationContext#reportProblem` is called, detailing the specific issue. + +```java +// For some object that implements Validatable + +@Override +public void validate(ValidationContext ctx) { + // Check if a specific condition is validated. + if (this.foo() != this.bar()) { + // If not, report that there is an issue. + ctx.reportProblem(() -> "'Foo' does not equal 'bar'."); + } +} +``` + +If the object itself does not have any issues, but rather the specific fields, then the reporter can follow the stack trace while checking the individual elements using one of the `ValidationContext#for*` methods, performing something similar. + +```java +// For some object that implements Validatable +// Let's assume it has a list of children objects. + +@Override +public void validate(ValidationContext ctx) { + for (int i = 0; i < this.children.size(); i++) { + // Get specific context for child in list + var childCtx = ctx.forIndexedField("children", i); + // Check if a specific condition is validated. + if (this.foo() != this.bar()) { + // If not, report that there is an issue. + childCtx.reportProblem(() -> "'Foo' does not equal 'bar'."); + } + } +} +``` + +`Validatable` also provides some static utilities for checking other `Validatable` fields. + +```java +// For some object that implements Validatable +// Assume some child object also implements Validatable + +@Override +public void validate(ValidationContext ctx) { + Validatable.validate(ctx, "child", this.child); +} +``` + +After `Validatable` is implemented on all required objects, the validation can then be called depending on where it is used (typically after deserialization or before serialization). The call stack for these is typically the following: + +```java +// For some Validatable validatable +// Let's assume we have access to the HolderGetter.Provider provider. +// The parameter itself is optional if not available. + +// Create the problem collector and validation context. +// The context params should only include the ones that are being provided. +ProblemReporter reporter = new ProblemCollector.Collector(); +ValidationContext ctx = new ValidationContext(reporter, LootContextParamSets.ALL_PARAMS, provider); + +// Call the validator +validatable.validate(ctx); +``` + +This can also be appended to the end of codecs via `Codec#validate`: + +```java +public record ExampleObject() implements Validatable { + public static final Codec CODEC = MapCodec.unitCodec( + ExampleObject::new + ).validate( + // Supply the validator along with the context params to check against. + // This method does not have access to the registry provider. + Validatable.validatorForContext(LootContextParamSets.ALL_PARAMS) + ); + + @Override + public void validate(ValidationContext ctx) { + // ... + } +} +``` + +- `net.minecraft.advancements.CriterionTriggerInstance#validate` now takes in a `ValidationContextSource` instead of a `CriterionValidator` +- `net.minecraft.advancements.criterion` + - `ContextAwarePredicate` now implements `Validatable` + - `CriterionValidator` -> `ValidationContextSource` and `Validatable` + - `Validatable` contains the `validate*` methods + - `ValidationContextSource` holds the context and reporters +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect` now implements `Validatable` + - `conditionCodec` is replaced by calling `validate` after load + - `TargetedConditionalEffect` now implements `Validatable` +- `net.minecraft.world.level.storage.loot` + - `IntRange` now implements `LootContextUser` + - `getReferencedContextParams` replaced by `validate` + - `LootContext$VisitedEntry` generic must now extend `Validatable` + - `LootContextUser` now implements `Validatable` + - `LootDataType` generic must now extend `Validatable` + - The constructor now takes in a `$ContextGetter` instead of a `$Validator` + - `runValidation` now takes in the `ValidationContextSource` instead of a `ValidationContext` + - Also has an overload taking in a `HolderLookup` instead of a key-value pair + - `createSimpleValidator`, `createLootTableValidator`, `$Validator` replaced by `Validatable` + - `$ContextGetter` - Gets the `ContextKeySet` for some value. + - `LootPool` now implements `Validatable` + - `LootTable` now implements `Validatable` + - `Validatable` - An interface which handles the validation of its instance within the given context. + - `ValidationContext` + - `forField` - Creates a context for a given field. + - `forIndexedField` - Creates a context for a given entry in a list. + - `forMapField` - Creates a context for a given key in a map. + - `setContextKeySet` is removed + - `ValidationContextSource` - The source for the defined context where the validation is taking place. +- `net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer` now implements `Validatable` +- `net.minecraft.world.level.storage.loot.functions` + - `SetAttributesFunction$Modifier` now implements `LootContextUser` + - `SetStewEffectFunction$EffectEntry` now implements `LootContextUser` + +## Datapack Villager Trades + +Villager trades has now become a data-generated registry from its original map-based setup. While basic impressions make it seem like that system is more limited, it is actually just as extensible, though in a rather convoluted way because the trades are functionally a loot table itself to determine what `MerchantOffer`s a trader can provide. For the purposes of understanding, this section will go over the basics of the trade rewrite, along with how each previous item listing can be converted to a `VillagerTrade`. + +### Understanding the Trade Format + +All trades are expressed as `VillagerTrade`s, which at its core determines what a trader `wants` and what it `gives` in return. Each trade can also provide modifiers to the item itself or its cost, or whether the specific trade can be made at all with the given condition. Each trade also specifies the number of trades that can be made, how much xp to give, or the price multiple that is multiplied with the user's reputation. A `VillagerTrade` is then turned into a `MerchantOffer` via `getOffer`, taking in the `LootContext`, typically with a context param of `LootContextParamSets#VILLAGER_TRADE`, providing the trader itself (`THIS_ENTITY`) and its position (`ORIGIN`). + +The trades themselves are within `data//villager_trade/`. Typically the path contains the profession and level the trade is for, such as `examplemod:example_profession/1/example_trade` + +```json5 +// For some villager trade 'examplemod:example_profession/1/example_trade' +// JSON at 'data/examplemod/villager_trade/example_profession/1/example_trade.json' +{ + // The stack the trader wants. + "wants": { + // The item of the stack. + "id": "minecraft:apple", + // A number provider used to determine how much + // of the item that it wants. Once the count is + // determined, any additional cost on the `gives` + // stack (via `ADDITIONAL_TRADE_COST` component) + // is added to the count before being clamped to + // the max stack size. + // If not specified, defaults to 1. + "count": { + "type": "minecraft:uniform", + "min": 1, + "max": 5 + }, + // Any components that stack should have. The stack + // must have the exact components specified. + // If not specified, then no components will be + // checked, meaning that this is ignored. + "components": { + // Map of registry key to component value. + "minecraft:custom_name": "Apple...?" + } + }, + // An additional stack the trader wants. + // If not specified, the trader only checks `wants`. + "additional_wants": { + "id": "minecraft:emerald" + }, + // The stack template the trader gives in return. + "gives": { + // The item of the stack. + "id": "minecraft:golden_apple", + // A number [1, 99]. + // If not specified, defaults to 1. + "count": 1, + // The components to apply to the stack. + // If not specified, just applies the default + // item components. + "components": { + "minecraft:custom_name": "Not an Apple" + } + }, + // A number provider to determine how many times + // the trade can be performed by the player before + // the trader restocks. The value will always be at + // least 1. + // If not specified, defaults to 4. + "max_uses": { + "type": "minecraft:uniform", + "min": 1, + "max": 20 + }, + // A number provider to determine the price multiplier + // to apply to the cost of the item based on the player's + // reputation with the trader and the item demand, + // calculated from how many times the player has performed + // the trade. This should generally be a small number as + // the maximum reputation a user can have per trader is 150, + // though it's more likely to have a reputation of 25 at most. + // However, the trade must always have a minimum of one item, + // even if the reputation discount multiplied with the reputation + // indicates 100% or more off. + // If not specified, defaults to 0. + "reputation_discount": { + "type": "minecraft:uniform", + "min": 0, + "max": 0.05 + }, + // A number provider to determine the amount of experience + // the player obtains from performing the trade with the trader. + // This is typically around 5-30 xp for vanilla trades. + // If not specified, defaults to 1. + "xp": { + "type": "minecraft:uniform", + "min": 10, + "max": 20 + }, + // A loot item condition that determines whether the + // trader can provide the trade to the player. + // If not specified, defaults to always true. + "merchant_predicate": { + // This trade can only be performed by villagers + // from a desert or snow village. + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "predicates": { + "minecraft:villager/variant": [ + "minecraft:desert", + "minecraft:snow" + ] + } + } + }, + // A list of loot item functions that modify the item + // offered from `gives` to the player. + // If not specified, `gives` is not modified. + "given_item_modifiers": [ + { + // Chooses a random enchantment from the provided tag + "function": "minecraft:enchant_randomly", + // If this is true, the trade cost increases the + // number of `wants` items required. + "include_additional_cost_component": true, + "only_compatible": false, + "options": "#minecraft:trades/desert_common" + } + ], + // Can either be an enchantment id, such as "minecraft:protection", + // or a list of enchantment ids, such as ["minecraft:protection", "minecraft:smite", ...], + // or an enchantment tag, such as "#minecraft:trades/desert_common". + // When provided, if the `gives` item after modifiers contains an + // enchantment in this list, then the number of `wants` items required + // is multiplied by 2. + // If not specified, does nothing. + "double_trade_price_enchantments": "#minecraft:trades/desert_common" +} +``` + +### The Trades of a Trader + +Every trader can make many trades, typically choosing from a specified pool known as a `TradeSet`. Trade sets themselves are a separate datapack registry that consumes `VillagerTrade`s. Each set of trades determines how many trades can be offered and if the same trade can be chosen more than once. The trades that are offered are computed within `AbstractVillager#addOffersFromTradeSet`, first calling `TradeSet#calculateNumberOfTrades` to get the number of offers, and then using either `AbstractVillager#addOffersFromItemListings` or `AbstractVillager#addOffersFromItemListingsWithoutDuplicates` to choose the offers to use. + +Note that if duplicate trades are allowed, there is a potential race condition where if all trades' `merchant_predicate`s fail, then the offers will loop forever. This is because the method always assumes that there will be one trade that can be made. + +The trade sets are within `data//trade_set/`. Typically the path contains the profession and level the trade is for, such as `examplemod:example_profession/level_1.json` + +```json5 +// For some trade set 'examplemod:example_profession/level_1' +// JSON at 'data/examplemod/villager_trade/trade_set/level_1.json' +{ + // Can either be a villager trade id, such as "examplemod:example_profession/1/example_trade", + // or a list of trade ids, such as ["examplemod:example_profession/1/example_trade", "minecraft:farmer/1/wheat_emerald", ...], + // or an trade tag, such as "#examplemod:example_profession/level_1". + // This is the set of trades that can be offered by the trader. + // This should always be a villager trade tag so allow other users + // to easily add their own trades to a trader. + "trades": "#examplemod:example_profession/level_1", + // A number provider that determines the number of offers that can be + // made by the trader. + "amount": { + "type": "minecraft:uniform", + "min": 1, + "max": 5 + }, + // Whether the same trade can be used to make multiple offers. + // If not specified, defaults to false. + "allow_duplicates": true, + // An identifier that determines the unique random instance to + // user when determining the offers. + // If not specified, uses the level random. + "random_sequence": "examplemod:example_profession/level_1" +} +``` + +Where the villager trade tag could be: + +```json5 +// For some tag 'examplemod:example_profession/level_1' +// JSON at 'data/examplemod/tags/villager_trade/example_profession/level_1.json' +{ + "values": [ + "examplemod:example_profession/1/example_trade" + ] +} +``` + +This also means trades can be easily added to existing trade sets by adding to the associated tag: + +```json5 +// For some tag 'minecraft:farmer/level_1' +// JSON at 'data/minecraft/tags/villager_trade/farmer/level_1.json' +{ + "values": [ + "examplemod:example_profession/1/example_trade" + ] +} +``` + +Meanwhile, adding to a new `VillagerProfession` is done by mapping the level int to the trade set key in `tradeSetsByLevel`: + +```java +public static final VillagerProfession EXAMPLE = Registry.register( + BuiltInRegistries.VILLAGER_PROFESSION, + Identifier.fromNamespaceAndPath("examplemod", "example_profession"), + new VillagerProfession( + Component.literal(""), + p -> true, + p -> true, + ImmutableSet.of(), + ImmutableSet.of(), + null, + // A map of profession level to trade set keys + Int2ObjectMap.ofEntries( + Int2ObjectMap.entry( + // The profession level + 1, + // The trade set id + ResourceKey.create(Registries.TRADE_SET, Identifier.fromNamespaceAndPath("examplemod", "example_profession/level_1")) + ) + ) + ) +); +``` + +### Item Listing Conversions + +With all this in mind, we can now convert item listings to their new data-generated villager trades. + +#### Emeralds <-> Items + +For the following trades: + +```java +public static final VillagerTrades.ItemListing ITEM_TO_EMERALD = new VillagerTrades.EmeraldForItems( + // The item the trader wants. + Items.WHEAT, + // The number of items the trader wants. + 20, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 2, + // The number of emeralds given in return. + 1 +); + +public static final VillagerTrades.ItemListing EMERALD_TO_ITEM = new VillagerTrades.ItemsForEmeralds( + // The item the trader will give in return. + Items.BREAD, + // The number of emeralds the trader wants. + 1, + // The number of items the trader will give. + 6, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 1, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.05f +); +``` + +Their equivalent would be: + +```json5 +// For some villager trade 'examplemod:item_to_emerald' +// JSON at 'data/examplemod/villager_trade/item_to_emerald.json' +{ + "gives": { + // The number of emeralds given in return. + "count": 1, + "id": "minecraft:emerald" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + // `EmeraldForItems` hardcoded this to 0.05 + "reputation_discount": 0.05, + "wants": { + // The number of items the trader wants. + "count": 20, + // The item the trader wants. + "id": "minecraft:wheat" + }, + // The amount of experience given for the trade. + "xp": 2 +} + + +// For some villager trade 'examplemod:emerald_to_item' +// JSON at 'data/examplemod/villager_trade/emerald_to_item.json' +{ + "gives": { + // The number of items the trader will give. + "count": 6, + // The item the trader will give in return. + "id": "minecraft:bread" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + "id": "minecraft:emerald", + // The number of emeralds the trader wants. + "count": 1 + }, + // The amount of experience given for the trade. + "xp": 1 +} +``` + +#### Items and Emeralds -> Items + +For the following trade: + +```java +public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_ITEM = new VillagerTrades.ItemsAndEmeraldsToItems( + // The item the trader wants. + Items.COD, + // The number of items the trader wants. + 6, + // The number of emeralds the trader additionally wants. + 1, + // The item the trader will give in return. + Items.COOKED_COD, + // The number of items the trader will give. + 6, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 1, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.05f +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:item_emerald_to_item' +// JSON at 'data/examplemod/villager_trade/item_emerald_to_item.json' +{ + // The emeralds the trader additionally wants. + "additional_wants": { + "id": "minecraft:emerald", + }, + "gives": { + // The number of items the trader will give. + "count": 6, + // The item the trader will give in return. + "id": "minecraft:cooked_cod" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + // The number of items the trader wants. + "count": 6, + // The item the trader wants. + "id": "minecraft:cod" + }, + // The amount of experience given for the trade. + "xp": 1 +} +``` + +#### Emeralds -> Dyed Armor + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_DYED_ARMOR = new VillagerTrades.DyedArmorForEmeralds( + // The item the trader will give in return and dye. + Items.LEATHER_HELMET, + // The number of emeralds the trader wants. + 5, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 5 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_dyed_armor' +// JSON at 'data/examplemod/villager_trade/emerald_to_dyed_armor.json' +{ + "given_item_modifiers": [ + { + // Sets the random dye(s) on the armor. + "function": "minecraft:set_random_dyes", + "number_of_dyes": { + "type": "minecraft:sum", + "summands": [ + 1.0, + { + "type": "minecraft:binomial", + "n": 2.0, + "p": 0.75 + } + ] + } + }, + { + // Checks that the dye was successfully applied + // to the item. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:leather_helmet", + "predicates": { + "minecraft:dyed_color": {} + } + }, + // If it fails, discards the offer. + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // The item the trader will give in return and dye. + "id": "minecraft:leather_helmet" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 5, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 5 +} +``` + +#### Emeralds -> Enchanted Item + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_BOOK = new VillagerTrades.EnchantBookForEmeralds( + // The amount of experience given for the trade. + 30, + // The minimum level used when selecting the stored enchantments on the book. + 3, + // The maximum level used when selecting the stored enchantments on the book. + 3, + // A tag containing the list of available enchantments to select from for the book. + EnchantmentTags.TRADES_DESERT_SPECIAL +); + +public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_ITEM = new VillagerTrades.EnchantedItemForEmeralds( + // The item the trader will give in return and try to enchant. + Items.FISHING_ROD, + // The base number of emeralds the trader wants. + 3, + // The maximum number of times the trade can be made + // before restock. + 3, + // The amount of experience given for the trade. + 10, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.2f +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_enchanted_book' +// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_book.json' +{ + // The trader expects a book to write the enchantment to. + "additional_wants": { + "id": "minecraft:book" + }, + // Trade cost for emeralds increased when in the double trade price + // tag. + "double_trade_price_enchantments": "#minecraft:double_trade_price", + "given_item_modifiers": [ + { + "function": "minecraft:enchant_with_levels", + "include_additional_cost_component": true, + "levels": { + "type": "minecraft:uniform", + // The minimum level used when selecting the stored enchantments on the book. + "min": 3, + // The maximum level used when selecting the stored enchantments on the book. + "max": 3 + }, + // The list of available enchantments to select from for the book. + "options": [ + "minecraft:efficiency" + ] + }, + { + // Make sure the enchantment was added successfully with the given level. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:enchanted_book", + "predicates": { + "minecraft:stored_enchantments": [ + { + "levels": { + // The minimum level used when selecting the stored enchantments on the book. + "min": 3, + // The maximum level used when selecting the stored enchantments on the book. + "max": 3 + } + } + ] + } + }, + // Discard on failure + "on_fail": { + "function": "minecraft:discard" + } + } + ], + // The trader gives the enchanted book. + "gives": { + "count": 1, + "id": "minecraft:enchanted_book" + }, + // The maximum number of times the trade can be made + // before restock was hardcoded to 12. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.2. + "reputation_discount": 0.2, + "wants": { + "count": { + "type": "minecraft:sum", + "summands": [ + // A hardcoded computation based on the min and max + // level of the enchantment. + 11.0, + { + "type": "minecraft:uniform", + "max": 35.0, + "min": 0.0 + } + ] + }, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 30 +} + +// For some villager trade 'examplemod:emerald_to_enchanted_item' +// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_item.json' +{ + "given_item_modifiers": [ + { + // Applies the enchantment to the given equipment. + "function": "minecraft:enchant_with_levels", + "include_additional_cost_component": true, + "levels": { + "type": "minecraft:uniform", + "max": 20, + "min": 5 + }, + "options": "#minecraft:on_traded_equipment" + }, + { + // Checks to make sure the enchantment was applied. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:fishing_rod", + "predicates": { + "minecraft:enchantments": [ + {} + ] + } + }, + // On fail, give nothing. + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // The item the trader will give in return and try to enchant. + "id": "minecraft:fishing_rod" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 3, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.2, + "wants": { + "count": { + "type": "minecraft:sum", + "summands": [ + // The base number of emeralds the trader wants. + 3, + { + // The variation based on the enchantment level. + // Originally, this would be the value used in the + // item function, but since they are now isolated, + // these values could differ. + "type": "minecraft:uniform", + "max": 20, + "min": 5 + } + ] + }, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 10 +} +``` + +#### Items and Emeralds -> Potion Effect Item + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_SUSPICIOUS_STEW = new VillagerTrades.SuspiciousStewForEmerald( + // The effect applied by the suspicious stew. + MobEffects.NIGHT_VISION, + // The number of ticks the effect should be active for. + 100, + // The amount of experience given for the trade. + 15 +); + +public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_TIPPED_ARROW = new VillagerTrades.TippedArrowForItemsAndEmeralds( + // The item the trader additionally wants. + Items.ARROW, + // The number of items the trader additionally wants. + 5, + // The item the trader will give in return. + Items.TIPPED_ARROW, + // The number of items the trader will give. + 5, + // The number of emeralds the trader wants. + 2, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 30 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_suspicious_stew' +// JSON at 'data/examplemod/villager_trade/emerald_to_suspicious_stew.json' +{ + "given_item_modifiers": [ + { + "effects": [ + { + // The effect applied by the suspicious stew. + "type": "minecraft:night_vision", + // The number of ticks the effect should be active for. + "duration": 100 + } + // Vanilla merges all suspicious stew offers + // into one since this function picks one + // stew effect at random. + ], + "function": "minecraft:set_stew_effect" + } + ], + "gives": { + "count": 1, + "id": "minecraft:suspicious_stew" + }, + // The maximum number of times the trade can be made + // before restock, hardcoded to 12. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 15 +} + +// For some villager trade 'examplemod:item_emerald_to_tipped_arrow' +// JSON at 'data/examplemod/villager_trade/item_emerald_to_tipped_arrow.json' +{ + "additional_wants": { + // The number of items the trader additionally wants. + "count": 5, + // The item the trader additionally wants. + "id": "minecraft:arrow" + }, + "given_item_modifiers": [ + { + // Applies a random potion effect from the tradable potions. + // Original implementation just picked any potion at random. + "function": "minecraft:set_random_potion", + "options": "#minecraft:tradeable" + } + ], + "gives": { + // The number of items the trader will give. + "count": 5, + // The item the trader will give in return. + "id": "minecraft:tipped_arrow" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 2, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 30 +} +``` + +#### Emeralds -> Treasure Map + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_TREASURE_MAP = new VillagerTrades.TreasureMapForEmeralds( + // The number of emeralds the trader wants. + 8, + // A tag containing a list of treasure structures to find the nearest of. + StructureTags.ON_TAIGA_VILLAGE_MAPS, + // The translation key of the map name. + "filled_map.village_taiga", + // The icon used to decorate the treasure location found on the map. + MapDecorationTypes.TAIGA_VILLAGE, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 5 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_treasure_map' +// JSON at 'data/examplemod/villager_trade/emerald_to_treasure_map.json' +{ + "additional_wants": { + // An item the trader additionally wants, hardcoded to compass. + "id": "minecraft:compass" + }, + "given_item_modifiers": [ + { + // Finds a treasure structure to display on the map. + + // The icon used to decorate the treasure location found on the map. + "decoration": "minecraft:village_taiga", + // A tag containing a list of treasure structures to find the nearest of. + "destination": "minecraft:on_taiga_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + // Sets the name of the map. + + "function": "minecraft:set_name", + "name": { + // The translation key of the map name. + "translate": "filled_map.village_taiga" + }, + "target": "item_name" + }, + { + // Check to make sure a structure was found. + + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:filled_map", + "predicates": { + "minecraft:map_id": {} + } + }, + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // Returns a map filled with the treasure location. + "id": "minecraft:map" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 8, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 5 +} +``` + +#### Villager Variants + +Some traders would provide different options depending on the villager type it was as one giant map of item listings. Now, each type has its own individual villager trade, using a `merchant_predicate` to check whether the offer can be made to the specific villager type: + +```json5 +// For some villager trade 'examplemod:villager_type_item' +// JSON at 'data/examplemod/villager_trade/villager_type_item.json' +{ + // ... + "merchant_predicate": { + // Check the entity. + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "predicates": { + // Villager type must be desert for this trade to be chosen. + "minecraft:villager/variant": "minecraft:desert" + } + } + }, + // ... +} +``` + +- `net.minecraft.core.registries.Registries` + - `TRADE_SET` - A key to the registry holding a list of trades. + - `VILLAGER_TRADE` - A key to the registry holding a single trade. +- `net.minecraft.tags.VillagerTradeTags` - Tags for villager trades. +- `net.minecraft.world.entity.npc.villager` + - `AbstractVillager#addOffersFromItemListings` -> `addOffersFromTradeSet`, taking in a key for the trade set rather than the `$ItemListing`s and number of offers; not one-to-one + - `VillagerProfession` now takes in a map of trader level to `TradeSet` + - `getTrades` - Returns the trades set key for the given level. + - `VillagerTrades` has been split into many different classes and implementations + - `TRADES`, `EXPERIMENTAL_TRADES`, `WANDERING_TRADER_TRADES` is now represented by the `VillagerProfession#tradeSetsByLevel` + - As they are now datapack entries, they are stored in their respective datapacks + - `TRADES`, `EXPERIMENTAL_TRADES` are represented by `data/minecraft/trade_set//*` + - `WANDERING_TRADER_TRADES` are represented by `data/minecraft/trade_set/wandering_trader/*` + - `$DyedArmorForEmeralds` -> `VillagerTrades#dyedItem`, `addRandomDye`; not one-to-one + - `$EmeraldForItems` -> `VillagerTrade`, not one-to-one + - `$EmeraldsForVillagerTypeItem` -> `VillagerTrades#registerBoatTrades`, see usage, not one-to-one + - `$EnchantBookForEmeralds` -> `VillagerTrades#enchantedBook`, not one-to-one + - `$EnchantedItemForEmeralds` -> `VillagerTrades#enchantedItem`, not one-to-one + - `$ItemListing` -> `VillagerTrade` + - `$ItemsAndEmeraldsToItems` -> `VillagerTrade` with `additionalWants` + - `$ItemsForEmeralds` -> `VillagerTrade`, not one-to-one + - `$SuspiciousStewForEmerald` -> `VillagerTrade` with `SetStewEffectFunction` + - `$TippedArrowForItemsAndEmeralds` -> `VillagerTrade` with `SetRandomPotionFunction` + - `$TreasureMapForEmeralds` -> `VillagerTrades$VillagerExplorerMapEntry`, see usage, not one-to-one + - `$TypeSpecificTrade` -> `VillagerTrades#villagerTypeRestriction`, `villagerTypeHolderSet`; not one-to-one +- `net.minecraft.world.item.enchantment.providers.TradeRebalanceEnchantmentProviders` interface is removed + - Replaced by `TradeRebalanceVillagerTrades`, `TradeRebalanceRegistries` +- `net.minecraft.world.item.trading` + - `TradeCost` - An `ItemStack` that is being traded to some trader. + - `TradeRebalanceVillagerTrades` - All trades part of the trade rebalance datapack. + - `TradeSet` - A set of trades that can be performed by a trader at some level. + - `TradeSets` - All vanilla trades sets for some trader at some level. + - `VillagerTrade` - A trade between the trader and the player. + - `VillagerTrades` - All vanilla trades. +- `net.minecraft.world.level.storage.loot.parameters.LootContextParamSets#VILLAGER_TRADE` - A loot context when a villager trade is taking place, containing the trade origin and the trading entity. + +## `Level#random` field now protected + +The `Level#random` field is now `protected` instead of `public`. As such, uses should transition to using the public `getRandom` method. + +```java +// For some Level level +RandomSource random = level.getRandom(); +``` + +- `net.minecraft.world.level.Level#random` field is now `protected` instead of `public` + - Use `getRandom` method instead + +## Data Component Initializers + +Data components have begun their transition from being moved off the raw object and onto the `Holder` itself. This is to properly handle objects that are not available during construction, such as datapack registry objects for items. Currently, this is only implemented for `Item`s, but the system allows for any registry object, given its wrapped-holder, to store some defined data components. + +Data components are attached to their holders through the `DataComponentInitializers`. During object construction, `DataComponentInitializers#add` is called, providing the `ResourceKey` identifier of the registry object, along with a `DataComponentInitializers$Initializer`. The initializer takes in three parameters: the builder for the component map, the full registries `HolderLookup$Provider`, and the key passed to `DataComponentInitializers#add`. The initializer functions like a consumer, also allowing for additional initializers to be chained via `$Initializer#andThen` or to easily add a component via `$Initializer#add`. + +```java +// For some custom registry object +public ExampleObject(ResourceKey id) { + // Register the data component initializer + BuiltInRegistries.DATA_COMPONENT_INITIALIZERS.add( + // The identifier for the registry object + id, + // The initializer function, taking in a component builder, + // the registries context, and the id + (components, context, key) -> components + .set(DataComponents.MAX_DAMAGE, 1) + .set(DataComponents.DAMAGE_TYPE, context.getOrThrow(DamageTypes.SPEAR)) + ); +} +``` + +From there, the data components are initialized or reinitialized whenever `ReloadableServerResources#loadResources` is called (on datapack reload). The datapack objects are loaded first, then the components are set on the `Holder$Reference`s. From there, the components can be gathered via `Holder#components`. + +```java +// For some Holder EXAMPLE_HOLDER +DataComponentMap components = EXAMPLE_HOLDER.components(); +``` + +### Items + +Since components are now initialized during resource reload, `Item$Properties` provides two methods to properly delay component initialization until such data components are loaded: `delayedComponent` and `delayedHolderComponent`. `delayedComponent` takes in the component type and a function that takes in the `HolderLookup$Provider` and returns the component value. `delayedHolderCOmponent` delegates to `delayedComponent`, taking in a `ResourceKey` and setting the registry object as the component value. + +```java +public static final Item EXAMPLE_ITEM = new Item( + new Item.Properties() + .delayedComponent( + // The component type whose construction + // should be lazily initialized. + DataComponents.JUKEBOX_PLAYABLE, + // A function that takes in the registries + // and returns the component value. + context -> new JukeboxPlayable(context.getOrThrow( + JukeboxSongs.THIRTEEN + )) + ) + .delayedHolderComponent( + // The component type which has a + // holder value type. + DataComponents.DAMAGE_TYPE + // The resource key for a registry + // object of the associated holder + // generic type. + DamageTypes.SPEAR + ) + // ... +); +``` + +### Recipes + +Since data components now hold the true values from being lazily initialized after resource reload, `Recipe#assemble` no longer takes in the `HolderLookup$Provider`. Instead, it assumes that the recipe has all the required data stored passed into the recipe, either on a stack or directly. + +- `net.minecraft.core` + - `Holder` + - `areComponentsBound` - Whether the components have been bound to the holder. + - `components` - The components of the object stored on the holder. + - `direct`, `$Direct` now can take in the `DataComponentMap` + - `$Reference#bindComponents` - Stores the components on the holder reference. + - `Registry#componentLookup` - Gets the lookup of component to holders. + - `WritableRegistry#bindTag` -> `bindTags`, now taking in a map of keys to holder lists instead of one mapping +- `net.minecraft.core.component` + - `DataComponentInitializers` - A class that handles initializing the data components for component-attached objects. + - `DataComponentLookup` - A lookup that maps the component type to the holders that use it. + - `DataComponentMap$Builder#addValidator` - Adds a validator for the components on the object. + - `DataComponentPatch` + - `get` now takes in a `DataComponentGetter` and returns the raw component value + - `$Builder#set` now has an overload that takes in an iterable of `TypedDataComponent`s + - `DataComponents` + - `DAMAGE_TYPE` now is a holder-wrapped `DamageType` instead of `EitherHolder`-wrapped + - `PROVIDES_TRIM_MATERIAL` now is a holder-wrapped `TrimMaterial` instead of `ProvidesTrimMaterial` + - `CHICKEN_VARIANT` now is a holder-wrapped `ChickenVariant` instead of `EitherHolder`-wrapped + - `ZOMBIE_NAUTILUS_VARIANT` now is a holder-wrapped `ZombieNautilusVariant` instead of `EitherHolder`-wrapped + - `PROVIDES_BANNER_PATTERNS` is now a `HolderSet` instead of a `TagKey` +- `net.minecraft.core.registries` + - `BuiltInRegistries#DATA_COMPONENT_INITIALIZERS` - A list of data components attached to registry entries. + - `Registries#componentsDirPath` - The path directory for the components in a registry. +- `net.minecraft.data.PackOutput#createRegistryComponentPathProvider` - The path provider for the components registry report. +- `net.minecraft.data.info.ItemListReport` -> `RegistryComponentsReport`, not one-to-one +- `net.minecraft.resources` + - `NetworkRegistryLoadTask` - A load task that handles registering registry objects and tags from the network, or else from a resource. + - `RegistryDataLoader` + - `$PendingRegistration` -> `RegistryLoadTask$PendingRegistration` + - `$RegistryData` now takes in a `RegistryValidator` instead of a `boolean` + - `$RegistryLoadTask` -> `RegistryLoadTask`, not one-to-one + - `RegistryValidator` - An interface that validates the entries in a registry, storing all errors in a map. + - `ResourceManagerRegistryLoadTask` - A load task that handles registering registry objects and tags from the local resource manager. +- `net.minecraft.server.ReloadableServerResources#updateStaticRegistryTags` -> `updateComponentsAndStaticRegistryTags`, not one-to-one +- `net.minecraft.world.item` + - `EitherHolder` class is removed + - `Item` + - `CODEC_WITH_BOUND_COMPONENTS` - An item codec that validates that the components are bound. + - `$Properties` + - `delayedComponent` - Sets the component lazily, providing the `HolderLookup$Provider` to get any dynamic elements. + - `delayedHolderComponent` - Sets the component lazily for some holder-wrapped registry object. + - `ItemStack#validateComponents` is now `private` from `public` + - `JukeboxPlayable` now holds a holder-wrapped `JukeboxSong` instead of an `EitherHolder`-wrapped variant + - `JukeboxSong#fromStack` no longer takes in the `HolderLookup$Provider` + - `SpawnEggItem` + - `spawnEntity` is now `static` + - `byId` now returns an optional holder-wrapped `Item` instead of a `SpawnEggItem` + - `eggs` is removed + - `getType` is now `static` + - `spawnOffspringFromSpawnEgg` is now `static` +- `net.minecraft.world.item.component` + - `BlocksAttacks` now holds an optional holder set-wrapped `DamageType` instead of a `TagKey` + - `DamageResistant` now holds a holder set `DamageType` instead of a `TagKey` + - `InstrumentComponent` now holds a holder-wrapped `Instrument` instead of an `EitherHolder`-wrapped variant + - `unwrap` is removed + - `ProvidesTrimMaterial` now holds a holder-wrapped `TrimMaterial` instead of an `EitherHolder`-wrapped variant +- `net.minecraft.world.item.crafting` + - `Recipe#assemble` no longer takes in the `HolderLookup$Provider` + - `SmithingTrimRecipe#applyTrim` no longer takes in the `HolderLookup$Provider` +- `net.minecraft.world.item.equipment.trim.TrimMaterials#getFromIngredient` is removed +- `net.minecraft.world.level.storage.loot.functions.SetInstrumentFunction`, `#setInstrumentOptions` now takes in a holder set-wrapped `Instrument` instead of a `TagKey` +- `net.minecraft.world.timeline.Timeline#validateRegistry` - Validates that each time marker was only defined once. + +## Item Instances and Stack Templates + +`ItemStack`s now have an immutable instance known as an `ItemStackTemplate`. Similar to the `ItemStack`, it contains the holder-wrapped `Item`, the number of items it represents, and a `DataComponentPatch` of the components to apply to the stack. The template can be transformed to a stack via `create`, or `apply` if adding additional data components. An `ItemStack` can likewise be turned into a template via `ItemStackTemplate#fromNonEmptyStack`. Templates are now used in place of `ItemStack`s were immutability is required (e.g., advancements, recipes, etc.). They provide a regular `CODEC`, a `MAP_CODEC`, and a `STREAM_CODEC` for network communication. + +```java +ItemStackTemplate apple = new ItemStackTemplate( + // The item of the stack + Items.APPLE.builtInRegistryHolder(), + // The number of items held + 5, + // The components applied to the stack + DataComponentPatch.builder() + .set(DataComponents.ITEM_NAME, Component.literal("Apple?")) + .build() +); + +// Turn the template into a stack +ItemStack stack = apple.create(); + +// Creating a template from a non-empty stack +ItemStackTemplate fromStack = ItemStackTemplate.fromNonEmptyStack(stack); +``` + +To help standardize accessing the general components between the two, both the template and the stack implement `ItemInstance`, which provides access to the standard holder method checks, the count, and the `DataComponentGetter`. The common interface also means that if it doesn't matter whether the stack is mutable or not, then the `ItemInstance` can be used as the type. + +```java +// Both are item instances +ItemInstance stack = new ItemStack(Items.APPLE); +ItemInstance template = new ItemStackTemplate(Items.APPLE); + +// Get the holder or check something +Holder item = stack.typeHolder(); +template.is(Items.APPLE); + +// Get the number of items in the stack or template +int stackCount = stack.count(); +int templateCount = template.count(); + +// Get the component values +Identifier stackModel = stack.get(DataComponents.ITEM_MODEL); +Identifier templateModel = template.get(DataComponents.ITEM_MODEL); +``` + +### Recipe Builders + +Due to the addition of `ItemStackTemplate`s, `RecipeBuilder`s have changed slightly in their implementation. First, the builder no longer stores an `Item` for the result, instead defining the `defaultId` as the resource key recipe. As such, this allows for a more clear method of defining custom recipes that do not export an `Item`. + +Of course, the change to this new format just has `defaultId` return `RecipeBuilder#getDefaultRecipeId` with the `ItemInstance` (either a stack or template), like so: + +```java +public class ExampleRecipeBuilder implements RecipeBuilder { + + // The result of the recipe + private final ItemStackTemplate result; + + public ExampleRecipeBuilder(ItemStackTemplate result) { + this.result = result; + } + + @Override + public ResourceKey> defaultId() { + // Get the default recipe id from the result + return RecipeBuilder.getDefaultRecipeId(this.result); + } + + // Implement everything else below + // ... +} +``` + +- `net.minecraft.advancements` + - `Advancement$Builder#display` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `DisplayInfo` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `getIcon` now returns an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.advancements.criterion` + - `AnyBlockInteractionTrigger#trigger` now takes in an `ItemInstance` instead of an `ItemStack` + - `ItemPredicate` now implements a predicate of `ItemInstance` instead of `ItemStack` + - `ItemUsedOnLocationTrigger#trigger` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.client.particle.BreakingItemParticle$ItemParticleProvider#getSprite` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.commands.arguments.item` + - `ItemInput` is now a record + - `serialize` is removed + - `createItemStack` no longer takes in the `boolean` to check the size + - `ItemParser#parse` now returns an `ItemResult` instead of an `ItemParser$ItemResult` + - `$ItemResult` merged into `ItemInput` +- `net.minecraft.core.component.predicates` + - `BundlePredicate` now deals with an iterable of `ItemInstance`s rather than `ItemStack`s + - `ContainerPredicate` now deals with an iterable of `ItemInstance`s rather than `ItemStack`s +- `net.minecraft.core.particles.ItemParticleOption` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - There is also an overload for a regular `Item` + - `getItem` now returns an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.data.recipes` + - `RecipeBuilder` + - `getResult` is removed + - `defaultId` - The default identifiers for the recipe made with this builder. + - `getDefaultRecipeId` now takes in an `ItemInstance` instead of an `ItemLike` + - `RecipeProvider` + - `oreSmelting`, `oreBlasting` now take in a `CookingBookCategory` + - `oreCooking` no longer takes in the `RecipeSerializer` and now takes in a `CookingBookCategory` + - `cookRecipes`, `simpleCookingRecipe` no longer take in the `RecipeSerializer` + - `shapeless` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `ShapedRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - Both constructors are `private` + - `ShapelessRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of an `ItemStack` + - `SimpleCookingRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - `generic` no longer takes in the `RecipeSerializer` and now takes in a `CookingBookCategory` + - `blasting`, `smelting` now take in a `CookingBookCategory` + - `SingleItemRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - The `ItemStackTemplate` constructor is made `private` + - `SmithingTransformRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of an `Item` + - `TransmuteRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of a `Holder` + - The constructor is `private` + - `transmute` now has an overload that takes in the `ItemStackTemplate` for the result + - `addMaterialCountToOutput`, `setMaterialCount` - Handles the size of the result stack based on the number of materials used. +- `net.minecraft.network.chat.HoverEvent$ShowItem` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.server.dialog.body.ItemBody` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.entity.LivingEntity` + - `dropFromEntityInteractLootTable` now takes in an `ItemInstance` instead of an `ItemStack` for the tool + - `dropFromShearingLootTable` now takes in an `ItemInstance` instead of an `ItemStack` for the tool +- `net.minecraft.world.item` + - `BundleItem#getSelectedItemStack` -> `getSelectedItem`, now returning an `ItemStackTemplate` instead of an `ItemStack` + - `Item` + - `getCraftingRemainder` now returns an `ItemStackTemplate` instead of an `ItemStack` + - `$Properties#craftRemainder` now has an overload that takes in the `ItemStackTemplate` + - `ItemInstance` - A typed item instance that can query the item, the size, and its components. + - `ItemStack` now implements `ItemInstance` + - `SINGLE_ITEM_CODEC`, `STRICT_CODEC`, `STRING_SINGLE_ITEM_CODEC`, `SIMPLE_ITEM_CODEC` are removed + - `getMaxStackSize` -> `ItemInstance#getMaxStackSize` + - `ItemStackTemplate` - A record containing the immutable components of a stack: the item, count, and components. +- `net.minecraft.world.item.component` + - `BundleContents` now takes in a list of `ItemStackTemplate`s instead of `ItemStack`s + - `items` now returns a list of `ItemStackTemplate`s instead of an iterable of `ItemStack`s + - `itemsCopy` is removed + - `getSelectedItem` - Returns the stack template of the selected item, or `null` if no item is selected. + - `ChargedProjectile` is now a record + - The constructor takes in a list of `ItemStackTemplate`s instead of `ItemStack`s + - `of` -> `ofNonEmpty` + - `getItems` -> `itemCopies` + - `ItemContainerContents` + - `stream` -> `allItemsCopyStream` + - `nonEmptyStream` -> `nonEmptyItemCopyStream` + - `nonEmptyItems`, `nonEmptyItemsCopy` -> `nonEmptyItems`, now returning an iterable of `ItemStackTemplate`s instead of `ItemStack`s + - `UseRemainder` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `$Factory#create` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `BlastingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `CampfireCookingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `ShapedRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `ShapelessRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SingleItemRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `result` now returns an `ItemStackTemplate` instead of an `ItemStack` + - `$Factory#create` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmeltingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmithingTransformRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmokingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `StonecutterRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `TransmuteRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `TransmuteResult` -> `ItemStackTemplate`, not one-to-one + - `isResultUnchanged` is removed + - `apply` -> `TransmuteRecipe#createWithOriginalComponents`, not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay$ItemStackSlotDisplay` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.item.enchantment.EnchantmentHelper#getItemEnchantmentLevel` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.world.level.block.Block` + - `dropFromBlockInteractLootTable` now takes in an `ItemInstance` instead of an `ItemStack` + - `getDrops` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.world.level.block.entity.DecoratedPotBlockEntity#createdDecoratedPotItem` -> `createdDecoratedPotInstance` + - `createDecoratedPotTemplate` creates the `ItemStackTemplate` instead of the `ItemStack` +- `net.minecraft.world.level.storage.loot` + - `LootContext$ItemStackTarget` now implements an `ItemInstance` generic for the argument getter instead of the `ItemStack` + - `LootContextArg$ArgCodecBuilder#anyItemStack` now requires a function taking in an `ItemInstance` context key instead of an `ItemStack` context key +- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#TOOL` is now an `ItemInstance` context key instead of an `ItemStack` context key + +## Serializer Records and Recipe Info + +Recipes have been slightly reworked in their implementation. First, `RecipeSerializer` is now a record taking in the `MapCodec` and `StreamCodec` used to serialize and deserialize the recipe. As such, `Serializer` classes have been removed in their entirety, replaced with providing the codecs to the record during registration: + +```java +// Assume some ExampleRecipe implements Recipe +// We'll say there's also only one INSTANCE +public static final RecipeSerializer EXAMPLE_RECIPE = new RecipeSerializer<>( + // The map codec for reading the recipe to/from disk. + MapCodec.unit(INSTANCE), + // The stream codec for reading the recipe to/from the network. + StreamCodec.unit(INSTANCE) +); +``` + +Second, some common data regarding the recipe settings and book information have been sectioned into separate objects. These objects are passed into the recipe as part of the constructor and used to more cleanly handle similar implementations across all recipes. + +Vanilla provides four of these common object classes, split into two separate categories. `Recipe$CommonInfo` is used for general recipe settings. Meanwhile, `Recipe$BookInfo` is used for recipe book information, with `CraftingRecipe$CraftingBookInfo` for crafting recipes, and `AbstractCookingRecipe$CookingBookInfo` for cooking recipes (e.g., smelting, blasting, etc.). The common object classes provide methods for constructing the codecs as required, which can then be passed into the relevant recipe codec. + +These classes are typically passed through the `Recipe` subclasses, used as boilerplate to implement abstract methods. None of the data in these objects are directly available outside the implementation itself, only through the methods defined in the `Recipe` interface. Because of this, classes like `NormalCraftingRecipe`, `CustomRecipe`, `SimpleSmithingRecipe`, and `SingleItemRecipe`, and `AbstractCookingRecipe` can be used to create a new recipe implementation by implementing a few methods. + +Note that these common info classes are a design philosophy, which you can choose to implement if desired. It's only when building off existing recipe subtypes that you are required to make use of them. + +- `net.minecraft.data.recipes` + - `CustomCraftingRecipeBuilder` - A recipe builder that creates an arbitrary crafting recipe from some common and crafting book information. + - `RecipeBuilder` + - `determineBookCategory` -> `determineCraftingBookCategory` + - `createCraftingCommonInfo` - Creates the common recipe info. + - `createCraftingBookInfo` - Creates the crafting book info. + - `RecipeUnlockAdvancementBuilder` - An advancement builder for unlocking a recipe. + - `SpecialRecipeBuilder`, `special` now takes in a supplied `Recipe` instead of a function of `CraftingBookCategory` to `Recipe` + - `unlockedBy` - The criteria required to unlock the recipe advancement. +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now takes in the `Recipe$CommonInfo` and `$CookingBookInfo` instead of the group and `CookingBookCategory` + - `$Factory#create` now takes in the `Recipe$CommonInfo` and `$CookingBookInfo` instead of the group and `CookingBookCategory` + - `$Serializer` replaced by `cookingMapCodec`, `cookingStreamCodec` + - `$CookingBookInfo` - A record containing the common cooking information for the recipe book. + - `BannerDuplicateRecipe` now takes in the banner `Ingredient` and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `BlastingRecipe` now takes in the `Recipe$CommonInfo` and `$AbstractCookingRecipeCookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `BookCloningRecipe` now takes in the `Ingredient` source and material, the `MinMaxBounds$Int`s defining the generations that can be copied, and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `ALLOWED_BOOK_GENERATION_RANGES`, `DEFAULT_BOOK_GENERATION_RANGES` - Ranges for the book generation cloning. + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `CampfireCookingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `CraftingRecipe$CraftingBookInfo` - A record containing the common crafting information for the recipe book. + - `CustomRecipe` no longer takes in anything to its constructor + - `$Serializer` is removed, replaced by its implementation's codecs + - `DecoratedPotRecipe` now takes in the `Ingredient` patterns for each side along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `DyeRecipe` now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `Ingredient` target and dye and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkRocketRecipe` now takes in the `Ingredient` shell, fuel, and star along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkStarFadeRecipe` now takes in the `Ingredient` target and dye along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkStarRecipe` now takes in the `$Shape` to `Ingredient` map; the `Ingredient` trail, twinkle, fuel, and dye; along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `MapCloningRecipe` replaced with `TransmuteRecipe` + - `MapExtendingRecipe` now extends `CustomRecipe` instead of `ShapedRecipe` + - The constructor now takes in the `Ingredient` map and material along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `NormalCraftingRecipe` - A class that defines the standard implementation for a crafting recipe. + - `Recipe` + - `showNotification`, `group` are no longer default + - `$BookInfo` - The information for the recipe book. + - `$CommonInfo` - The common information across all recipes. + - `RecipeSerializer` is now a record containing the `MapCodec` and `StreamCodec` + - The registered entries have been moved to `RecipeSerializers` + - `register` is removed + - `RecipeSerializers` - All vanilla serializers for recipes. + - `RepairItemRecipe` no longer takes in anything + - `INSTANCE` - The recipe serializer singleton. + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `ShapedRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `ShapelessRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `ShieldDecorationRecipe` now takes in the `Ingredient` banner and target along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `SimpleSmithingRecipe` - A class that defines the standard implementation of a smithing recipe. + - `SingleItemRecipe` now takes in the `Recipe$CommonInfo` instead of the group + - `commonInfo` - The common information for the recipe. + - `$Factory#create` now takes in the `Recipe$CommonInfo` instead of the group + - `$Serializer` -> `simpleMapCodec`, `simpleStreamCodec`; not one-to-one + - `SmeltingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `SmithingTransformRecipe` now extends `SimpleSmithingRecipe` instead of implementing `SmithingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `SmithingTrimRecipe` now extends `SimpleSmithingRecipe` instead of implementing `SmithingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `SmokingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `StonecutterRecipe` now takes in the `Recipe$CommonInfo` instead of the group + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `TippedArrowRecipe` -> `ImbueRecipe`, not one-to-one + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `Ingredient` source and material and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `TransmuteRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `MinMaxBounds$Ints` and `boolean` handling the material count and adding it to the result instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay` + - `$OnlyWithComponent` - A display only with the contents having the desired components. + - `$WithAnyPotion` - A display with the contents having any potion contents component. +- `net.minecraft.world.level.storage.loot.functions.SmeltItemFunction#smelted` now can take in whether to use the input material count + +## Dye Component + +Specifying whether an item can be used as a dye material is now handled through the `DYE` data component. The component specifies a `DyeColor`, which can be set via `Item$Properties#component`: + +```java +public static final Item EXAMPLE_DYE = new Item(new Item.Properties().component( + DataComponents.DYE, DyeColor.WHITE +)); +``` + +However, a dye material's behavior is not fully encompassed by the component alone. In most cases, the component is used in conjunction with some other tag or subclass to get the desired behavior. + +### Entities and Signs + +Dying sheeps and signs are handled purely through the `DyeItem` subclass, checking if the item has the `DYE` component. + +Dying the collars of wolfs and cats, on the other hand, can be any item, assuming it has the `DYE` component. Additionally, the item must be in the `ItemTags#WOLF_COLLAR_DYES` or `ItemTags#CAT_COLLAR_DYES` tag, respectively. + +### Dye Recipes + +The `DyeRecipe`, formerly named `ArmorDyeRecipe`, can take any target ingredient and apply the colors of the dye ingredients to obtain the desired result with the associated `DYED_COLOR` component. Any item can be considered a dye; however, those without the `DYE` component will default to `DyeColor#WHITE`. Armor makes used of `RecipeProvider#dyedItem` to allow any item in the `ItemTags#DYES` tag to dye armor. However, bundles and shulker boxes have their color components as different items, meaning instead the default recipes are tied directly to the vanilla `DyeItem`, meaning a separate recipe will need to be generated for applying dyes to those items. + +The loom, firework star, and firework star face recipes on the other hand expect any dye material to have the `DYE` component. The loom has an additional requirement of the item being in the `ItemTags#LOOM_DYES` tag. + +- `net.minecraft.core.component.DataComponents#DYE` - Represents that an item can act as a dye for the specific color. +- `net.minecraft.data.recipes.RecipeProvider` + - `dyedItem` - Creates a dyed item recipe. + - `dyedShulkerBoxRecipe` - Creates a dyed shulker box recipe. + - `dyedBundleRecipe` - Creates a dyed bundle recipe. +- `net.minecraft.world.item` + - `BundleItem` + - `getAllBundleItemColors`, `getByColor` are removed + - `DyeColor#VALUES` - A list of all dye colors. + - `DyeItem` no longer takes in the `DyeColor` + - `getDyeColor`, `byColor` are removed +- `net.minecraft.world.item.component.DyedItemColor#applyDyes` now takes in a list of `DyeColor`s instead of `DyeItem`s + - An overload can also take in a `DyedItemColor` component instead of the `ItemStack` +- `net.minecraft.world.item.crafting.ArmorDyeRecipe` -> `DyeRecipe`, not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay$DyedSlotDemo` - A display for demoing dying an item. +- `net.minecraft.world.level.block` + - `BannerBlock#byColor` is removed + - `ShulkerBoxBlock#getBlockByColor`, `getColoredItemStack` are removed + +## World Clocks and Time Markers + +World clocks are objects that represent some time that increases every tick from when the world first loads. These clocks are used as timers to properly handle timing-based events (e.g., the current day, sleeping). Vanilla provides two world clocks: one for `minecraft:overworld` and one for `minecraft:the_end`. + +Creating a clock is rather simple: just an empty, datapack registry object in `world_clock`. + +```json5 +// For some world clock 'examplemod:EXAMPLE_CLOCK' +// JSON at 'data/examplemod/world_clock/EXAMPLE_CLOCK.json' +{} +``` + +From there, you can query the clock state through the `ClockManager` via `Level#clockManager` or `MinecraftServer#clockManager`: + +```java +// For some Level level +// Assume we have some ResourceKey EXAMPLE_CLOCK + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Query the clock time +long ticksPassed = level.clockManager().getTotalTicks(clock); +``` + +If accessing the clock from the server, you can also modify the state of the clock: + +```java +// For some ServerLevel level +// Assume we have some ResourceKey EXAMPLE_CLOCK + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Get the server clock manager +ServerClockManager clockManager = level.clockManager(); + +// Set the total number of ticks that have passed +clockManager.setTotalTicks(clock, 0L); + +// Add the a certain value to the number of ticks +clockManager.addTicks(clock, 10L); + +// Pause the clock +clockManager.setPaused( + clock, + // `true` to pause. + // `false` to unpause. + true +); +``` + +### Marking Timelines + +On its own, world clocks are rather limited in scope as you have to keep track of the number of ticks that have passed. However, when used with timelines, specific recurring times can be marked to handle timing-based events. + +As a refresher, `Timeline`s are a method of modifying attributes based on some `WorldClock`. Currently, all vanilla timelines use the `minecraft:overworld` world clock to keep track of their timing, via the `clock` field. All timelines must define a clock it uses; however, be aware that clocks to not support any synchronization by default, meaning that updating the time on one clock will not affect the other. + +```json5 +// For some timeline 'examplemod:example_timeline' +// In `data/examplemod/timeline/example_timeline.json +{ + // Uses the custom clock. + // Any changes to the clock time will only affect + // timelines using this clock. + // e.g., `minecraft:overworld` will not be changed. + "clock": "examplemod:example_clock", + // Perform actions on a 24,000 tick interval. + "period_ticks": "24000", + // ... +} + + +// For some timeline 'examplemod:example_timeline_2' +// In `data/examplemod/timeline/example_timeline_2.json +{ + // Uses the same clock as the one above. + // Changes to the clock time will affect both + // timelines. + "clock": "examplemod:example_clock", + // Perform actions on a 1,000 tick interval. + "period_ticks": "1000", + // ... +} + +// For some timeline 'examplemod:example_overworld' +// In `data/examplemod/timeline/example_overworld.json +{ + // Uses the vanilla overworld clock. + // Changes to the clock time will not affect + // the above timelines as they use a different + // clock. + "clock": "minecraft:overworld", + // Perform actions on a 6,000 tick interval. + "period_ticks": "6000", + // ... +} +``` + +Timelines can also define time markers, which is just some identifier for a time within the timeline period for a world clock. These are commonly used within commands (e.g. `/time set`), to check if a certain time has passed (e.g. village sieges), or to skip to the given time (e.g. waking up from sleep). Time markers are defined in `time_markers`, specifying the `ticks` within the period and whether it can be `show_in_commands`. As time markers are identified by their world clock, timelines using the same world clock cannot define the same time markers. + +```json5 +// For some timeline 'examplemod:example_timeline' +// In `data/examplemod/timeline/example_timeline.json +{ + // The identifier of the clock. + "clock": "examplemod:example_clock", + // Perform actions on a 24,000 tick interval. + "period_ticks": "24000", + // The markers within the period specified by the timeline + "time_markers": { + // A marker + "examplemod:example_marker": { + // The number of ticks within the period + // that this marker represents. + // e.g., 5000, 29000, 53000, etc. + "ticks": 5000, + // When true, allows the time marker to be + // suggested in the command. If false, + // the time marker can still be used in the + // command, it just won't be suggested. + "show_in_commands": true + } + } + // ... +} +``` + +Once the time markers are defined, they are registered for a world clock in the `ServerClockManager`, allowing them to be used given the `ResourceKey`. + +```java +// For some ServerLevel level +// Assume we have some ResourceKey EXAMPLE_CLOCK +// Assume we have some ResourceKey EXAMPLE_MARKER + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Get the server clock manager +ServerClockManager clockManager = level.clockManager(); + +// Check if the time is at the specified marker +// This should be used when checking for a specific time event every tick +boolean atMarker = clockManager.isAtTimeMarker(clock, EXAMPLE_MARKER); + +// Skip to the time specified by the marker +// If the world clock is at 3000, sets the clock time to 5000 +// If the world clock is at 6000, sets the clock time to 29000 +// Returns whether the time was set, which is always true if the marker +// exists for the clock. +boolean timeSet = clockManager.skipToTimeMarker(clock, EXAMPLE_MARKER); +``` + +- `net.minecraft.client.ClientClockManager` - Manages the ticking of the world clocks on the client side. +- `net.minecraft.client.gui.components.debug.DebugEntryDayCount` - Displays the current day of the Minecraft world. +- `net.minecraft.client.multiplayer` + - `ClientLevel` + - `setTimeFromServer` no longer takes in the `long` day time nor the `boolean` of whether to tick the day time + - `$ClientLevelData#setDayTime` is removed + - `ClientPacketListener#clockManager` - Gets the client clock manager. +- `net.minecraft.client.renderer.EndFlashState#tick` now takes in the end clock time instead of the game time +- `net.minecraft.commands.arguments.ResourceArgument` + - `getClock` - Gets a reference to the world clock given the string resource identifier. + - `getTimeline` - Gets a reference to the timeline given the string resource identifier. +- `net.minecraft.core.registries.Registries#WORLD_CLOCK` - The registry identifier for the world clock. +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` + - `$TimeOfDay` -> `$ClockTime`, not one-to-one + - `$Timelines` - A test environment that uses a list of timelines. +- `net.minecraft.network.protocol.game.ClientboundSetTimePacket` now takes in a map of clocks to their network states instead of the day time `long` and `boolean` +- `net.minecraft.server` + - `MinecraftServer` + - `forceTimeSynchronization` -> `forceGameTimeSynchronization`, not one-to-one + - `clockManager` - The server clock manager. +- `net.minecraft.server.level.ServerLevel` + - `setDayTime`, `getDayCount` are removed + - `setEnvironmentAttributes` - Sets the environment attribute system to use. +- `net.minecraft.world.attribute.EnvironmentAttributeSystem$Builder#addTimelineLayer` now takes in the `ClockManager` instead of a `LongSupplier` +- `net.minecraft.world.clock` + - `ClockManager` - A manager that gets the total number of ticks that have passed for a world clock. + - `ClockNetworkState` - The current state of the clock to sync over the network. + - `ClockState` - The current state of the clock, including the total number of ticks and whether the clock is paused. + - `ClockTimeMarker` - A marker that keeps track of a certain period of time for a world clock. + - `ClockTimeMarkers` - All vanilla time markers. + - `PackedClockStates` - A map of clocks to their states, compressed for storage or other use. + - `ServerClockManager` - Manages the ticking of the world clocks on the server side. + - `WorldClock` - An empty record that represents a key for timing some location. + - `WorldClocks` - All vanilla world clocks. +- `net.minecraft.world.level` + - `Level` + - `getDayTime` -> `getOverworldClockTime`, not one-to-one + - `clockManager` - The clock manager. + - `getDefaultClockTime` - Gets the clock time for the current dimension. + - `LevelReader#getEffectiveSkyBrightness` - Gets the sky brightness with the current darkening factor. +- `net.minecraft.world.level.dimension.DimensionType` now takes in a default, holder-wrapped `WorldClock` +- `net.minecraft.world.level.storage` + - `LevelData#getDayTime` is removed + - `ServerLevelData` + - `setDayTime` is removed + - `setClockStates`, `clockStates` - Handles the current states of the world clocks. +- `net.minecraft.world.level.storage.loot.predicates.TimeCheck` now takes in a holder-wrapped `WorldClock` + - `time` now takes in a holder-wrapped `WorldClock` + - `$Builder` now takes in a holder-wrapped `WorldClock` +- `net.minecraft.world.timeline` + - `AttributeTrack#bakeSampler` now takes in a holder-wrapped `WorldClock` + - `AttributeTrackSampler` now takes in a holder-wrapped `WorldClock`, and a `ClockManager` instead of a `LongSupplier` for the day time getter + - `Timeline` now takes in a holder-wrapped `WorldClock` along with a map of time markers to their infos + - `#builder` now takes in a holder-wrapped `WorldClock` + - `getPeriodCount` - Gets the number of times a period has occurred within the given timeframe. + - `getCurrentTicks` now takes in the `ClockManager` instead of the `Level` + - `getTotalTicks` now takes in the `ClockManager` instead of the `Level` + - `clock` - Returns the holder-wrapped `WorldClock`. + - `registerTimeMarkers` - Registers all `ClockTimeMarker` defined in this timeline. + - `createTrackSampler` now takes in a `ClockManager` instead of a `LongSupplier` for the day time getter + - `$Builder#addTimeMarker` - Adds a time markers at the given tick, along with whether the marker can be suggested in commands. + - `Timelines#DAY` -> `OVERWORLD_DAY` + +## Splitting the Primary Level Data into Saved Data + +Some of the `WorldData` settings have been moved into `SavedData`, allowing for levels / dimensions to have more customizability. This addition also brings along some changes to how `SavedData` is referenced and queried. + +### Saved Data Changes + +`SavedDataType` now identifies some `SavedData` using an `Identifier`, which is resolved against the data folder. This change allows subdirectories within the data folder, as the data storage will first create all missing parent directories before attempting to write the file. + +```java +public class ExampleData extends SavedData { + + public static final SavedDataType TYPE = new SavedDataType<>( + // The identifier for the saved data to resolve against + // Data can be found in: + // `/dimensions///data/examplemod/example/data.dat` + Identifier.fromNamespaceAndPath("examplemod", "example/data"), + // The constructor to create a new saved data + ExampleData::new, + // The codec to serialize the new saved data + MapCodec.unitCodec(ExampleData::new), + // The data fixer type + // Either some patched enum value or null depending on mod loader implementation. + null + ); +} +``` + +The `SavedData` can then be queried through the `SavedDataStorage`, renamed from `DimensionDataStorage`. This was renamed because the `MinecraftServer` instance now has its own data storage for global instances in addition to the levels. This means that any global saved data should be stored on the server instance rather than the overworld. + +```java +// Given a MinecraftServer server +ExampleData data = server.getDataStorage().computeIfAbsent(ExampleData.TYPE); + + +// Given a ServerLevel level +ExampleData data = level.getDataStorage().computeIfAbsent(ExampleData.TYPE); +``` + +### Additional Saved Data + +The following information is now stored as saved data: + +- Custom boss events +- Ender dragon fight +- Game rules +- Wandering trader spawning +- Weather +- World generation settings + +Of these, only the ender dragon fight is on a per-level / dimension basis. The rest are still stored and accessed through the server data storage. Custom boss events, on the other hand, remain unique as it is up to the implementer to determine what players are part of the event. + +- `net.minecraft.client.Minecraft#doWorldLoad` now takes in the optional `GameRules` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldCallback` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` and the optional `GameRules` instead of the `PrimaryLevelData` + - `EditGameRulesScreen` -> `AbstractGameRulesScreen` + - Implementations in `.screens.options.InWorldGameRulesScreen` and `WorldCreationGameRulesScreen` + - `WorldOpenFlows` + - `createLevelFromExistingSettings` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` and the optional `GameRules` instead of the `WorldData` + - `loadWorldStem` now takes in the `LevelStorageSource$LevelStorageAccess` +- `net.minecraft.client.server.IntegratedServer` now takes in the optional `GameRules` +- `net.minecraft.server` + - `MinecraftServer` now takes in the optional `GameRules` + - `getGlobalGameRules` - Gets the game rules for the overworld dimension. + - `getWorldGenSettings` - Gets the generation settings for the world. + - `getWeatherData` - Gets the weather data for the server. + - `getDataStorage` - Gets the saved data storage for the server. + - `getGameRules` - Gets the game rules for the server. + - `WorldStem` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` instead of the `WorldData` +- `net.minecraft.server.bossevents` + - `CustomBossEvent` now takes in a `UUID` for the identifier along with a `Runnable` for the callback + - `getTextId` -> `customId` + - `addOfflinePlayer` is removed + - `getValue` -> `value` + - `getMax` -> `max` + - `load` now takes in the `UUID` identifier along with a `Runnable` for the callback + - `CustomBossEvents` now extends `SavedData` + - `create` now takes in a `RandomSource` + - `save`, `load` -> `TYPE`, not one-to-one +- `net.minecraft.server.dedicated.DedicatedServer` now takes in the optional `GameRules` +- `net.minecraft.server.level` + - `ChunkMap#getChunkDataFixContextTag` now takes in an optional `Identifier` instead of a `ResourceKey` + - `ServerBossEvent` now takes in an `UUID` for the id + - `setDirty` - Marks the boss event as dirty for saving. + - `ServerLevel` no longer takes in the `RandomSequences` + - `setWeatherParameters` -> `MinecraftServer#setWeatherParameters` + - `getWeatherData` - Gets the weather data for the server. + - `getRandomSequence` -> `MinecraftServer#getRandomSequence` + - `getRandomSequences` -> `MinecraftServer#getRandomSequences` +- `net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner` now takes in the `SavedDataStorage` instead of the `ServerLevelData` + - `MIN_SPAWN_CHANCE` is now `public` from `private` +- `net.minecraft.world.entity.raid.Raids#TYPE_END`, `getType` are removed +- `net.minecraft.world.level` + - `Level#prepareWeather` is removed + - `LevelSettings` is now a record + - The constructor now takes in the `$DifficultySettings` instead of just the `Difficulty` + - `withDifficultyLock` - The settings with whether the difficulty is locked. + - `copy` - Copies the settings. + - `$DifficultySettings` - The settings for the difficulty. +- `net.minecraft.world.level.dimension.DimensionType` now takes in a `boolean` for whether the dimension can have an ender dragon fight +- `net.minecraft.world.level.dimension.end` + - `DragonRespawnAnimation` -> `DragonRespawnStage`, not one-to-one + - `EndDragonFight` -> `EnderDragonFight`, not one-to-one +- `net.minecraft.world.level.gamerules.GameRuleMap` now extends `SavedData` + - `TYPE` - The saved data type. + - `reset` - Resets the rule to its default value. +- `net.minecraft.world.level.levelgen.WorldGenSettings` is now a final class instead of a record, extending `SavedData` + - `encode`, `decode` replaced with `TYPE` + - `of` - Constructs the generation settings. +- `net.minecraft.world.level.saveddata` + - `SavedDataType` now takes in an `Identifier` instead of a string for the id + - `WanderingTraderData` - The saved data for the wandering trader. + - `WeatherData` - The saved data for the weather. +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` -> `SavedDataStorage`, not one-to-one + - `LevelData#isThundering`, `isRaining`, `setRaining` now in `WeatherData` + - `LevelDataAndDimensions` now takes in a `$WorldDataAndGenSettings` instead of the `WorldData` + - `$WorldDataAndGenSettings` - Holds the world data and generation settings. + - `LevelResource` is now a record + - `PrimaryLevelData` fields have been moved to their respective saved data classes + - `PLAYER` -> `OLD_PLAYER` + - `SINGLEPLAYER_UUID` - A string that represents the UUID of the player in a singleplayer world. + - `WORLD_GEN_SETTINGS` -> `OLD_WORLD_GEN_SETTINGS` + - `writeLastPlayed` - Writes the last played player. + - `writeVersionTag` - Writes the data version tag. + - `ServerLevelData` + - `setThundering`, `getRainTime`, `setRainTime`, `setThunderTime`, `getThunderTime`, `getClearWeatherTime`, `setClearWeatherTime` moved to `WeatherData` + - `getWanderingTraderSpawnDelay`, `setWanderingTraderSpawnDelay`, `getWanderingTraderSpawnChance`, `setWanderingTraderSpawnChance`, `getWanderingTraderId`, `setWanderingTraderId` moved to `WanderingTraderData` + - `getLegacyWorldBorderSettings`, `setLegacyWorldBorderSettings` replaced by `WorldBorder` + - `getScheduledEvents` -> `MinecraftServer#getScheduledEvents` + - `getGameRules` replaced by `GameRuleMap` + - `WorldData` + - `getCustomBossEvents`, `setCustomBossEvents` replaced by `CustomBossEvents` + - `createTag` no longer takes in the `RegistryAccess` + - `getGameRules` replaced by `GameRuleMap` + - `getLoadedPlayerTag` -> `getSinglePlayerUUID`, not one-to-one + - `endDragonFightData`, `setEndDragonFightData` replaced by `EnderDragonFight` + - `worldGenOptions` replaced by `WorldGenSettings` saved data +- `net.minecraft.world.level.timers.TimerQueue` now extends `SavedData` + - The constructor now takes in the `$Packed` events instead of the `TimerCallbacks` and `Stream` of event data + - `store` replaced by `CODEC`, `TYPE`, `codec` + - `loadEvent`, `storeEvent` replaced by `$Event$Packed#codec` + - `$Event` is now a record + - `$Packed` - The packed event data. + - `$Packed` - The packed time queue. + +## Even More Rendering Changes + +### Materials and Dynamic Layer Selection + +Block and item models now no longer specify what `RenderType` or `ChunkSectionLayer` they belong to. Instead, this is computed when loading the model, determing the associated layer for each quad. This means that `ItemBlockRenderTypes` is removed, with setting the `RenderType` for an item removed altogether. + +To determine what layer a quad or face gets set to, the `Transparency` of the texture is computed. Specifically, it checks that, for the UV area mapped to the quad, if there are any pixels that are transparent (have an alpha of 0), or translucent (have an alpha that is not 0 or 255). For the `ChunkSectionLayer`, `ChunkSectionLayer#TRANSLUCENT` is used if there is a translucent pixel, else `CUTOUT` is used if there is a transparent pixel, else `SOLID`. For the item `RenderType`, `Sheets#translucentItemSheet` and `translucentBlockItemSheet` for block items are used if there is a translucent pixel, or `cutoutItemSheet` and `cutoutBlockItemSheet` for block items. The `Transparency` also affects using `MipmapStrategy#AUTO`, using `CUTOUT` instead of `MEAN` as the default if there is a transparent pixel. + +One can influence a quad's `Transparency` through the `Material` texture defined by the model JSON. A `Material` specifies the texture's `sprite`, which represents the relative path to the texture, and optionally `force_translucent`, which forces any quad using this texture to use `Transparency#TRANSLUCENT` (transparent is false while translucent is true): + +```json5 +// For some model `examplemod:example_model` +// In: `assets/examplemod/models/example_model.json` +{ + "parent": "minecraft:block/template_glass_pane_post", + "textures": { + // A Material can be a simple texture reference + // Points to `assets/minecraft/textures/block/glass_pane_top.png` + "edge": "minecraft:block/glass_pane_top", + // Or it can be an object + "pane": { + // The relative texture reference for faces using this key + // Points to `assets/minecraft/textures/block/glass.png` + "sprite": "minecraft:block/glass", + // When true, sets all faces using this texture key to + // always have a transparent pixel. + "force_translucent": true + } + } + // ... +} +``` + +This change also defines the rendering order, where all solid quads are rendered first, followed by cutout quads, and finally translucent quads, sorted by distance from the camera. + +### Materials and Sprites + +As you may have noticed, `Material`s were originally used to define some texture in an atlas. The addition of materials in texture JSONs have changed the naming of these classes. `Material`s now explicitly refer to texture references within model JSONs. This means that all references to the raw texture location have been replaced with `Material`, if unbaked, and `Material$Baked`, if baked. Additionally, the `SpriteGetter` is now `MaterialBaker`. + +As for the original `Material`, these are now known as sprites, where `Material` is renamed to `SpriteId`, and `MaterialSet` is renamed to `SpriteGetter`. + +### Quad Particle Layers + +The `SingleQuadParticle$Layer`s have been split into `OPAQUE_*` and `TRANSLUCENT_*` layers, depending on if the particle texture used by the atlas contains a translucent pixel. Note that 'opaque' in this instance means cutout, where pixels with an alpha of less than 0.1 are discarded. If not creating a new layer, `$Layer#bySprite` can be used to determine what layer the particle texture should use. + +```java +public class ExampleParticle extends SingleQuadParticle { + + private final SingleQuadParticle.Layer layer; + + public SingleQuadParticle(ClientLevel level, double x, double y, double z, TextureAtlasSprite sprite) { + super(level, x, y, z, sprite); + this.layer = SingleQuadParticle.Layer.bySprite(sprite); + } + + @Override + protected SingleQuadParticle.Layer getLayer() { + return this.layer; + } +} +``` + +### Block Models + +The pipeline for rendering individual block models outside of the general world context has been rewritten similarly to `ItemModel`s, where a 'block model' updates some render state, which then submits its elements for rendering. As such, most of the block model classes have been either rewritten or reorganized to a degree. + +Due to the block model name being synonymous with the model JSONs in general, many classes were moved and rename to separate the model JSONs, from the block state JSONs, from the now block models. As such, geometry for models that originally had 'block' in the name were changed to 'cuboid': (e.g., `BlockModel` -> `CuboidModel`, `BlockModelWrapper` -> `CuboidItemModelWrapper`). Additionally, parts of the rendering process referring to the definitions within a block state JSON were changed from 'block' to 'block state' (e.g., `BlockModelPart` -> `BlockStateModelPart`, `BlockModelDefinition` -> `BlockStateModelDispatcher`). You can consider most of the 'block model' classes to be new, with those renamed replacing the `SpecialBlockModelRenderer` system. + +The block model system starts from the `ModelManager` after all models and definitions are loaded and resolved, ready to be baked. Block models are loaded through `BuiltInBlockModels#crateBlockModels`, which links some `BlockState` to a `BlockModel$Unbaked`. Similarly to item models, the unbaked instance defines the properties of how the block model should be constructed. These are stored within `LoadedBlockModels`, to which they are then subsequently baked after all JSONs into `BlockModel`s via `bake`. This `BlockState` to `BlockModel` map is then stored within the `BlockModelSet`, ready to be queried through `get`, or more commonly through `BlockModelResolver#update`, which calls in the model set. Any models not defined lazily resolve to a wrapper around the `BlockStateModel`. + +Vanilla provides six `BlockModel` implementations for common usage. There is `EmptyBlockModel`, which submit no elements, and as such renders nothing; and `BlockStateModelWrapper`, which wraps around and displays the associated `BlockStateModel`. Then, there are equivalents for changing the model based on some property switch (`SelectBlockModel`), a conditional `boolean` (`ConditionalBlockModel`), and composing multiple models together (`CompositeBlockModel`). Finally, there is the `SpecialBlockModelWrapper`, which submits its elements through the stored `SpecialModelRenderer`, the unified submitter between item and block models. + +```java +// As the block model system is hardcoded through its in-code bootstrap, +// this example will assume there exists some method to get access to the +// `BuiltInBlockModels$Builder` builder. + +// We will also assume we have some Block EXAMPLE_BLOCK_* to attach the models to. + +// Regular block model +builder.put( + // A factory that takes in the `BlockColors` and `BlockState` to return + // a `BlockModel$Unbaked`. + (colors, state) -> new BlockStateModelWrapper.Unbaked( + // The state to get the `BlockStateModel` of. + state, + // The tint layers for the model. + colors.getTintSources(state), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(new Transformation(new Matrix4f().translation(0.5f, 0.5f, 0.5f))) + ), + // The block to use this model for. Will loop through a construct one + // per state. + EXAMPLE_BLOCK_1 +); + +// Block model switched on some property +builder.put( + (colors, state) -> new SelectBlockModel.Unbaked( + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(), + // A record containing the property to switch on, along with the + // values when a specific block model should be selected. + new SelectBlockModel.UnbakedSwitch<>( + // The `SelectBlockModelProperty` to switch on. The property + // value is determined from the `BlockState` and its `BlockDisplayContext`. + (state, displayContext) -> state.getRenderShape(), + // The list of cases to determine what `BlockModel` to use. + List.of( + new SelectBlockModel.SwitchCase<>( + // The list of values this model applies to. + List.of(RenderShape.INVISIBLE), + // The model to use when this property is met. + new EmptyBlockModel.Unbaked() + ) + ), + // An optional fallback if no switch case matches the state's + // property. + Optional.of(new EmptyBlockModel.Unbaked()) + ) + ), + EXAMPLE_BLOCK_2 +); + +// Block model based on some conditional +builder.put( + (colors, state) -> new ConditionalBlockModel.Unbaked( + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(), + // The `ConditionalBlockModelProperty` that determines the + // `boolean` from the `BlockState`. + BlockState::isSignalSource, + // The model to display when the property returns `true`. + new EmptyBlockModel.Unbaked(), + // The model to display when the property returns `false`. + new EmptyBlockModel.Unbaked() + ), + EXAMPLE_BLOCK_3 +); + +// A composite block model +builder.put( + (colors, state) -> new CompositeBlockModel.Unbaked( + // The first model to display. + new EmptyBlockModel.Unbaked(), + // The second model to display. + new EmptyBlockModel.Unbaked(), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty() + ), + EXAMPLE_BLOCK_4 +); + +// Special block model +builder.put( + (colors, state) -> new SpecialBlockModelWrapper.Unbaked( + // The unbaked `SpecialModelRenderer` used to submit elements for the + // model. + new BellSpecialRenderer.Unbaked(), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty() + ), + EXAMPLE_BLOCK_5 +); +``` + +During the feature submission process, block models are handled through the `BlockModelResolver` and `BlockModelRenderState`. This is similar to how other render states work. First, `BlockModelResolver#update` sets up the `BlockModelRenderState`. Setup is handled through either the basic path -- `BlockModelRenderState#setupModel`, add the model parts to the returned list, then `setupTints`, or through `setupSpecialModel` for the special renderers. Then, the render state submits its elements for rendering through `BlockModelRenderState#submit`. The render state also provides `submitOnlyOutline` which uses the outline render type, and `submitWithZOffset` which uses the sold entity forward Z-offset render type. + +```java +// BlockEntity example +public class ExampleRenderState extends BlockEntityRenderState { + // Hold the render state. + public final BlockModelRenderState exampleBlock = new BlockModelRenderState(); +} + +public class ExampleRenderer implements BlockEntityRenderer { + + // The display context for use in the block entity renderer. + public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create(); + private final BlockModelResolver blockResolver; + + public ExampleRenderer(BlockEntityRendererProvider.Context ctx) { + super(ctx); + // Get the model resolver. + this.blockResolver = ctx.blockModelResolver(); + } + + @Override + public void extractRenderState(ExampleBlockEntity blockEntity, ExampleRenderState state, float partialTick, Vec3 cameraPosition, ModelFeatureRenderer.CrumblingOverlay breakProgress) { + super.extractRenderState(blockEntity, state, partialTick, cameraPosition, breakProgress); + + // Update the model state. + this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT); + } + + @Override + public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) { + super.submit(state, pose, collector, camera); + + // Submit the model state for rendering. + state.exampleBlock.submit( + // The current pose stack, + pose, + // The node collector. + collector, + // The light coordinates. + state.lightCoords, + // The overlay coordinates. + OverlayTexture.NO_OVERLAY, + // The outline color. + 0 + ); + + + } +} + +// Entity example +public class ExampleRenderState extends EntityRenderState { + // Hold the render state. + public final BlockModelRenderState exampleBlock = new BlockModelRenderState(); +} + +public class ExampleRenderer extends EntityRenderer { + + // The display context for use in the entity renderer. + public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create(); + private final BlockModelResolver blockResolver; + + public ExampleRenderer(EntityRendererProvider.Context ctx) { + super(ctx); + // Get the model resolver. + this.blockResolver = ctx.getBlockModelResolver(); + } + + @Override + public void extractRenderState(ExampleEntity entity, ExampleRenderState state, float partialTick) { + super.extractRenderState(entity, state, partialTick); + + // Update the model state. + this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT); + } + + @Override + public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) { + super.submit(state, pose, collector, camera); + + // Submit the model state for rendering. + state.exampleBlock.submit( + // The current pose stack. + pose, + // The node collector. + collector, + // The light coordinates. + state.lightCoords, + // The overlay coordinates. + OverlayTexture.NO_OVERLAY, + // The outline color. + state.outlineColor + ); + } +} +``` + +### Block Tint Sources + +`BlockColor` has been completely replaced by `BlockTintSource`, which sets the ARGB tint of a particular index based on the desired context. There are three contexts a tint source can provide: + +- `color` for the general context, used by `BlockModel`s +- `colorInWorld` for the world context, used by `ModelBlockRenderer#tesselateBlock` +- `colorAsTerrainParticle` for the particle context, used by the falling dust and terrain particle + +In addition, `BlockTintSource` provides a `relevantProperties` if the `Property`s of a `BlockState` are used to determine what color to tint. This is used by the `LevelRenderer` to determine whether a change in state requires a model to be re-rendered. + +`BlockTintSource`s are still registered to `BlockColors` via `register`, taking in a list of sources followed by the vararg of blocks. The `tintindex` specfied in the model JSON is used to index into the tint source list. + +```java +// Assume access to BlockColors colors +colors.register( + // The list of tints to apply to some block model. + List.of( + // "tintindex": 0 + (state) -> 0xFFFF0000, + // "tintindex": 1 + new BlockTintSource() { + + @Override + public int color(BlockState state) { + return 0xFF00FF00; + } + + @Override + public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) { + return 0xFF0000FF; + } + } + ), + // The blocks these tint sources will apply to. + EXAMPLE_BLOCK_1 +); +``` + +### Removing the Old Block and Item Renderers + +Since `ItemModel`s and `BlockModel` are now fully handled through their own feature submission pipeline, `BlockRenderDispatcher` and `ItemRenderer` have been completely removed, replaced by the corresponding systems. + +### Object Definition Transformations + +`ItemModel`s and `BlockModel`s can now take in an optional `Transformation`, which transforms how the model should be displayed. As such, the `$Unbaked#bake` methods now take in the parent `Matrix4fc` transformation, to which the transformation is multiplied to via `Transformation#compose`. For item models, this is known as a local transform separate from the model JSON item transform. The local transforms are always applied after the item transform. + +Note that adding support for transformations should always be done through `Transformation#compose` as the matrices passed around are mutable by nature. Assume any custom methods not performed through a vanilla interface should copy before performing any modifications. + +### Quad Instance + +The brightness / tint color, lightmap, and overlay coordinates have been consolidated into a single object: `QuadInstance`. The mutable class sets its values through its associated `set*` methods, and can pull the information for each quad vertex via the `get*` methods. Brightness and tinting are stored together as the color, rather them being two separate values. + +`QuadInstance` does not replace all usecases, such as when adding a single vertex. It only updates methods for the `VertexConsumer`, splitting `putBulkData` into `putBlockBakedQuad` for quads in block models, and `putBakedQuad` for all other uses. + +In addition, mmany methods used to upload `BakedQuad`s to a buffer now take in a `BlockQuadOutput`. This has the same parameters as `VertexConsumer#putBlockBakedQuad`, and was added due to the section renderer uploading to a newly allocated `BufferBuilder` for use with the uber buffer. + +### Gui Extractor + +GUI classes methods have gone through a massive renaming scheme, indicating that the submitted elements are 'extracted' into a general tree to be submitted and then rendered. As such, methods that began with `draw*` or `render*` are now prefixed with `extract*`, and potentially suffixed with `*RenderState` (e.g., `Renderable#render` -> `extractRenderState`, `AbstractContainerScreen#renderLabels` -> `extractLabels`, `AbstractWidget#renderWidget` -> `extractWidgetRenderState`). Some shorthands were also expanded, either by renamining or replacing the method with another (e.g., `AbstractContainerScreen#renderBg` replaced by `Screen#extractBackground`). + +`GuiGraphics` was also renamed to `GuiGraphicsExtractor` in the same fashion. The methods follow similar patterns to the rest of the GUI changes (e.g. `hline` -> `horizontalLine`), except that `draw*`, `render*`, and `submit*` prefixes along with `*RenderState` suffixes are removed (e.g. `renderOutline` -> `outline`, `submitEntityRenderState` -> `entity`). The only rename is that `*String*` method names are replaced with `*Text*`. + +### Fluid Models + +Defining a fluid's textures and tint has now been moved out of the `FluidRenderer` (previously `LiquidBlockRenderer`) and into its own separate `FluidModel` record. Initially, given the small number of fluids, the unbaked variants (`FluidModel$Unbaked`) are stored as constants. Then, after `BlockModel` have been baked, the fluid models are baked via `FluidStateModelSet#bake`, linking a `Fluid` to its `FluidModel`. This map is then stored within the `FluidStateModelSet`, ready to be queried through `get`. + +A `FluidModel$Unbaked` has four arguments: three `Material`s for the still, flowing, and optional overlay textures; and one for the `BlockTintSource`. The tint is obtained via `BlockTintSource#colorInWorld`. During the baking process, it will determine the `ChunkSectionLayer` based on the transparency of the provided materials. + +```java +// As the fluid model system is hardcoded within its baking, this example +// will assume there exists some method to get modifiable access to the +// `Map` fluidModels returned by `FluidStateModelSet#bake`. + +// We will also assume we have some Fluid EXAMPLE_FLUID* to attach the models to. + +FluidModel.Unbaked exampleFluidModel = new FluidModel.Unbaked( + // The texture for the still fluid. + new Material( + // The relative identifier for the texture. + // Points to `assets/examplemod/textures/block/example_fluid_still.png` + Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_still"), + // When true, sets all faces using this texture key to + // always have a transparent pixel. + true + ), + // The texture for the flowing fluid. + new Material(Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_flowing")), + // If not null, the texture for the overlay when the side of the fluid is + // occluded by a `HalfTransparentBlock` or `LeavesBlock`. + null, + // If not null, the tint source to apply to the fluid's texture when in + // the world. + null +); + +// Assume we have access to the `MaterialBaker` materials. + +FluidModel exampleBakedFluidModel = exampleFluidModel.bake( + // The baker to grab the atlas sprites for the materials. + materials, + // A supplied debug name to properly report which models have + // missing textures. + () -> "examplemod:example_fluid_model" +); + +fluidModels.put( + // The fluid the model should be used by. + EXAMPLE_FLUID, + // The baked fluid model. + exampleBakedFluidModel +); +fluidModels.put(EXAMPLE_FLUID_FLOWING, exampleBakedFluidModel); +``` + +### Name Tag Offsets + +`EntityRenderer#submitNameTag` has been renamed to `submitNameDisplay`, now optionally taking in the y offset from the name tag attachment. + +### Tint Getter + +`BlockAndTintGetter` is now a client only interface attached to the `ClientLevel`. It previous uses were replaced with `BlockAndLightGetter` -- which `BlockAndTintGetter` now extends -- with the tint and lighting directions stripped. + +### Pipeline Depth and Color + +Depth and color methods defined in the `RenderPipeline` have been consolidated into two state objects. + +The `DepthTestFunction`, write `boolean`, and the bias `float`s are now stored in `DepthStencilState`. `DepthTestFunction` has been replaced with a more generic `CompareOp`, which defines how to compare two numbers. Each function has an simple equivalent, with `NO_DEPTH_TEST` replaced by `CompareOp#ALWAYS_PASS`. The depth information can be added to the pipeline via `RenderPipeline$Builder#withDepthStencilState`. + +The optional `BlendFunction` and color / alpha `boolean`s are now stored in `ColorTargetState`. The `boolean`s are consolidated into an `int` using the lower four bits as flags: `1` is red, `2` is green, `4` is blue, and `8` is alpha. The color `boolean` uses `7` for red, green, and blue; the alpha `boolean` uses `8`; while both combined use `15`. The `LopicOp` is removed entirely. The color information can be added to the pipeline via `RenderPipeline$Builder#withColorTargetState`. + +```java +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder() + .withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example")) + .withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + .withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + .withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS) + .withShaderDefine("ALPHA_CUTOUT", 0.5) + .withSampler("Sampler0") + .withUniform("ModelOffset", UniformType.VEC3) + .withUniform("CustomUniform", UniformType.INT) + .withPolygonMode(PolygonMode.FILL) + .withCull(false) + // Sets the color target when writing the buffer data. + .withColorTargetState(new ColorTargetState( + // Specifies the functions to use when blending two colors with alphas together. + // Made up of the `SourceFactor` and `DestFactor`. + // First two are for RGB, the last two are for alphas. + // If the optional is empty, then blending is disabled. + Optional.of(BlendFunction.TRANSLUCENT), + // The mask determining what colors to write to the buffer. + // Represented as a four bit value + // 0001 - Write the red channel.. + // 0010 - Write the green channel. + // 0100 - Write the blue channel. + // 1000 - Write the alpha channel. + ColorTargetState.WRITE_RED | ColorTargetState.WRITE_GREEN | ColorTargetState.WRITE_BLUE | ColorTargetState.WRITE_ALPHA + )) + // Sets the depth stencil when writing the buffer data. + .withDepthStencilState(new DepthStencilState( + // Sets the depth test function to use when rendering objects at varying + // distances from the camera. + // Values: + // - ALWAYS_PASS (GL_ALWAYS) + // - LESS_THAN (GL_LESS) + // - LESS_THAN_OR_EQUAL (GL_LEQUAL) + // - EQUAL (GL_EQUAL) + // - NOT_EQUAL (GL_NOTEQUAL) + // - GREATER_THAN_OR_EQUAL (GL_GEQUAL) + // - GREATER_THAN (GL_GREATER) + // - NEVER_PASS (GL_NEVER) + CompareOp.LESS_THAN_OR_EQUAL, + // Whether to mask writing values to the depth buffer + false, + // The scale factor used to calculate the depth values for the polygon. + 0f, + // The unit offset used to calculate the depth values for the polygon. + 0f + )) + .build() +; +``` + +### Blaze3d Backends + +`CommandEncoder`, `GpuDevice`, and `RenderPassBackend` has been split into the `*Backend` interface, which functions similarly to the previous interface, and the wrapper class, which holds the backend and provides delegate calls, performing any validation necessary. The `*Backend` interfaces now explicitly perform the operation without checking whether the operation is valid. + +### Solid and Translucent Features + +Feature rendering has been further split into two passes: one for solid render types, and one for translucent render types. As such, most `render` methods now have a `renderSolid` and `renderTranslucent` method, respectively. Those which only render solid or translucent data only have one of the methods. + +### Camera State + +The `Camera` has been updated similarly to other render state implementations where the camera is extracted to the `CameraRenderState` during `GameRenderer#renderLevel`, and that is passed around with the data required to either submit and render elements. + +Due to this change, `FogRenderer#setupFog` now returns the `FogData`, containing all the information needed to render the fog, instead of just its color, and storing that in `CameraRenderState#fogData`. + +- Some shaders within `assets/minecraft/shaders/core` now use `texture` over `texelFetch` + - `entity.vsh` + - `item.vsh` + - `rendertype_leash.vsh` + - `rendertype_text.vsh` + - `rendertype_text_background.vsh` + - `rendertype_text_intensity.vsh` +- `assets/minecraft/shaders/core` + - `block.vsh#minecraft_sample_lightmap` -> `sample_lightmap.glsl#sample_lightmap` + - `rendertype_crumbling` no longer takes in `texCoord2` (lightmap) + - `rendertype_entity_alpha`, `rendertype_entity_decal` merged into `entity.fsh` using a `DissolveMaskSampler` + - `rendertype_item_entity_translucent_cull` -> `item`, not one-to-one + - `rendertype_translucent_moving_block` is removed + - This now uses the the shaders provided by the `ChunkSectionLayer` +- `com.mojang.blaze3d` + - `GLFWErrorCapture` - Captures errors during a GL process. + - `GLFWErrorScope` - A closable that defines the scope of the GL errors to capture. +- `com.mojang.blaze3d.opengl` + - `GlProgram#BUILT_IN_UNIFORMS`, `INVALID_PROGRAM` are now final + - `GlBackend` - A GPU backend for OpenGL. + - `GlCommandEncoder` now implements `CommandEncoderBackend` instead of `CommandEncoder`, the class now package-private + - `getDevice` is removed + - `GlConst#toGl` now takes in a `CompareOp` instead of the `DepthTestFunction` + - `GlDevice` now implements `GpuDeviceBackend` instead of `GpuDevice`, the class now package-private + - The constructor now takes in a `GpuDebugOptions` containing the log level, whether to use synchronous logs, and whether to use debug labels instead of those parameters being passed in directly + - `GlRenderPass` now implements `RenderPassBackend` instead of `RenderPass`, the class now package-private + - The constructor now takes in the `GlDevice` + - `GlStateManager#_colorMask` now takes an `int` for the color mask instead of four `boolean`s +- `com.mojang.blaze3d.platform` + - `ClientShutdownWatchdog` now takes in the `Minecraft` instance + - `DebugMemoryUntracker#untrack` is removed + - `GLX#make(T, Consumer)` is removed + - `NativeImage` + - `computeTransparency` - Returns whether there is at least one transparent or translucent pixel in the image. + - This crashes if the image's area is greater than 512MiB, or 2GiB with color data. + - `isClosed` - Whether the image is closed or deallocated. + - `Transparency` - An object of whether some image has a translucent and/or transparent pixel. + - `Window` now takes the `GpuBackend` instead of the `ScreenManager` + - `createGlfwWindow` - Directly creates the GLFW window with the provided settings. + - `updateDisplay` -> `updateFullscreenIfChanged`, not one-to-one + - `isResized`, `resetIsResized` - Handles whether the window has been resized. + - `backend` - Returns the `GpuBackend`. + - `$WindowInitFailed` constructor is now `public` from `private` + - `WindowEventHandler#resizeDisplay` -> `resizeGui` +- `com.mojang.blaze3d.pipeline` + - `ColorTargetState` - A record containing the blend function and mask for the color. + - `DepthStencilState` - A record containing the data for the depth stencil. + - `RenderPipeline` now takes in the `ColorTargetState` instead of the optional `BlendFunction`, color and alpha `boolean`s, and `LogicOp`; and the `DepthStencilState` instead of the `DepthTestFunction`, depth `boolean`, and bias `float`s + - `getDepthTestFunction`, `isWriteDepth`, `getDepthBiasScaleFactor`, `getDepthBiasConstant` -> `getDepthStencilState`, not one-to-one + - `getColorLogic`, `getBlendFunction`, `isWriteColor`, `isWriteAlpha` -> `getColorTargetState`, not one-to-one + - `$Builder` + - `withDepthTestFunction`, `withDepthWrite`, `withDepthBias` -> `withDepthStencilState`, not one-to-one + - `withBlend`, `withColorWrite`, `withColorLogic` -> `withColorTargetState`, not one-to-one + - `$Snippet` now takes in the `ColorTargetState` instead of the optional `BlendFunction`, color and alpha `boolean`s, and `LogicOp`; and the `DepthStencilState` instead of the `DepthTestFunction` and depth `boolean` +- `com.mojang.blaze3d.platform` + - `BackendOptions` - A configuration for initializing the backend with. + - `DepthTestFunction` -> `CompareOp`, not one-to-one + - `NO_DEPTH_TEST` -> `CompareOp#ALWAYS_PASS` + - `EQUAL_DEPTH_TEST` -> `CompareOp#EQUAL` + - `LEQUAL_DEPTH_TEST` -> `CompareOp#LESS_THAN_OR_EQUAL` + - `LESS_DEPTH_TEST` -> `CompareOp#LESS_THAN` + - `GREATER_DEPTH_TEST` -> `CompareOp#GREATER_THAN` + - `GLX` + - `_initGlfw` now takes in the `BackendOptions` + - `glfwBool` - `1` if `true`, `0` if `false`. + - `LogicOp` enum is removed +- `com.mojang.blaze3d.shaders.GpuDebugOptions` - The debug options for the GPU pipeline. +- `com.mojang.blaze3d.systems` + - `BackendCreationException` - An exception thrown when the GPU backend couldn't be created. + - `CommandEncoder` -> `CommandEncoderBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `GpuBackend` - An interface responsible for creating the used GPU device and window to display to. + - `GpuDevice` -> `GpuDeviceBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `setVsync` - Sets whether VSync is enabled. + - `presentFrame` - Swaps the front and back buffers of the window to display the present frame. + - `isZZeroToOne` - Whether the 0 to 1 Z range is used instead of -1 to 1. + - `RenderPass` -> `RenderPassBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `RenderSystem` + - `pollEvents` is now public + - `flipFrame` no longer takes in the `Window` + - `initRenderer` now only takes in the `GpuDevice` + - `limitDisplayFPS` -> `FramerateLimiter#limitDisplayFPS` + - `initBackendSystem` now takes in the `BackendOptions` +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat#BLOCK` no longer takes in the normal vector + - `PoseStack#mulPose`, `$Pose#mulPose` now has an overload that takes in the `Transformation` + - `QuadInstance` - A class containing the color, light coordinates, and overlay of a quad. + - `TlsfAllocator` - A two-level segregate fit allocator for dynamic memory allocation. + - `UberGpuBuffer` - A buffer for uploading dynamically sized data to the GPU, used for chunk section layers. + - `VertexConsumer` + - `putBulkData` -> `putBlockBakedQuad`, `putBakedQuad`; not one-to-one + - Brightness `float` array, color `float`s, lightmap `int` array, and overlay `int` are replaced with `QuadInstance` + - `putBlockBakedQuad` replaces the `PoseStack$Pose` with the XYZ `float` block position + - `addVertex(PoseStack$Pose, Vector3f)` -> `addVertex(PoseStack$Pose, Vector3fc)` + - `setNormal(PoseStack$Pose, Vector3f)` -> `setNormal(PoseStack$Pose, Vector3fc)` +- `com.mojang.math` + - `MatrixUtil` + - `checkPropertyRaw` is now `public` from `private` + - `isOrthonormal` is removed + - `Transformation` + - `IDENTITY` is now `public` from `private` + - Replaces `identity` method + - `getTranslation` -> `translation` + - `getLeftRotation` -> `leftRotation` + - `getScale` -> `scale` + - `getRightRotation` -> `rightRotation` + - `compose` - Applies the transformation to the given matrix, if present. +- `net.minecraft.SharedConstants` + - `DEBUG_DUMP_INTERPOLATED_TEXTURE_FRAMES` is removed + - `DEBUG_PREFER_WAYLAND` - When true, prevents the platform initialization hint from being set to X11 if both Wayland and X11 are supported. +- `net.minecraft.client` + - `Camera` + - `BASE_HUD_FOV` - The base hud field-of-view. + - `setup` -> `update`, not one-to-one + - `extractRenderState` - Extract the state of the camera. + - `getFov` - Gets the field-of-view. + - `getViewRotationMatrix` - Gets the matrix for a projection view. + - `setEntity` - Sets the entity the camera is attached to. + - `getNearPlane` now takes in the `float` field-of-view + - `panoramicForwards` - The forward vector when in panorama mode. + - `getPartialTickTime` is removed + - `setLevel` - Sets the level the camera is in. + - `getCameraEntityPartialTicks` - Gets the partial tick based on the state of the entity. + - `DeltaTracker#advanceTime` replaced by `advanceGameTime` when the `boolean` was `true`, and `advanceRealTime` + - `advanceGameTime`, `advanceRealTime` were previously `private`, now `public` + - `FramerateLimiter` - A utility for limiting the framerate of the client. + - `Minecraft` + - `noRender` is removed + - `useAmbientOcclusion` is removed + - `getBlockRenderer` is removed + - `getItemRenderer` is removed + - `Options` + - `getCloudsType` -> `getCloudStatus` + - `exclusiveFullscreen` - When `true`, fullscreen mode takes full control of the monitor. +- `net.minecraft.client.color.block` + - `BlockColor` replaced by `BlockTintSource`, not one-to-one + - `getColor` -> `colorInWorld`, `colorAsTerrainParticle`; not one-to-one + - `BlockColors` + - `getColor` replaced by `getTintSources`, `getTintSource`; not one-to-one + - `register` now takes in a list of `BlockTintSource`s instead of a `BlockColor` + - `BlockTintSource` - A source for how to tint a `BlockState` in isolation or with context. + - `BlockTintSources` - Utilites for common block tint sources. +- `net.minecraft.client.data.models` + - `BlockModelGenerators` + - `createSuffixedVariant` now takes in a function of `Material` to `TextureMapping` for the textures instead of just an `Identifier` + - `createAirLikeBlock` now takes in a `Material` instead of an `Identifier` for the particle texture + - `generateSimpleSpecialItemModel` now takes in an optional `Transformation` + - `createChest` now has an overload that takes in the `MutiblockChestResources` textures + - `ItemModelGenerators#generateLayeredItem` now takes in `Material`s instead of `Identifier`s for the textures +- `net.minecraft.client.data.models.model` + - `ItemModelUtils` + - `specialModel` now has overloads that take in the `Transformation` + - `conditional` now has overloads that take in the `Transformation` + - `select` now has an overload that takes in the `Transformation` + - `selectBlockItemProperty` now has an overload that takes in the `Transformation` + - `TexturedModel#createAllSame` now takes in a `Material` instead of an `Identifier` for the texture + - `TextureMapping` + - `put`, `putForced` now take in a `Material` instead of an `Identifier` for the texture + - `get` now returns a `Material` instead of an `Identifier` for the texture + - `copyAndUpdate` now takes in a `Material` instead of an `Identifier` for the texture + - `updateSlots` - Replaces all slots using the provided mapper function. + - `forceAllTranslucent` - Sets the force translucency flag for all material textures. + - `defaultTexture`, `cube`, `cross`, `plant`, `rail`, `wool`, `crop`, `singleSlot`, `particle`, `torch`, `cauldron`, `layer0` now take in a `Material` instead of an `Identifier` for the texture + - `column`, `door`, `layered` now take in `Material`s instead of `Identifier`s for the textures + - `getBlockTeture`, `getItemTexture` now return a `Material` instead of an `Identifier` for the texture +- `net.minecraft.client.entity.ClientAvatarEntity#belowNameDisplay` -> `Entity#belowNameDisplay` +- `net.minecraft.client.gui` + - `Font` + - `drawInBatch`, `drawInBatch8xOutline` now take in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `$GlyphVisitor#forMultiBufferSource` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `Gui` + - `render*` methods have been renamed to `extract*` + - `render` -> `extractRenderState` + - `$RenderFunction` interface is removed + - `GuiGraphics` -> `GuiGraphicsExtractor` + - `hLine` -> `horizontalLine` + - `vLine` -> `verticalLine` + - `renderOutline` -> `outline` + - `drawCenteredString` -> `centeredText` + - `drawString` -> `text` + - `drawStringWithBackdrop` -> `textWithBackdrop` + - `renderItem` -> `item` + - `renderFakeItem` -> `fakeItem` + - `renderItemDecorations` -> `itemDecorations` + - `submitMapRenderState` -> `map` + - `submitEntityRenderState` -> `entity` + - `submitSkinRenderState` -> `skin` + - `submitBookModelRenderState` -> `book` + - `submitBannerPatternRenderState` -> `bannerPattern` + - `submitSignRenderState` -> `sign` + - `submitProfilerChartRenderState` -> `profilerChart` + - `renderTooltip` -> `tooltip` + - `renderComponentHoverEffect` -> `componentHoverEffect`, now `private` instead of `public` +- `net.minecraft.client.gui.components` + - Most methods that begin with `render*` or `draw*` have been renamed to either `extract*` or `extract*RenderState` depending on usage. + - `AbstractWidget#renderWidget` -> `extractWidgetRenderState` + - `DebugScreenOverlay#render3dCrosshair` now takes in the `CameraRenderState` instead of the `Camera`, and the gui scale `int` + - `LogoRenderer#renderLogo` -> `extractRenderState` + - `PlayerFaceRenderer` -> `PlayerFaceExtractor` + - `draw` -> `extractRenderState` + - `Renderable#render` -> `extractRenderState` + - `StringWidget#clipText` -> `ComponentRenderUtils#clipText` + - `TextCursorUtils#draw*` -> `extract*` +- `net.minecraft.client.gui.components.debugchart` + - `AbstractDebugChart` + - `drawChart` -> `extractRenderState` + - `drawDimensions` -> `extractSampleBars` + - `drawMainDimension` -> `extractMainSampleBar` + - `drawAdditionalDimensions` -> `extractAdditionalSampleBars` + - `renderAdditionalLinesAndLabels` -> `extractAdditionalLinesAndLabels` + - `drawStringWithShade` -> `extractStringWithShade` + - `ProfilerPieChart#render` -> `extractRenderState` +- `net.minecraft.client.gui.components.spectator.SpectatorGui#render*` -> `extract*` +- `net.minecraft.client.gui.components.toasts` + - `NowPlayingToast#renderToast` -> `extractToast` + - `Toast#render` -> `extractRenderState` + - `ToastManager`, `$ToastInstance#render` -> `extractRenderState` + - `TutorialToast$Icons#render` -> `extractRenderState` +- `net.minecraft.client.gui.contextualbar.ContextualBarRenderer` + - `renderBackground` -> `extractBackground` + - `render` -> `extractRenderState` + - `renderExperienceLevel` -> `extractExperienceLevel` +- `net.minecraft.client.gui.font` + - `PlainTextRenderable#renderSprite` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `TextRenderable#render` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose +- `net.minecraft.client.gui.render` + - `DynamicAtlasAllocator` - An allocator for handling a dynamically sized texture atlas. + - `GuiItemAtlas` - An atlas for all items displayed in a user interface. + - `GuiRenderer#incrementFrameNumber` -> `endFrame`, not one-to-one +- `net.minecraft.client.gui.render.state.*` -> `.client.rendererer.state.gui.*` + - `GuiItemRenderState` no longer takes in the `String` name + - `name` is removed +- `net.minecraft.client.gui.render.state.pip.*` -> `.client.rendererer.state.gui.pip.*` +- `net.minecraft.client.gui.screens` + - `LevelLoadingScreen#renderChunks` -> `extractChunksForRendering` + - `Screen` + - `renderWithTooltipAndSubtitles` -> `extractRenderStateWithTooltipAndSubtitles` + - `renderBackground` -> `extractBackground` + - `renderBlurredBackground` -> `extractBlurredBackground` + - `renderPanorama` -> `extractPanorama` + - `renderMenuBackground` -> `extractMenuBackground` + - `renderMenuBackgroundTexture` -> `extractMenuBackgroundTexture` + - `renderTransparentBackground` -> `extractTransparentBackground` +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementTab#draw*` -> `extract*` + - `AdvancementTabType` + - `draw` -> `extractRenderState` + - `drawIcon` -> `extractIcon` + - `AdvancementWidget` + - `draw` -> `extractRenderState` + - `draw*` -> `extract*` +- `net.minecraft.client.gui.screens.inventory` + - Most methods that begin with `render*` or `draw*` have been renamed to either `extract*` or `extract*RenderState` depending on usage. + - `AbstractContainerScreen` + - `renderContents` -> `extractContents` + - `renderCarriedItem` -> `extractCarriedItem` + - `renderSnapbackItem` -> `extractSnapbackItem` + - `renderSlots` -> `extractSlots` + - `renderTooltip` -> `extractTooltip` + - `renderLabels` -> `extractLabels` + - `renderBg` replaced by `Screen#extractBackground` + - `renderSlot` -> `extractSlot` + - `AbstractMountInventoryScreen#drawSlot` -> `extractSlot` + - `AbstractSignEditScreen#renderSignBackground` -> `extractSignBackground` + - `CyclingSlotBackground#render` -> `extractRenderState` + - `EffectsInInventory#render` -> `extractRenderState` + - `InventoryScreen#renderEntityInInventoryFollowsMouse` -> `extractEntityInInventoryFollowsMouse` + - `ItemCombinerScreen#renderErrorIcon` -> `extractErrorIcon` +- `net.minecraft.client.gui.screens.inventory.tooltip` + - `ClientTooltipComponent` + - `renderText` -> `extractText` + - `renderImage` -> `extractImage` + - `TooltipRenderUtil#renderTooltipBackground` -> `extractTooltipBackground` +- `net.minecraft.client.gui.screens.options` + - `DifficultyButtons` is now a record that takes in the `LayoutElement`, `CycleButton` for the difficulty, the `LockIconButton`, and the current `Level` + - `create` now takes in the `Level` and returns the `DifficultyButtons` instead of a `LayoutElement` + - `refresh` - Sets the data of the held button components. + - `HasDifficultyReaction` - An interface that responds to when the difficulty has changed. + - `OptionsScreen` now implements `HasDifficultyReaction` + - `WorldOptionsScreen` now implements `HasDifficultyReaction` + - The constructor now takes in the `Level` +- `net.minecraft.client.gui.screens.recipebook` + - `GhostSlots` + - `render` -> `extractRenderState` + - `renderTooltip` -> `extractTooltip` + - `RecipeBookComponent#render*` -> `extract*` + - `RecipeBookPage` + - `render` -> `extractRenderState` + - `renderTooltip` -> `extractTooltip` +- `net.minecraft.cilent.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#renderItem` -> `extractItem` +- `net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen$GameRuleEntry#renderLabel` -> `extractLabel` +- `net.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon` -> `extractIcon` +- `net.minecraft.client.model.Model#renderType` now has an overload that returns the passed in function +- `net.minecraft.client.model.object.book.BookModel$State` no longer takes in the animation pos, and moves the open `float` to the first parameter + - `forAnimation` - Gets the current state of the animation for the book based on the progress. +- `net.minecraft.client.model.object.statue.CopperGolemStatueModel` now uses `Unit` for the generic instead of `Direction` +- `net.minecraft.client.multiplayer.ClientLevel` now implements `BlockAndTintGetter` + - `update` - Updates the lighting of the level. +- `net.minecraft.client.multiplayer.chat.GuiMessageTag$Icon#draw` -> `extractRenderState` +- `net.minecraft.client.particle` + - `Particle#getLightColor` -> `getLightCoords` + - `SimpleVerticalParticle` - A particle that moves vertically. + - `SingleQuadParticle$Layer` + - `TERRAIN` -> `OPAQUE_TERRAIN`, `TRANSLUCENT_TERRAIN` + - `ITEMS` -> `OPAQUE_ITEMS`, `TRANSLUCENT_ITEMS` + - `bySprite` - Gets the layer from the atlas sprite. +- `net.minecraft.client.renderer` + - `CachedOrthoProjectionMatrixBuffer`, `CachedPerspectiveProjectionMatrixBuffer`, `PerspectiveProjectionMatrixBuffer` -> `ProjectionMatrixBuffer` with sometimes `Projection`, not one-to-one + - `CloudRenderer` now takes in the cloud range `int` + - `CubeMap` no longer takes in the `Minecraft` instance + - `GameRenderer` now takes in the `ModelManager` instead of the `BlockRenderDispatcher` + - `PROJECTION_Z_NEAR` -> `Camera#PROJECTION_Z_NEAR` + - `setPanoramicScreenshotParameters`, `getPanoramicScreenshotParameters` -> `Camera#enablePanoramicMode`, `disablePanoramicMode`; not one-to-one + - `isPanoramicMode` -> `Camera#isPanoramicMode` + - `getProjectionMatrix` -> `Camera#getViewRotationProjectionMatrix`, not one-to-one + - `updateCamera` -> `Camera#update`, not one-to-one + - `getRenderDistance` is removed + - `cubeMap` -> `GuiRenderer#cubeMap`, now `private` from `protected` + - `getDarkenWorldAmount` -> `getBossOverlayWorldDarkening` + - `lightTexture` -> `lightmap`, `levelLightmap`; not one-to-one + - `getLevelRenderState` replaced by `getGameRenderState`, returning the `GameRenderState` instead of the `LevelRenderState` + - `pick` -> `Minecraft#pick`, now `private` from `public` + - `render` split between `update`, `extract`, and `render`; with the `boolean` now taking in whether to advance the game time rather than render the level + - `GlobalSettingsUniform` now takes in the `Vec3` camera position instead of the main `Camera` itself + - `ItemBlockRenderTypes` is removed + - `getChunkRenderType`, `getMovingBlockRenderType` now stored within `BakedQuad$SpriteInfo` + - `getRenderLayer(FluidState)` -> `FluidModel#layer`, not one-to-one + - `setCutoutLeaves` is removed + - This should be obtained directly from the options + - `MultiblockChestResources` - A record containing some data based on the `ChestType`. + - `LevelRenderer` now takes in the `GameRenderState` instaed of the `LevelRenderState` + - `update` - Updates the level. + - `renderLevel` now takes in the `CameraRenderState` instead of the `Camera`, a `Matrix4fc` instead of a `Matrix4f` from the model view, and the `ChunkSectionsToRender`; it no longer takes in the `Matrix3f` for the projection matrices + - `extractLevel` - Extracts the level state. + - `prepareChunkRenders` is now `public` instead of `private` + - `captureFrustum`, `killFrustum`, `getCapturedFrustum` are removed + - `getLightColor` -> `getLightCoords`, now taking in the `BlockAndLightGetter` instead of the `BlockAndTintGetter` + - `$BrightnessGetter#packedBrightness` now takes in the `BlockAndLightGetter` instead of the `BlockAndTintGetter` + - `LightTexture` -> `Lightmap` + - `tick` -> `LightmapRenderStateExtractor#tick` + - `updateLightTexture` -> `render` + - `pack` -> `LightCoordsUtil#pack` + - `block` -> `LightCoordsUtil#block` + - `sky` -> `LightCoordsUtil#sky` + - `lightCoordsWithEmission` -> `LightCoordsUtil#lightCoordsWithEmission` + - `MaterialMapper` -> `SpriteMapper` + - `OrderedSubmitNodeCollector` + - `submitBlock` is removed + - `submitBlockModel` now takes in a list of `BlockStateModelPart`s instead of the `BlockStateModel`, and an array of `int`s (array of tint colors) instead of three `float`s for a single color + - `submitItem` no longer takes in the `RenderType` + - `submitModel` now has overloads that takes in the `Identifier` for the texture, or a `SpriteId` with the `SpriteGetter` along with an `int` tint color + - `submitBreakingBlockModel` - Submits the block breaking overlay. + - `PanoramaRenderer` replaced by `Panorama` + - `registerTextures` -> `GuiRenderer#registerPanoramaTextures` + - `render` -> `extractRenderState` + - `PanoramicScreenshotParameters` record is removed + - `PostChain` now takes in a `Projection` and `ProjectionMatrixBuffer` instead of an `CachedOrthoProjectionMatrixBuffer` + - `load` now takes in a `Projection` and `ProjectionMatrixBuffer` instead of an `CachedOrthoProjectionMatrixBuffer` + - `RenderPipelines` + - `ENTITY_CUTOUT_NO_CULL` -> `ENTITY_CUTOUT` + - The original cutout with cull is replaced by `ENTITY_CUTOUT_CULL` + - `ENTITY_CUTOUT_NO_CULL_Z_OFFSET` -> `ENTITY_CUTOUT_Z_OFFSET` + - `ENTITY_SMOOTH_CUTOUT` -> `END_CRYSTAL_BEAM` + - `ENTITY_NO_OUTLINE` replaced by `ENTITY_TRANSLUCENT`, render type constructed with affects outline being false + - `ENTITY_DECAL`, `DRAGON_EXPLOSION_ALPHA` -> `ENTITY_CUTOUT_DISSOLVE`, not one-to-one + - `ITEM_ENTITY_TRANSLUCENT_CULL` -> `ENTITY_TRANSLUCENT_CULL`, `ITEM_CUTOUT`, `ITEM_TRANSLUCENT`; not one-to-one + - `TRANSLUCENT_MOVING_BLOCK` replaced by `TRANSLUCENT_BLOCK` + - `BANNER_PATTERN` - A pipeline for rendering the patterns on a banner. + - `ScreenEffectRenderer#renderScreenEffect` now takes in `boolean`s for whether the player is in first person and whether to hide the GUI + - `Sheets` + - `*CHEST_*LOCATION*` have been combined into one of the `CHEST_*` fields based on what the resource was for + - `translucentBlockSheet` - A cullable entity item translucent render type using the block atlas. + - `cutoutBlockItemSheet` - An item cutout render type using the block atlas. + - `bannerSheet` -> `RenderTypes#entityTranslucent`, not one-to-one + - `cutoutItemSheet` - An item cutout render type using the item atlas. + - `get*Material` -> `get*Sprite` + - `chooseMaterial` -> `chooseSprite` + - `SpecialBlockModelRenderer` replaced by `BuiltInBlockModels`, not one-to-one + - `renderByBlock` -> `BlockModelRenderState#submit*`, not one-to-one + - `SubmitNodeCollection` + - `getBlockSubmits` is removed + - `getBreakingBlockModelSubmits` - Gets the submitted breaking block overlay. + - `SubmitNodeCollector$ParticleGroupRenderer` + - `isEmpty` - Whether there are no particles to render in this group. + - `prepare` now takes whether the particles are being prepared for the translucent layer + - `render` no longer takes in the translucent `boolean` + - `SubmitNodeStorage` + - `$BlockModelSubmit` now takes in a list of `BlockStateModelPart`s instead of the `BlockStateModel`, and an array of `int`s (array of tint colors) instead of three `float`s for a single color + - `$BlockSubmit` is removed + - `$BreakingBlockModelSubmit` - A record containing the information to render the block breaking overlay. + - `$ItemSubmit` no longer takes in the `RenderType` + - `$MovingBlockSubmit`, `$NameTagSubmit`, `$ShadowSubmit`, `$TextSubmit` now take in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `VirtualScreen` replaced by `GpuBackend` +- `net.minecraft.client.renderer.block` + - `BlockAndTintGetter` - A getter for positional block tinting (e.g., biomes). + - `BlockModelRenderState` - The render state for a block model. + - `BlockModelResolver` - A helper for setting up the render state for a `BlockState`. + - `BlockModelSet` - Holds the `BlockModel` associated with each `BlockState`. + - `BlockModelShaper` -> `BlockStateModelSet`, not one-to-one + - `getParticleIcon` -> `getParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `getBlockModel` -> `get` + - `getModelManager`, `replaceCache` are removed + - `BlockQuadOutput` - A functional interface for writing the baked quad information to some output, like a buffer. + - `BlockRenderDispatcher` class is removed + - `getBlockModelShaper` -> `getModelSet`, not one-to-one + - `renderBreakingTexture` replaced with `SubmitNodeCollector#submitBreakingBlockModel` + - `renderBatched` replaced with direct call to `ModelBlockRenderer#tesselateBlock` + - `renderLiquid` replaced with direct call to `FluidRenderer#tesselate` + - `renderSingleBlock` is now inlined within `BlockFeatureRenderer#renderBlockModelSubmits`, a `private` method + - Use `ModelBlockRenderer#tesselateBlock` as an alternative + - `FluidModel` - The base fluid model that holds the data for the renderer. + - `FluidStateModelSet` - Holds the `FluidModel` associated with each `Fluid`. + - `LoadedBlockModels` - A task for baking the `BlockModel` for each `BlockState`. + - `LiquidBlockRenderer` -> `FluidRenderer`, not one-to-one + - The constructor now takes in the `FluidStateModelSet` instead of the `SpriteGetter` + - `tesselate` now takes in a `FluidRenderer$Output` instead of a `VertexConsumer` + - `$Output` - Gets the `VertexConsumer` to use for the `ChunkSectionLayer`. + - `ModelBlockRenderer` now takes in `boolean`s for ambient occlusion and culling + - `tesselateBlock` now takes in a `BlockQuadOutput` instead of a `VertexConsumer`, the XYZ `float`s instead of a `PoseStack`, the `BlockStateModel` instead of the list of `BlockModelPart`s, no longer takes in the cull `boolean` and `int` overlay, and takes in the seed `long` + - `tesselateWithAO` -> `tesselateAmbientOcclusion`, now `private` instead of `public` + - `tesselateWithoutAO` -> `tesselateFlat`, now `private` instead of `public` + - `renderModel` is now inlined within `BlockFeatureRenderer#renderBlockModelSubmits`, a `private` method + - `forceOpaque` - Whether the block textures should be opaque instead of translucent. + - `enableCaching` -> `BlockModelLighter$Cache#enable` + - `clearCache` -> `BlockModelLighter$Cache#disable` + - `$AdjacencyInfo` -> `BlockModelLighter$AdjacencyInfo`, now `private` instead of `protected` + - `$AmbientOcclusionRenderStorage` is replaced by `BlockModelLighter`, not one-to-one + - `$AmbientVertexRemap` -> `BlockModelLighter$AmbientVertexRemap` + - `$Cache` -> `BlockModelLighter$Cache` + - `$CommonRenderStorage` is replaced by `BlockModelLighter`, not one-to-one + - `$SizeInfo` -> `BlockModelLighter$SizeInfo` + - `MovingBlockRenderState#level` -> `cardinalLighting`, `lightEngine`; not one-to-one + - `SelectBlockModel` - A block model that determined or selected by its resolved property. +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` -> `.client.resources.model.geometry.BakedQuad` + - The constructor now takes in a `$MaterialInfo` instead of the `TextureAtlasSprite`, `int` tint index, `int` light emission, and `boolean` shade + - `FLAG_TRANSLUCENT` - A flag that marks the baked quad has having translucency. + - `FLAG_ANIMATED` - A flag that marks the baked quad has having an animated texture. + - `isTinted` -> `$MaterialInfo#isTinted` + - `$MaterialFlags` - An annotation that marks whether a given integer defines the flags for a material. + - `$MaterialInfo` - A record holding the information on how to render the quad. + - `BlockDisplayContext` - An object that represents the display context of a block. + - `BlockElement` -> `.client.resources.model.cuboid.CuboidModelElement` + - `BlockElementFace` -> `.client.resources.model.cuboid.CuboidFace` + - `BlockElementRotation` -> `.client.resources.model.cuboid.CuboidRotation` + - `BlockModel` - The base block model that updates the render state for use outside the world context. + - The original implementation has been moved to `.client.resources.model.cuboid.CuboidModel` + - `BlockModelDefinition` -> `.block.dispatch.BlockStateModelDispatcher` + - `BlockModelPart` -> `.block.dispatch.BlockStateModelPart` + - `particleIcon` -> `particleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `materialFlags` - Handles the flags for the material(s) used by the model. + - `BlockStateModel` -> `.block.dispatch.BlockStateModel` + - `particleIcon` -> `particleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `materialFlags`, `hasMaterialFlag` - Handles the flags for the material(s) used by the model. + - `BlockStateModelWrapper` - The basic block model that contains the model, tints, and transformation. + - `CompositeBlockModel` - Overlays multiple block models together. + - `ConditionalBlockModel` - A block model that shows a different model based on a boolean obtained from some property. + - `EmptyBlockModel` - A block model that shows nothing. + - `FaceBakery` -> `.client.resources.model.cuboid.FaceBakery` + - `bakeQuad` overload now takes in a `ModelBaker` instead of the `ModelBaker$PartCache`, and a `Material$Baked` instead of a `TextureAtlasSprite` + - It also has an overload taking in the fields of the `BlockElementFace` instead of the object itself + - Another `bakedQuad` ovrload now takes in the `BakedQuad$MaterialInfo` instead of the `int` tint index and light emission, and the shade `boolean` + - `ItemModelGenerator` -> `.client.resources.model.cuboid.ItemModelGenerator` + - `ItemTransform` -> `.client.resources.model.cuboid.ItemTransform` + - `ItemTransforms` -> `.client.resources.model.cuboid.ItemTransforms` + - `SimpleModelWrapper` -> `.client.resources.model.SimpleModelWrapper` + - The constructor now takes in a `Material$Baked` instead of a `TextureAtlasSprite` for the particle + - `SimpleUnbakedGeometry` -> `.client.resources.model.cuboid.UnbakedCuboidGeometry` + - `SingleVariant` -> `.block.dispatch.SingleVariant` + - `SpecialBlockModelWrapper` - A block model for models that submit their elements through `SpecialModelRenderer`s. + - `TextureSlots` -> `.client.resources.model.sprite.TextureSlots` + - `Variant` -> `.block.dispatch.Variant` + - `VariantMutator` -> `.block.dispatch.VariantMutator` + - `VariantSelector` -> `.block.dispatch.VariantSelector` +- `net.minecraft.client.renderer.block.model.multipart.*` -> `.block.dispatch.multipart.*` +- `net.minecraft.client.renderer.block.model.properties.conditional` + - `ConditionalBlockModelProperty` - A property that computes some `boolean` from the `BlockState`. + - `IsXmas` - Returns whether the current time is between December 24th - 26th. +- `net.minecraft.client.renderer.block.model.properties.select` + - `DisplayContext` - A case based on the current `BlockDisplayContext`. + - `SelectBlockModelProperty` - A property that computes some switch state from the `BlockState`. +- `net.minecraft.client.renderer.blockentity` + - `AbstractEndPortalRenderer` + - `renderCube` -> `submitCube`, now `protected` and `static` from `private` + - `submitSpecial` - Submits the end portal cube, used by the special renderer. + - `getExtents` - Gets the vertices of each face. + - `getOffsetUp`, `getOffsetDown` are removed + - `renderType` is removed + - `AbstractSignRenderer` now takes in a generic for the `SignRenderState` + - `getSignModel` now takes in the `SignRenderState` generic instead of the `BlockState` and `WoodType` + - `getSignModelRenderScale`, `getSignTextRenderScale`, `getTextOffset`, `translateSign` replaced by `SignRenderState#transformations`, `SignRenderState$SignTransformations` + - `getSignMaterial` -> `getSignSprite` + - `BannerRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `submitPatterns` no longer takes in the base `SpriteId`, whether the pattern has foil, and the outline color + - `submitSpecial` now takes in the `BannerBlock$AttachmentType` + - `BedRenderer` + - `submitSpecial` is removed + - This is replaced by calling `submitPiece` twice, or making a composite for each bed part via the `BedSpecialRenderer` + - `submitPiece` is now `public` from `private`, taking in the `BedPart` instead of the `Model$Simple`, `Direction`, or the `boolean` of whether to translate in the Z direction + - `getExtents` now takes in the `BedPart` + - `modelTransform` - Gets the transformation for the given `Direction`. + - `BlockEntityRenderDispatcher` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher`, and no longer takes in the `ItemRenderer` + - `prepare` now takes in a `Vec3` camera position instead of the `Camera` itself + - `BlockEntityRendererProvider$Context` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher`, and no longer takes in the `ItemRenderer` + - `materials` -> `sprites` + - `ChestRenderer` + - `LAYERS` - Holds the model layers of the chest. + - `modelTransformation` - Gets the transformation for the given `Direction`. + - `ConduitRenderer#DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `CopperGolemStatueBlockRenderer#modelTransformation` - Gets the transformation for the given `Direction`. + - `DecoratedPotRenderer#modelTransformation` - Gets the transformation for the given `Direction`. + - `HangingSignRenderer` now uses a `HangingSignRenderState` + - `MODEL_RENDER_SCALE` is now `private` from `public` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `translateBase` -> `baseTransformation`, now `private` from `public` + - `$AttachmentType` -> `HangingSignBlock$Attachment` + - `byBlockState` -> `$Models#get` + - `$ModelKey` record is removed + - `ShulkerBoxRenderer` + - `modelTransform` - Gets the transformation for the given `Direction`. + - `getExtents` no longer takes in the `Direction` + - `SignRenderer` -> `StandingSignRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `createSignModel` now takes in a `PlainSignBlock$Attachment` instead of a `boolean` for whether the block is standing + - `SkullBlockRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `submitSkull` no longer takes in the `Direction` or `float` rotation + - `WallAndGroundTransformations` - A class that holds a map of `Direction`s to transforms to apply for the wall, and an `int` function to compute the ground transformations, with the `int` segments generally acting as the number of rotation states. +- `net.minecraft.client.renderer.blockentity.state` + - `BannerRenderState` + - `angle` -> `transformation`, not one-to-one + - `standing` -> `attachmentType`, not one-to-one + - `BedRenderState#isHead` -> `part`, not one-to-one + - `BlockEntityRenderState#blockState` is now `private` from `public` + - `ChestRenderState#angle` -> `facing`, not one-to-one + - `CondiutRenderState` -> `ConduitRenderState` + - `CopperGolemStatueRenderState#oxidationState` - The current oxidation state. + - `HangingSignRenderState` - The render state for the hanging sign. + - `ShelfRenderState#facing` - The direction the shelf is facing. + - `SignRenderState#woodType` - The type of wood the sign is made of. + - `SkullblockRenderState#direction`, `rotationDegrees` -> `transformation`, not one-to-one + - `StandingSignRenderState` - The render state for the standing sign. +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` now takes in a `boolean` for whether the layer is translucent rather than just sorting on upload + - `byTransparency` - Gets the layer by its transparency setting. + - `sortOnUpload` -> `translucent`, not one-to-one + - `vertexFormat` - The vertex format of the pipeline used by the layer. + - `ChunkSectionsToRender#drawsPerLayer` -> `drawGroupsPerLayer`, with its value being a `int` to list of draws map + - `CompiledSectionMesh` + - `uploadMeshLayer` replaced by `isVertexBufferUploaded`, `setVertexBufferUploaded` + - `uploadLayerIndexBuffer` replaced by `isIndexBufferUploaded`, `setIndexBufferUploaded` + - `RenderRegionCache#createRegion` now takes in the `ClientLevel` instead of the `Level` + - `SectionBuffers` -> `SectionRenderDispatcher$RenderSectionBufferSlice`, not one-to-one + - `SectionCompiler` now takes in the `boolean`s for ambient occlusion and cutout leaves, the `BlockStateModelSet`, the `FluidStateModelSet`, and the `BlockColors` instead of the `BlockRenderDispatcher` + - `SectionMesh` + - `getBuffers` -> `getSectionDraw`, not one-to-one + - `$SectionDraw` - The draw information for the section. + - `SectionRenderDispatcher` now takes in the `SectionCompiler` instead of the `BlockRenderDispatcher` and `BlockEntityRenderDispatcher` + - `getRenderSectionSlice` - Gets the buffer slice of the section mesh to render for the chunk layer. + - `uploadAllPendingUploads` -> `uploadGlobalGeomBuffersToGPU`, not one-to-one + - `lock`, `unlock` - Handles locking the dispatcher when copying data from location to another, usually for GPU allocation. + - `getToUpload` is removed + - `setLevel` now takes in the `SectionCompiler` + - `$RenderSection` + - `upload`, `uploadSectionIndexBuffer` -> `addSectionBuffersToUberBuffer`, now private + - `$CompileTask` + - `doTask` now returns a `$SectionTaskResult` instead of a `CompletableFuture` + - `$SectionTaskResult` -> `$RenderSection$CompileTask$SectionTaskResult` +- `net.minecraft.client.renderer.culling.Frustum` now takes in a `Matrix4fc` instead of a `Matrix4f` for the model view + - `set` - Copies the information from another frustum. +- `net.minecraft.client.renderer.entity` + - `AbstractBoatRenderer` now takes in the `Identifier` texture + - `renderType` is removed + - `AbstractMinecartRenderer` + - `BLOCK_DISPLAY_CONTEXT` - The context of how to display the block inside the minecart. + - `submitMinecartContents` now takes in a `BlockModelRenderState` instead of the `BlockState` + - `CopperGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the antenna block. + - `DisplayRenderer` + - `BLOCK_DISPLAY_CONTEXT` - The context of how to display the displayed block. + - `blockModelResolver` - The block model resolver. + - `EndermanRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the held block. + - `EntityRenderDispatcher` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher` + - `EntityRenderer#submitNameTag` -> `submitNameDisplay`, now optionally taking in the y position `int` as an offset from the name tag attachment + - `EntityRendererProvider$Context` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher` + - `getMaterials` -> `getSprites` + - `getBlockRenderDispatcher` replaced by `getBlockModelResolver` + - `IronGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the held block. + - `ItemFrameRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the displayed block. + - `ItemRenderer` class is removed + - Use the `ItemStackRenderState` to submit elements to the feature dispatcher instead + - `ENCHANTED_GLINT_ARMOR` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ARMOR` + - `ENCHANTED_GLINT_ITEM` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ITEM` + - `NO_TINT` -> `ItemFeatureRenderer#NO_TINT` + - `getFoilBuffer` -> `ItemFeatureRenderer#getFoilBuffer` + - `getFoilRenderType` -> `ItemFeatureRenderer#getFoilRenderType`, now `public` from `private` + - `MushroomCowRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the attached blocks. + - `SnowGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the head block. + - `TntRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the TNT block. + - `TntMinecartRenderer#submitWhiteSolidBlock` now takes in a `BlockModelRenderState` instead of the `BlockState` +- `net.minecraft.client.renderer.entity.layers` + - `BlockDecorationLayer` now takes in a function that returns a `BlockModelRenderState` instead of an optional `BlockState` + - `MushroomCowMushroomLayer` no longer takes in the `BlockRenderDispatcher` + - `SnowGolemHeadLayer` no longer takes in the `BlockRenderDispatcher` +- `net.minecraft.client.renderer.entity.state` + - `AvatarRenderState#scoreText` -> `EntityRenderState#scoreText` + - `BlockDisplayEntityRenderState#blockRenderState` -> `blockModel`, now a `BlockModelRenderState` instead of a `BlockRenderState` + - `CopperGolemRenderState#blockOnAntenna` now a `BlockModelRenderState` instead of an optional `BlockState` + - `EndermanRenderState#carriedBlock` now a `BlockModelRenderState` instead of a nullable `BlockState` + - `IronGolemRenderState#flowerBlock` - The flower held by the iron golem. + - `ItemFrameRenderState#frameModel` - The model of the item frame block. + - `MinecartRenderState#displayBlockState` -> `displayBlockModel`, now a `BlockModelRenderState` instead of a `BlockState` + - `MushroomCowRenderState#mushroomModel` - The model of mushrooms attached to the cow. + - `SnowGolemRenderState#hasPumpkin` -> `headBlock`, now a `BlockModelRenderState` instead of a `boolean` + - `TntRenderState#blockState` now a `BlockModelRenderState` instead of a nullable `BlockState` +- `net.minecraft.client.renderer.features` + - Feature `render` methods have been split into `renderSolid` for solid render types, and `renderTranslucent` for see-through render types + - Some `render*` methods now take in the `OptionsRenderState` + - `BlockFeatureRenderer` + - `renderSolid` now takes in the `BlockStateModelSet` instead of the `BlockRenderDispatcher` + - `renderTranslucent` now takes in the `BlockStateModelSet` and the crumbling `MultiBufferSource$BufferSource` instead of the `BlockRenderDispatcher` + - `FeatureRenderDispatcher` now takes in the `GameRenderState` and `ModelManager` + - `renderAllFeatures` has been split into `renderSolidFeatures` and `renderTranslucentFeatures` + - The original method now calls both of these methods, first solid then translucent + - `clearSubmitNodes` - Clears the submit node storage. + - `renderTranslucentParticles` - Renders collected translucent particles. + - `FlameFeatureRenderer#render` -> `renderSolid` + - `LeashFeatureRenderer#render` -> `renderSolid` + - `NameTagFeatureRenderer#render` -> `renderTranslucent` + - `ShadowFeatureRenderer#render` -> `renderTranslucent` + - `TextFeatureRenderer#render` -> `renderTranslucent` +- `net.minecraft.client.renderer.fog` + - `FogData#color` - The color of the fog. + - `FogRenderer` + - `setupFog` now returns a `FogData` instead of the `Vector4f` fog color + - `updateBuffer` - Updates the buffer with the fog data. +- `net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives#render` now takes in a `Matrix4fc` instead of a `Matrix4f` for the model view +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` -> `CuboidItemModelWrapper` + - The constructor no longer takes in the `RenderType` function, and now takes in the `Matrix4fc` transformation + - `$Unbaked` now takes in an optional `Transformation` + - `CompositeModel$Unbaked` now takes in an optional `Transformation` + - `ConiditionalItemModel$Unbaked` now takes in an optional `Transformation` + - `ItemModel` + - `$BakingContext` + - `materials` -> `sprites` + - `missingItem` - Gets the missing item model with the given `Matrix4fc` transformation. + - `$Unbaked#bake` now takes in the `Matrix4fc` transformation from any parent client items + - `ItemStackRenderState` + - `pickParticleIcon` -> `pickParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `$LayerRenderState` + - `EMPTY_TINTS` - An `int` array representing no tints to apply. + - `setRenderType` is removed + - `setParticleIcon` -> `setParticleMaterial`, now taking a `Material$Baked` instead of a `TextureAtlasSprite` + - `setTransform` -> `setItemTransform` + - `setLocalTransform` - Sets the client item transform that's applied after item display transforms. + - `prepareTintLayers` -> `tintLayers`, not one-to-one + - `MissingItemModel#withTransform` - Gets a missing item model with the given transform. + - `ModelRenderProperties#particleIcon` -> `particleMaterial`, now taking a `Material$Baked` instead of a `TextureAtlasSprite` + - `RangeSelectItemModel$Unbaked` now takes in an optional `Transformation` + - `SelectItemModel` + - `$ModelSelector#get` no longer supports nullable `ItemModel`s. + - `$Unbaked` now takes in an optional `Transformation` + - `$UnbakedSwitch#bake` now takes in the `Matrix4fc` transformation + - `SpecialModelWrapper` now takes in the `Matrix4fc` transformation + - `$Unbaked` now takes in an optional `Transformation` +- `net.minecraft.client.renderer.rendertype` + - `RenderType#outputTarget` - Gets the output target. + - `RenderTypes` + - `MOVING_BLOCK_SAMPLER` replaced by `createMovingBlockSetup`, now `private` + - `entityCutoutNoCull` -> `entityCutout` + - The original cutout with cull is replaced by `entityCutoutCull` + - `entityCutoutNoCullZOffset` -> `entityCutoutZOffset` + - `entitySmoothCutout` -> `endCrystalBeam` + - `entityNoOutline` -> `entityTranslucent` with `affectsOutline` as `false` + - `entityDecal`, `dragonExplosionAlpha` -> `entityCutoutDissolve`, not one-to-one + - `itemEntityTranslucentCull` -> `entityTranslucentCullItemTarget`, `itemCutout`, `itemTranslucent`; not one-to-one + - `bannerPattern` - The render type for rendering the patterns of banners. +- `net.minecraft.client.renderer.special` + - `BannerSpecialRenderer`, `$Unbaked` now take in the `BannerBlock$AttachmentType` + - `$Unbaked` now uses `BannerPatternLayers` for the generic + - `BedSpecialRenderer`, `$Unbaked` now take in the `BedPart` + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `BellSpecialRenderer` - A special renderer for the bell. + - `BookSpecialRenderer` - A special renderer for the book on the enchantment table. + - `ChestSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `ChestType` + - `*_CHEST_TEXTURE` is removed from the field name, now a `MultiBlockChestResources` + - `ENDER_CHEST_TEXTURE` -> `ENDER_CHEST` + - `ConduitSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `CopperGolemStatueSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `DecoratedPotSpecialRenderer$Unbaked` now uses `PotDecorations` for the generic + - `EndCubeSpecialRenderer` - A special renderer for the end portal cube. + - `HangingSignSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `HangingSignBlock$Attachment` + - `NoDataSpecialModelRenderer` + - `submit` no longer takes in the `ItemDisplayContext` + - `$Unbaked` - The unbaked renderer for a special model renderer not needing extracted data. + - `PlayerHeadSpecialRenderer$Unbaked` now uses `PlayerSkinRenderCache$RenderInfo` for the generic + - `ShieldSpecialRenderer` + - `DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `$Unbaked` now uses `DataComponentMap` for the generic + - `ShulkerBoxSpecialRenderer`, `$Unbaked` no longer takes in the `Direction` orientation + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `SkullSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `SpecialModelRenderer` + - `submit` no longer takes in the `ItemDisplayContext` + - `$BakingContext` + - `materials` -> `sprites` + - `$Simple` replaced by `BlockModel$BakingContext`, `ItemModel$BakingContext` + - `materials` -> `sprites` + - `$Unbaked` now has the generic of the argument to extract from the representing object + - `SpecialModelRenderers#createBlockRenderers` -> `BuiltInBlockModels#createBlockModels`, not one-to-one + - `StandingSignSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `PlainSignBlock$Attachment` + - `TridentSpecialRenderer` + - `DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` +- `net.minecraft.client.renderer.state.*` -> `.state.level.*` +- `net.minecraft.client.renderer.state` + - `GameRenderState` - The render state of the game. + - `OptionsRenderState` - The render state of the client user options. + - `WindowRenderState` - The render state of the game window. +- `net.minecraft.client.renderer.state.gui.GuiRenderState#submit*` methods have been renamed to `add*` +- `net.minecraft.client.renderer.state.level` + - `BlockBreakingRenderState` is now a record, and no longer extends `MovingBlockRenderState` + - The constructor takes in the `BlockPos`, `BlockState`, and the current `int` progress + - `CameraEntityRenderState` - The render state for the camera entity. + - `CameraRenderState` + - `xRot`, `yRot` - The rotation of the camera. + - `entityPos` is removed + - `isPanoramicMode` - Whether the camera is in panorama mode. + - `cullFrustum` - The cull frustum. + - `fogType`, `fogData` - Fog metadata. + - `hudFov` - The hud field-of-view. + - `depthFar` - The depth Z far plane. + - `projectionMatrix`, `viewRotationMatrix` - The matrices for moving from world space to screen space. + - `entityRenderState` - The entity the camera is attached to. + - `LevelRenderState` + - `lastEntityRenderStateCount` - The number of entities being rendered to the screen. + - `cloudColor`, `cloudHeight` - Cloud metadata. + - `LightmapRenderState` - The render state for the lightmap. +- `net.minecraft.client.renderer.texture` + - `MipmapGenerator#generateMipLevels` now takes in the computed `Transparency` of the image + - `SpriteContents` + - `transparency` - Gets the transparency of the sprite. + - `getUniqueFrames` now returns an `IntList` instaed of an `IntStream` + - `computeTransparency` - Computes the transparency of the selected UV bounds. + - `$AnimatedTexture#getUniqueFrames` now returns an `IntList` instaed of an `IntStream` + - `TextureAtlasSprite#transparency` - Gets the transparency of the sprite. +- `net.minecraft.client.resources.model` + - `AtlasManager` -> `.model.sprite.AtlasManager` + - `BlockModelRotation` -> `.client.renderer.block.dispatch.BlockModelRotation` + - `Material` -> `.model.sprite.SpriteId`, not one-to-one + - `MaterialSet` -> `.model.sprite.SpriteGetter` + - `MissingBlockModel` -> `.model.cuboid.MissingCuboidModel` + - `ModelBaker` + - `sprites` -> `materials` + - `parts` -> `interner` + - `$PartCache` -> `$Interner` + - `vector(float, float, float)` is removed + - `materialInfo` - Gets the interned material info object. + - `ModelBakery` + - `BANNER_BASE` -> `Sheets#BANNER_BASE` + - `SHIELD_BASE` -> `Sheets#SHIELD_BASE` + - `NO_PATTERN_SHIELD` -> `Sheets#SHIELD_BASE_NO_PATTERN` + - `LAVA_*` -> `FluidStateModelSet#LAVA_MODEL`, now `private` from `public` + - `WATER_*` -> `FluidStateModelSet#WATER_MODEL`, now `private` from `public` + - `$BakingResult#getBlockStateModel` - Gets the `BlockStateModel` from the `BlockState`. + - `$MissingModels` now takes in a `MissingItemModel` instead of an `ItemModel` for the `Item`, and a `FluidModel` + - `ModelManager` + - `BLOCK_OR_ITEM` is removed + - `getMissingBlockStateModel` -> `BlockStateModelSet#missingModel` + - `getBlockModelShaper` -> `getBlockStateModelSet`, not one-to-one + - `getBlockModelSet` - Gets the map of `BlockState` to block model. + - `specialBlockModelRenderer` is removed + - `getFluidStateModelSet` - Gets the map of `Fluid` to fluid model. + - `ModelState` -> `.client.renderer.block.dispatch.ModelState` + - `QuadCollection` -> `.model.geometry.QuadCollection` + - `addAll` - Adds all elements from another quad collection. + - `materialFlags`, `hasMaterialFlag` - Handles the flags for the material(s) used by the model. + - `ResolvedModel#resolveParticleSprite` -> `resolveParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `SpriteGetter` -> `.model.sprite.MaterialBaker` + - `UnbakedGeometry` -> `.model.geometry.UnbakedGeometry` + - `WeightedVariants` -> `.client.renderer.block.dispatch.WeightedVariants` +- `net.minecraft.client.resources.model.sprite.Material` - A reference to a texture sprite, along with whether to force translucency on the texture. +- `net.minecraft.world.entity.animal.Animal#isBrightEnoughToSpawn` now takes in a `BlockAndLightGetter` instead of the `BlockAndTintGetter` +- `net.minecraft.world.level` + - `BlockAndTintGetter` -> `BlockAndLightGetter` + - `BlockAndTintGetter` is now client only, implementing `BlockAndLightGetter` + - `getShade` -> `cardinalLighting`; not one-to-one + - `getBlockTint` -> `BlockAndTintGetter#getBlockTint` + - `CardinalLighting` - Holds the lighting applied in each direction. + - `EmptyBlockAndTintGetter` -> `BlockAndTintGetter#EMPTY` + - `LevelReader` now implements `BlockAndLightGetter` instead of `BlockAndTintGetter` +- `net.minecraft.world.level.block` + - `BannerBlock$AttachmentType` - Where the banner attaches to another block. + - `CeilingHangingSignBlock` now implements `HangingSignBlock` + - `getAttachmentPoint` - Gets where the sign attaches to another block. + - `HangingSignBlock` - An interface that defines a hanging sign attached to another block. + - `PlainSignBlock` - An inteface that defines a plain sign attached to another block. + - `StandingSignBlock` now implements `PlainSignBlock` + - `WallingHangingSignBlock` now implements `HangingSignBlock` + - `WallSignBlock` now implements `PlainSignBlock` +- `net.minecraft.world.level.block.state.BlockBehaviour#getLightBlock`, `$BlockStateBase#getLightBlock` -> `getLightDampening` +- `net.minecraft.world.level.block.state.properties` + - `BedPart#CODEC` - The codec for the bed part. + - `ChestType#CODEC` - The codec for the chest type. +- `net.minecraft.world.level.dimension.DimensionType$CardinalLightType` -> `CardinalLighting$Type` + +## 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. + +### Plantable Tags + +The blocks to determine whether a plantable can survive or be placed on has been moved to block and fluid tags. Each of these tags starts with `support_*` along with the block (e.g., `bamboo`, `cactus`) or group (e.g., `crops`, `dry_vegetation`). This is handled by the relevant block subclasses overriding either `Block#canSurvive`, or for vegetation `VegetationBlock#mayPlaceOn`. + +- `net.minecraft.world.level.block` + - `AttachedStemBlock` now takes in a `TagKey` for the blocks it can be placed on + - `FarmBlock` -> `FarmlandBlock` + - `FungusBlock` -> `NetherFungusBlock`, not one-to-one + - `RootsBlock` -> `NetherRootsBlock`, not one-to-one + - `WaterlilyBlock` -> `LilyPadBlock`, not one-to-one + - `StemBlock` now takes in a `TagKey` for the blocks it can be placed on, and a `TagKey` for the blocks its fruit can be placed on + +### Container Screen Changes + +The usage of `AbstractContainerScreen`s has changed slightly, requiring some minor changes. First `imageWidth` and `imageHeight` are now final, settable as parameters within the constructor. If these two are not specified, they default to the original 176 x 166 background image. + +```java +// Assume some AbstractContainerMenu subclass exists +public class ExampleContainerScreen extends AbstractContainerScreen { + + // Constructor + public ExampleContainerScreen(ExampleContainerMenu menu, Inventory playerInventory, Component title) { + // Specify image width and height as the last two parameters in the constructor + super(menu, playerInventory, title, 256, 256); + } +} +``` + +Additionally, the `AbstractContainerScreen#render` override now calls `renderTooltip` at the end of the call stack. This means that, in most cases, you should not override `render` in subtypes of the `AbstractContainerScreen`. Everything can be done in one of the other methods provided by the class. + +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen` now optionally takes in the background image width and height + - `imageWidth`, `imageHeight` are now final + - `DEFAULT_IMAGE_WIDTH`, `DEFAULT_IMAGE_HEIGHT` - The default width and height of the container background image. + - `slotClicked` now takes is a `ContainerInput` instead of a `ClickType` + - `render` override now calls `renderTooltip` by default +- `net.minecraft.world.inventory` + - `AbstractContainerMenu#clicked` now takes in a `ContainerInput` instead of a `ClickType` + - `ClickType` -> `ContainerInput` + +### New Tag Providers + +A new `TagsProvider` has been added that provides a utility for working with `Holder$Reference`s, known as `HolderTagProvider`. This is only used by the `PotionTagsProvider`. + +Additionally, the `TagBuilder` now provides a method of setting the `replace` field on a tag, which removes all previous read entries during deserialization. + +- `net.minecraft.data.tags` + - `FeatureTagsProvider` - A tag provider for `ConfiguredFeature`s. + - `HolderTagProvider` - A tag provider with a utility for appending tags by their reference holder. + - `KeyTagProvider#tag` now has an overload of whether to replace the entries in the tag. + - `PotionTagsProvider` - A provider for potion tags. + - `TradeRebalanceTradeTagsProvider` - A provider for villager trade tags for the trade rebalance. + - `VillagerTradesTagsProvider` - A provider for villager trade tags. +- `net.minecraft.tags` + - `FeatureTags` - Tags for `ConfiguredFeature`s. + - `TagBuilder#shouldReplace`, `setReplace` - Handles the `replace` field that removes all previously read entries during deserialization. + +### Test Environment State Tracking + +`TestEnvironmentDefinition`s can now keep track of the original state of the world when being created, such that it can be properly restored on run. This is done through a generic known as the 'SavedDataType'. On `setup`, each environment will return the generic data representing the original state of what was modified. Then, on `teardown`, the original state will be restored to the level for the next test case. + +```java +// The generic should represent the original data stored on the level +public record RespawnEnvironment(LevelData.RespawnData respawn) implements TestEnvironmentDefinition { + + @Override + public LevelData.RespawnData setup(ServerLevel level) { + // Modify the level while logging the original state. + var original = level.getRespawnData(); + level.setRespawnData(this.respawn); + + // Return the original state. + return original; + } + + @Override + public void teardown(ServerLevel level, LevelData.RespawnData original) { + // Reset the state of the level to the original values. + level.setRespawnData(original); + } + + @Override + public MapCodec codec() { + // Return the registered MapCodec here. + // ... + } +} +``` + +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` now has a generic representing the original state of the given modification performed by the test environment + - `setup` now returns the generic representing the original state + - `teardown` is no longer default, taking in the original state to restore + - `activate`, `$Activation` - Handles an active test environment. + +### Typed Instance + +`TypedInstance` is an interface that is attached to certain objects that represent an instance of some other 'type' object. For example, and `Entity` is a typed instance of `EntityType`, or a `BlockState` is a typed instance of `Block`. This interface is meant as a standard method to provide access to the type `Holder` and check whether the backing type, and therefore the instance, is equivalent to some identifier, tag, or raw object via `is`. + +```java +// For some Entity entity, check the EntityType +entity.is(EntityType.PLAYER); + +// For some ItemStack itemStack, check the Item +itemStack.is(ItemTags.BUTTONS); + +// For some BlockEntity blockEntity, check the BlockEntityType +blockEntity.is(BlockEntityType.CHEST); + +// For some BlockState blockState, check the Block +blockState.is(Blocks.DIRT); + +// For some FluidState fluidState, check the Fluid +fluidState.is(FluidTags.WATER); +``` + +- `net.minecraft.core.TypedInstance` - An interface that represents that this object is an instance for some other 'type' object. +- `net.minecraft.world.entity` + - `Entity` now implements `TypedInstance>` + - `EntityType#is` -> `TypedInstance#is` + - Now on the `Entity` instance +- `net.minecraft.world.item.ItemStack` now implements `TypedInstance` + - `getItemHolder` -> `typeHolder` + - `getTags` -> `tags` +- `net.minecraft.world.level.block.entity` + - `BlockEntity` now implements `TypedInstance` + - `BlockEntityType#getKey` is removed +- `net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase` now implements `TypedInstance` + - `getBlockHolder` -> `typeHolder` + - `getTags` -> `tags` +- `net.minecraft.world.level.material.FluidState` now implements `TypedInstance` + - `holder` -> `typeHolder` + - `getTags` -> `tags` + +### Entity Textures and Adult/Baby Models + +Entity textures within `assets/minecraft/textures/entity/*` have now been sorted into subdirectories (e.g., `entity/panda` for panda textures, or `entity/pig` for pig textures). Most textures have been named with the entity type starting followed by an underscore along with its variant (e.g., `arrow_tipped` for tipped arrow, `pig_cold` for the cold pig variant, or `panda_brown` for the brown panda variant). + +Additionally, some animal models have been split into separate classes for the baby and adult variants. These models either directly extend an abstract model implementation (e.g., `AbstractFelineModel`) or the original model class (e.g., `PigModel`). + +- `net.minecraft.client.animation.definitions` + - `BabyArmadilloAnimation` - Animations for the baby armadillo. + - `BabyAxolotlAnimation` - Animations for the baby axolotl. + - `BabyRabbitAnimation` - Animations for the baby rabbit. + - `CamelBabyAnimation` - Animations for the baby camel. + - `FoxBabyAnimation` - Animations for the baby fox. + - `RabbitAnimation` - Animations for the rabbit. +- `net.minecraft.client.model` + - `HumanoidModel` + - `ADULT_ARMOR_PARTS_PER_SLOT`, `BABY_ARMOR_PARTS_PER_SLOT` - A map of equipment slot to model part keys. + - `createBabyArmorMeshSet` - Creates the armor model set for a baby humanoid. + - `createArmorMeshSet` can now take in a map of equipment slot to model part keys for what to retain + - `setAllVisible` is removed + - `QuadrupedModel` now has a constructor that takes in a function for the `RenderType` +- `net.minecraft.client.model.animal.armadillo` + - `AdultArmadilloModel` - Entity model for the adult armadillo. + - `ArmadilloModel` is now abstract + - The constructor now takes in the definitions for the walk, roll out/up, and peek animations + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyArmadilloModel` + - `HEAD_CUBE`, `RIGHT_EAR_CUBE`, `LEFT_EAR_CUBE` are now `protected` instead of `private` + - `createBodyLayer` -> `AdultArmadilloModel#createBodyLayer`, `BabyArmadilloModel#createBodyLayer` + - `BabyArmadilloModel` - Entity model for the baby armadillo. +- `net.minecraft.client.model.animal.axolotl.AxolotlModel` -> `AdultAxolotlModel`, `BabyAxolotlModel` +- `net.minecraft.client.model.animal.bee` + - `AdultBeeModel` - Entity model for the adult bee. + - `BabyBeeModel` - Entity model for the baby bee. + - `BeeModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyBeeModel` + - `BONE`, `STINGER`, `FRONT_LEGS`, `MIDDLE_LEGS`, `BACK_LEGS` are now `protected` instead of `private` + - `bone` is now `protected` instead of `private` + - `createBodyLayer` -> `AdultBeeModel#createBodyLayer`, `BabyBeeModel#createBodyLayer` + - `bobUpAndDown` - Bobs the bee up and down at the desired speed, depending on its current age. +- `net.minecraft.client.model.animal.camel` + - `AdultCamelModel` - Entity model for the adult camel. + - `BabyCamelModel` - Entity model for the baby camel. + - `CamelModel` is now abstract + - The constructor now takes in the definitions for the walk, sit with/without pose, standup, idle, and dash animations + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyCamelModel` + - `createBodyLayer` -> `AdultCamelModel#createBodyLayer`, `BabyCamelModel#createBodyLayer` + - `CameSaddleModel` now extends `AdultCamelModel` instead of `CamelModel` +- `net.minecraft.client.model.animal.chicken` + - `AdultChickenModel` - Entity model for the adult chicken. + - `BabyChickenModel` - Entity model for the baby chicken. + - `ChickenModel` is now abstract + - `RED_THING` -> `AdultChickenModel#RED_THING` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyChickenModel` + - `createBodyLayer` -> `AdultChickenModel#createBodyLayer` + - `createBaseChickenModel` -> `AdultChickenModel#createBaseChickenModel` + - `ColdChickenModel` now extends `AdultChickenModel` +- `net.minecraft.client.model.animal.cow.BabyCowModel` - Entity model for the baby cow. +- `net.minecraft.client.model.animal.dolphin.BabyDolphinModel` - Entity model for the baby dolphin. +- `net.minecraft.client.model.animal.equine` + - `AbstractEquineModel` now has an overload that directly specifies the `ModelPart`s to use + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyDonkeyModel` + - `rightHindLeg`, `leftHindLeg`, `rightFrontLeg`, `leftFrontLeg` are now `protected` from `private` + - `createBabyMesh` -> `BabyHorseModel#createBabyMesh`, not one-to-one + - `offsetLegPositionWhenStanding` - Offsets the position of the legs when the entity is standing. + - `getLegStandAngle`, `getLegStandingYOffset`, `getLegStandingZOffset`, `getLegStandingXRotOffset`, `getTailXRotOffset` - Offsets and angles for parts of the equine model. + - `animateHeadPartsPlacement` - Animates the head based on its eating and standing states. + - `BabyDonkeyModel` - Entity model for the baby donkey. + - `BabyHorseModel` - Entity model for the baby horse. + - `DonkeyModel` now has an overload that directly specifies the `ModelPart`s to use + - `createBabyLayer` -> `BabyDonkeyModel#createBabyLayer` + - `EquineSaddleModel#createFullScaleSaddleLayer` is removed + Merged into `createSaddleLayer`, with the baby variant removed +- `net.minecraft.client.model.animal.feline` + - `CatModel` -> `AdultCatModel`, `BabyCatModel`; not one-to-one + - `FelineModel` -> `AbstractFelineModel`, not one-to-one + - Implementations in `AdultFelineModel` and `BabyFelineModel` + - `OcelotModel` -> `AdultOcelotModel`, `BabyOcelotModel`; not one-to-one +- `net.minecraft.client.model.animal.fox` + - `AdultFoxModel` - Entity model for the adult fox. + - `BabyFoxModel` - Entity model for the baby fox. + - `FoxModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyFoxModel` + - `body`, `rightHindLeg`, `leftHindLeg`, `rightFontLeg`, `leftFrontLeg`, `tail` are now `protected` instead of `private` + - `createBodyLayer` -> `AdultFoxModel#createBodyLayer`, `BabyFoxModel#createBodyLayer` + - `set*Pose` - Methods for setting the current pose of the fox. +- `net.minecraft.client.model.animal.goat` + - `BabyGoatModel` - Entity model for the baby goat. + - `GoatModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyGoatModel` +- `net.minecraft.client.model.animal.llama` + - `BabyLlamaModel` - Entity model for the baby llama. + - `LlamaModel#createBodyLayer` no longer takes in the `boolean` for if the entity is a baby +- `net.minecraft.client.model.animal.panda` + - `BabyPandaModel` - Entity model for the baby panda. + - `PandaModel` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyPandaModel` + - `animateSitting` - Animates the panda sitting. +- `net.minecraft.client.model.animal.pig.BabyPigModel` - Entity model for the baby pig. +- `net.minecraft.client.model.animal.polarbear` + - `BabyPolarBearModel` - Entity model for the baby polar bear. + - `PolarBearModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyPolarBearModel` +- `net.minecraft.client.model.animal.rabbit` + - `AdultRabbitModel` - Entity model for the adult rabbit. + - `BabyRabbitModel` - Entity model for the baby rabbit. + - `RabbitModel` is now abstract + - The constructor now takes in two animation definitions for the hop and idle head tilt + - `FRONT_LEGS`, `BACK_LEGS` - The child name for the entity legs. + - `LEFT_HAUNCH`, `RIGHT_HAUNCH` are now `protected` + - `createBodyLayer` -> `AdultRabbitModel#createBodyLayer`, `BabyRabbitModel#createBodyLayer`; not one-to-one +- `net.minecraft.client.model.animal.sheep` + - `BabySheepModel` - Entity model for the baby sheep. + - `SheepModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabySheepModel` +- `net.minecraft.client.model.animal.sniffer` + - `SnifferModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `SniffletModel` + - `SniffletModel` - Entity model for the baby sniffer. +- `net.minecraft.client.model.animal.squid` + - `BabySquidModel` - Entity model for the baby squid. + - `SquidModel#createTentacleName` is now protected from private +- `net.minecraft.client.model.animal.turtle` + - `AdultTurtleModel` - Entity model for the adult turtle. + - `BabyTurtleModel` - Entity model for the baby turtle. + - `TurtleModel` is now abstract + - The constructor can how take in the render type function + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyTurtleModel` + - `createBodyLayer` -> `AdultTurtleModel#createBodyLayer`, `BabyTurtleModel#createBodyLayer` +- `net.minecraft.client.model.animal.wolf` + - `AdultWolfModel` - Entity model for the adult wolf. + - `BabyWolfModel` - Entity model for the baby wolf. + - `WolfModel` is now abstract + - `ModelPart` fields are now all protected + - `createMeshDefinition` -> `AdultWolfModel#createBodyLayer`, `BabyWolfModel#createBodyLayer`; not one-to-one + - `shakeOffWater` - Sets the body rotation when shaking off water. + - `setSittingPose` - Sets the sitting pose of the wolf. +- `net.minecraft.client.model.geom` + - `ModelLayers` + - `COLD_CHICKEN_BABY` is removed + - `COLD_PIG_BABY` is removed + - `PIG_BABY_SADDLE` is removed + - `SHEEP_BABY_WOOL_UNDERCOAT` is removed + - `WOLF_BABY_ARMOR` is removed + - `DONKEY_BABY_SADDLE` is removed + - `HORSE_BABY_ARMOR` is removed + - `HORSE_BABY_SADDLE` is removed + - `MULE_BABY_SADDLE` is removed + - `SKELETON_HORSE_BABY_SADDLE` is removed + - `UNDEAD_HORSE_BABY_ARMOR` is removed + - `ZOMBIE_HORSE_BABY_SADDLE` is removed + - `STRIDER_BABY_SADDLE` is removed + - `PartNames#WAIST` - The waist part. +- `net.minecraft.client.model.monster.hoglin` + - `BabyHoglinModel` - Entity model for the baby hoglin. + - `HoglinModel` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyHoglinModel` + - `head` is now `protected` from `private` + - `createBabyLayer` -> `BabyHoglinModel#createBodyLayer` +- `net.minecraft.client.model.monster.piglin` + - `AbstractPiglinModel` is now abstract + - `leftSleeve`, `rightSleeve`, `leftPants`, `rightPants`, `jacket` are removed + - `ADULT_EAR_ANGLE_IN_DEGREES`, `BABY_EAR_ANGLE_IN_DEGREES` - The angle of the piglin ears. + - `createMesh` replaced by `AdultPiglinModel#createBodyLayer`, `AdultZombifiedPiglinModel#createBodyLayer`, `BabyPiglinModel#createBodyLayer`, `BabyZombifiedPiglinModel#createBodyLayer` + - `createBabyArmorMeshSet` - Create the armor meshes for the baby piglin model. + - `getDefaultEarAngleInDegrees` - Gets the default ear angle. + - `AdultPiglinModel` - Entity model for the adult piglin. + - `AdultZombifiedPiglinModel` - Entity model for the adult zombified piglin. + - `BabyPiglinModel` - Entity model for the baby piglin. + - `BabyZombifiedPiglinModel` - Entity model for the baby zombified piglin. + - `PiglinModel` is now abstract + - `ZombifiedPiglinModel` is now abstract +- `net.minecraft.client.model.monster.strider` + - `AdultStriderModel` - Entity model for the adult strider. + - `BabyStriderModel` - Entity model for the baby strider. + - `StriderModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyStriderModel` + - `rightLeg`, `leftLeg`, `body` are now `protected` from `private` + - `SPEED` - The speed scalar of the movement animation. + - `customAnimations` - Additional animation setup. + - `animateBristle` - Animates the bristles of the strider. +- `net.minecraft.client.model.monster.zombie` + - `BabyDrownedModel` - Entity model for the baby drowned. + - `BabyZombieModel` - Entity model for the baby zombie. + - `BabyZombieVillagerModel` - Entity model for the baby zombie villager. +- `net.minecraft.client.model.npc` + - `BabyVillagerModel` - Entity model for the baby villager. + - `VillagerModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyVillagerModel` +- `net.minecraft.client.renderer.entity` + - `AxolotlRenderer` now takes in an `EntityModel` for its generic + - `CamelHuskRenderer` now extends `MobRenderer` instead of `CamelRenderer` + - `CamelRenderer#createCamelSaddleLayer` is now `static` + - `CatRenderer` now takes in an `AbstractFelineModel` for its generic + - `DonkeyRenderer` now takes in an `EquipmentClientInfo$LayerType` and `ModelLayerLocation` for the saddle layer and model, and splits the `DonkeyRenderer$Type` into the adult type and baby type + - `$Type` + - `DONKEY_BABY` - A baby variant of the donkey. + - `MULE_BABY` - A baby variant of the mule. + - `OcelotRenderer` now takes in an `AbstractFelineModel` for its generic + - `UndeadHorseRenderer` now takes in an `EquipmentClientInfo$LayerType` and `ModelLayerLocation` for the saddle layer and model, and splits the `UndeadHorseRenderer$Type` into the adult type and baby type + - `$Type` + - `SKELETON_BABY` - A baby variant of the skeleton horse. + - `ZOMBIE_BABY` - A baby variant of the zombie horse. +- `net.minecraft.client.renderer.entity.layers.CatCollarLayer` now takes in an `AbstractFelineModel` for its generic +- `net.minecraft.client.renderer.entity.state` + - `AxolotlRenderState` + - `swimAnimation` - The state of swimming. + - `walkAnimationState` - The state of walking on the ground, not underwater. + - `walkUnderWaterAnimationState` - The state of walking underwater. + - `idleUnderWaterAnimationState` - The state of idling underwater but not on the ground. + - `idleUnderWaterOnGroundAnimationState` - The state of idling underwater while touching the seafloor. + - `idleOnGroundAnimationState` - The state of idling on the ground, not underwater. + - `playDeadAnimationState` - The state of playing dead. + - `RabbitRenderState` + - `hopAnimationState` - The state of the hop the entity is performing. + - `idleHeadTiltAnimationState` - The state of the head tilt when performing the idle animation. +- `net.minecraft.client.resources.model.EquipmentClientInfo$LayerType#HUMANOID_BABY` - The baby humanoid equipment layer. +- `net.minecraft.sounds.SoundEvents#PIG_EAT_BABY` - Ths sound played when a baby big is eating. +- `net.minecraft.world.entity.AgeableMob` + - `canUseGoldenDandelion` - Whether a golden dandelion can be used to agelock an entity. + - `setAgeLocked` - Sets the entity as agelocked. + - `makeAgeLockedParticle` - Creates the particles when agelocking an entity. + - `AGE_LOCK_DOWNWARDS_MOVING_PARTICLE_Y_OFFSET` - The Y offset for the particle's starting position. +- `net.minecraft.world.entity.animal.axolotl.Axolotl` + - `swimAnimation` - The state of swimming. + - `walkAnimationState` - The state of walking on the ground, not underwater. + - `walkUnderWaterAnimationState` - The state of walking underwater. + - `idleUnderWaterAnimationState` - The state of idling underwater but not on the ground. + - `idleUnderWaterOnGroundAnimationState` - The state of idling underwater while touching the seafloor. + - `idleOnGroundAnimationState` - The state of idling on the ground, not underwater. + - `playDeadAnimationState` - The state of playing dead. + - `$AnimationState` -> `$AxolotlAnimationState` +- `net.minecraft.world.entity.animal.chicken.ChickenVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.cow.CowVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.cat.CatVariant` now takes in a resource for the baby texture + - `CatVariant#assetInfo` - Gets the entity texture based on whether the entity is a baby. +- `net.minecraft.world.entity.animal.equine.AbstractHorse#BABY_SCALE` - The scale of the baby size compared to an adult. +- `net.minecraft.world.entity.animal.frog.Tadpole` + - `ageLockParticleTimer` - A timer for how long the particles for the agelocked entity should spawn. + - `setAgeLocked`, `isAgeLocked` - Handles agelocking for the tadpole. +- `net.minecraft.world.entity.animal.goat.Goat` + - `BABY_DEFAULT_X_HEAD_ROT` - The default head X rotation for the baby variant. + - `MAX_ADDED_RAMMING_X_HEAD_ROT` - The maximum head X rotation. + - `addHorns`, `removeHorns` are removed +- `net.minecraft.world.entity.animal.pig.PigVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.rabbit.Rabbit` + - `hopAnimationState` - The state of the hop the entity is performing. + - `idleHeadTiltAnimationState` - The state of the head tilt when performing the idle animation. +- `net.minecraft.world.entity.animal.wolf` + - `WolfSoundVariant` -> `WolfSoundVariant$WolfSoundSet` + - The class itself now holds two sound sets for the adult wolf and baby wolf. + - `WolfSoundVariants$SoundSet#getSoundEventSuffix` -> `getSoundEventIdentifier` +- `net.minecraft.world.entity.animal.wolf.WolfVariant` now takes in an asset info for the baby variant +- `net.minecraft.world.item.equipment.EquipmentAssets#TRADER_LLAMA_BABY` - Equipment asset for baby trader llamas. + +### The Removal of interactAt + +`Entity#interactAt` has been removed, with all further invocation merged with `Entity#interact`. Originally, `Entity#interactAt` was called if the hit result was within the entity's interaction range. If `interactAt` did not consume the action (i.e., `InteractionResult#consumesAction` returns false), then `Entity#interact` is called. Now, `Entity#interact` is called if within the entity's interaction range, taking in the `Vec3` location of interaction. + +```java +// In some Entity subclass + +@Override +public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { + // Handle the interaction + super.interact(player, hand, location); +} +``` + +`interactAt` checks if result does not consume the interaction, and if not calls `interact` +Now, `interact` is called with the entity hit + +- `net.minecraft.client.multiplayer.MultiPlayerGameMode` + - `interact` now takes in the `EntityHitResult` + - `interactAt` is removed +- `net.minecraft.world.entity.Entity` + - `interact` now takes in a `Vec3` for the location of the interaction + - `interactAt` is removed +- `net.minecraft.world.entity.player.Player#interactOn` now takes in a `Vec3` for the location of the interaction + +### ChunkPos, now a record + +`ChunkPos` is now a record. The `BlockPos` constructor has been replaced by `ChunkPos#containing` while the packed `long` constructor has been replaced by `ChunkPose#unpack`. + +- `net.minecraft.world.level.ChunkPos` is now a record + - `ChunkPos(BlockPos)` -> `containing` + - `ChunkPos(long)` -> `unpack` + - `toLong`, `asLong` -> `pack` + +### No More Tripwire Pipelines + +The tripwire render pipeline has been completely removed. Now, tripwires make use of `cutout` with an `alpha_cutoff_bias` of 0.1 for the texture. + +- `net.minecraft.client.renderer.RenderPipelines#TRIPWIRE_BLOCK`, `TRIPWIRE_TERRAIN` are removed +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer#TRIPWIRE` is removed + - `ChunkSectionLayerGroup#TRIPWIRE` is removed +- `net.minecraft.client.renderer.rendertype.RenderTypes#tripwireMovingBlock` is removed + +### Activities and Brains + +Activities, which define how a living entity behaves during a certain phase, now are stored and passed around through `ActivityData`. This contains the activity type, the behaviors to perform along with their priorities, the conditions on when this activity activates, and the memories to erase when the activity has stopped. `Brain#provider` now takes in an `$ActivitySupplier` to construct a list of `ActivityData` the entity performs. + +Brains have also changed slightly. First, the `Brain` itself is not directly serializable. Instead, the brain is `$Packed` into the record, holding a map of its current memories. To get the memory types used, they are typically extracted from those that the `Sensor#requires`. Additionally, `LivingEntity#brainProvider` no longer exists, instead opting to store the provider in a static constant on the entity itself. This means that brains are now completely constructed through the `makeBrain` method, taking in the previous `$Packed` data: + +```java +// For some ExampleEntity extends LivingEntity +// Assume extends Mob subclass +private static final Brain.Provider BRAIN_PROVIDER = Brain.provider( + // The list of sensors the entity uses. + ImmutableList.of(), + // A function that takes in the entity and returns a list of activities. + entity -> List.of( + new ActivityData( + // The activity type + Activity.CORE, + // A list of priority and behavior pairs + ImmutableList.of(Pair.of(0, new MoveToTargetSink())), + // A set of memory conditions for the activity to run + // For example, this memory value must be present + ImmutableSet.of(Pair.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT)), + // The set of memories to erase when the activity has stopped + ImmutableSet.of(MemoryModuleType.ATTACK_TARGET) + ) + ) +); + +@Override +protected Brain.Provider makeBrain(Brain.Packed packedBrain) { + // Make the brain, populating any previous memories + return BRAIN_PROVIDER.makeBrain(this, packedBrain); +} +``` + +- `net.minecraft.world.entity.LivingEntity` + - `brainProvider` is removed + - `makeBrain` now takes in a `Brain$Packed` instead of a `Dynamic` +- `net.minecraft.world.entity.ai` + - `ActivityData` - A record containing the activity being performed, the behaviors to perform during that activity, any memory conditions, and what memories to erase once stopped. + - `Brain` is now protected, taking in a list of `ActivityData`, a `MemoryMap` instead of an immutable list of memories, a `RandomSource`, and not the supplied `Codec` + - The public constructor no longer takes in anything + - `provider` now has an overload that only takes in the sensor types, defaulting the memory types to an empty list + - Some `provider` methods also take in the `Brain$ActivitySupplier` to perform + - `codec`, `serializeStart` are replaced by `pack`, `Brain$Packed` + - `addActivityAndRemoveMemoryWhenStopped`, `addActivityWithConditions` merged into `addActivity` + - Alternatively use `ActivityData#create` + - `copyWithoutBehaviors` is removed + - `getMemories` replaced by `forEach` + - `$ActivitySupplier` - Creates a list of activities for the entity. + - `$MemoryValue` is removed + - `$Packed` - A record containing the data to serialize the brain to disk. + - `$Provider#makeBrain` now takes in the entity and the `Brain$Packed` to deserialize the memories + - `$Visitor` - Visits the memories within a brain, whether defined but empty, present, or present with some timer. +- `net.minecraft.world.entity.ai.behavior.VillagerGoalPackages#get*Package` no longer take in the `VillagerProfession` +- `net.minecraft.world.entity.ai.memory` + - `ExpirableValue` -> `MemorySlot`, not one-to-one + - The original `ExpirableValue` is now a record that defines when a memory should expire, rather than be updated itself + - `MemoryMap` - A map linking the memory type to its stored value. + - `MemoryModuleType` - Whether a memory can be serialized. +- `net.minecraf.tworld.entity.ai.sensing.Sensor#randomlyDelayStart` - How long to delay a sensor. +- `net.minecraft.world.entity.animal.allay.AllayAi` + - `SENSOR_TYPES`, `MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.animal.armadillo.ArmadilloAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.axolotl` + - `AxolotlSENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `AxolotlAi` + - `makeBrain` -> `getActivities`, not one-to-one + - `initPlayDeadActivity`, now `protected`, no longer taking in anything + - `initFightActivity`, now `protected`, no longer taking in anything + - `initCoreActivity`, now `protected`, no longer taking in anything + - `initIdleActivity`, now `protected`, no longer taking in anything +- `net.minecraft.world.entity.animal.camel.CamelAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.frog` + - `Frog#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `FrogAi#makeBrain` -> `getActivities`, not one-to-one + - `Tadpole#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one +- `net.minecraft.world.entity.animal.frog.TadpoleAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.animal.goat` + - `Goat#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `GoatAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.animal.golem.CopperGolemAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.happyghast.HappyGhastAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.nautilus` + - `NautilusAi` + - `SENSOR_TYPES`,`MEMORY_TYPES` -> `Nautilus#BRAIN_PROVIDER`, now private, not one-to-one + - `makeBrain`, `brainProvider` -> `getActivities`, now `public`, not one-to-one + - `ZombieNautilusAi` + - `SENSOR_TYPES`,`MEMORY_TYPES` -> `ZombieNautilus#BRAIN_PROVIDER`, now private, not one-to-one + - `makeBrain`, `brainProvider` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.animal.sniffer.SnifferAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.monster.Zoglin` + - `SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `getActivities` - The activities the zoglin performs. +- `net.minecraft.world.entity.monster.breeze.BreezeAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.monster.creaking.CreakingAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.monster.hoglin` + - `Hoglin#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `HoglinAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.monster.piglin` + - `Piglin#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `PiglinAi#makeBrain` -> `getActivities`, now `public`, not one-to-one + - `PiglinBrute#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `PiglinBruteAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.monster.warden.WardenAi#makeBrain` -> `getActivities`, not one-to-one + +### File Fixer Upper + +The file fixer upper is a new system to help with upgrading game files between versions, in conjunction with the data fixer upper. Similar to how the data within files can be modified or 'upgraded' between Minecraft versions via data fixers, file fixers can modify anything within a world directory, from moving files and directories to deleting them outright. As such, file fixers are always applied before data fixers. + +Unlike when upgrading when data fixers, file fixers change the structure of the world folder. Because of this, downgrading is rarely possible, as the file names and locations will have likely changed location. + +File fixers are applied through a `FileFix`, which defines some operation(s) to perform on a file using `makeFixer`. This is done typically through the `addFileContentFix`, providing access to the desired files through the `FileAccess`, and then modifying the data like any other `Dynamic` instance. Operations are commonly defined as `FileFixOperation`s, which can move the file structure around. + +The file fixes are then applied through the `FileFixerUpper`, which uses a copy-on-write file system to operate on the files. The fixer is constructed using the `$Builder`, using `addSchema` and `addFixer` to apply the fixers for the desired version. During the upgrade process, the files are created in a temporary folder, then moved to the world folder. The original world folder is moved to another folder before being deleted. + +- `net.minecraft.client.gui.screens.FileFixerAbortedScreen` - A screen that's shown when the file fixing has been aborted. +- `net.minecraft.client.gui.screens.worldselection.FileFixerProgressScreen` - A screen that's displayed when attempting to show the progress of upgrading and fixing the world files. +- `net.minecraft.server.packs.linkfs` + - `DummyFileAttributes` -> `.minecraft.util.DummyFileAttributes` + - `LinkFSPath` + - `DIRECTORY_ATTRIBUTES` -> `DummyFileAttributes#DIRECTORY` + - `FILE_ATTRIBUTES` -> `DummyFileAttributes#FILE` +- `net.minecraft.util` + - `ExtraCodecs` + - `pathCodec` - A codec for a path, converting from a string and storing with Unix separators. + - `relaiveNormalizedSubPathCodec` - A codec for a path, normalized and validated to make sure it is relative. + - `guardedPathCodec` - A codec for a path, resolved and relativatized from some base path. + - `FileUtil` + - `isPathNormalized`, `createPathToResource` are removed + - `isEmptyPath` - Returns whether the path is empty. + - `Util#safeMoveFile` - Safely moves a file from some source to a destination with the given options. +- `net.minecraft.util.filefix` + - `AbortedFileFixException` - An exception thrown when the file fix has been aborted and was unable to revert moves. + - `AtmoicMoveNotSupportedFileFixException` - An exception thrown when the user file system does not support atomic moves. + - `CanceledFileFixException` - An exception thrown when the file fix upgrade proccess is canceled. + - `FailedCleanupFileFixException` - An exception thrown when the file fix was not able to move or delete folders for cleanup. + - `FileFix` - A fixer that performs some operation on a file. + - `FileFixerUpper` - The file fixers to perform operations with. + - `FileFixException` - An exception thrown when attempting to upgrade a world through the file fixer. + - `FileFixUtil` - A utility for performing some file operations. + - `FileSystemCapabilities` - The capabilities of the file system from a directory. +- `net.minecraft.util.filefix.access` + - `ChunkNbt` - Handles upgrading a chunk nbt. + - `CompressedNbt` - Handles upgrading a compressed nbt file. + - `FileAccess` - Provides an reference to some file resource(s), given its relation. + - `FileAccessProvider` - A provider of file accesses, given some relation to the origin. + - `FileRelation` - A definition of how a file relates to some origin bpath. + - `FileResourceType` - Defines the type of resource to access. + - `FileResourceTypes` - All defined file resource types. + - `LevelDat` - Handles upgrading a level dat. + - `PlayerData` - Handles upgrading the player data. + - `SavedDataNbt` - Handles upgrading the saved data. +- `net.minecraft.util.filefix.fixes.*` - The vanilla fixes to apply to the file(s). +- `net.minecraft.util.filefix.operations` + - `ApplyInFolders` - Applies the given operations within the related folders. + - `DeleteFileOrEmptyDirectory` - Deletes the target file or empty directory. + - `FileFixOperation` - An operation performed within some base directory. + - `FileFixOperations` - All vanilla file fix operations. + - `GroupMove` - Moves some directory, applying any move operation on its contents. + - `ModifyContent` - Modifies the content of a file. + - `Move` - Moves a file from some source to some destination. + - `RegexMove` - Moves all files that match the given source pattern to the destination, replacing the matched sections. +- `net.minecraft.util.filefix.virtualfilesystem` + - `CopyOnWriteFileStore` - A file store using the copy-on-write principle. + - `CopyOnWriteFileSystem` - A file system using the copy-on-write principle. + - `CopyOnWriteFSPath` - A path using the copy-on-write principle. + - `CopyOnWriteFSProvider` - A file system provider using the copy-on-write principle. + - `DirectoryNode` - A directory node for some copy-on-write file system path. + - `FileMove` - A record containing the path a file has been moved from to. + - `FileNode` - A file node for some copy-on-write file system path. + - `Node` - A node for some copy-on-write file system path. +- `net.minecraft.util.filefix.virtualfilesystem.exception` + - `CowFSCreationException` - A `CowFSFileSystemException` when the file system cannot be created. + - `CowFSDirectoryNotEmptyException` - A `DirectoryNotEmptyException` specifically for a copy-on-write system. + - `CowFSFileAlreadyExistsException` - A `FileAlreadyExistsException` specifically for a copy-on-write system. + - `CowFSFileSystemException` - A `FileSystemException` specifically for a copy-on-write system. + - `CowFSIllegalArgumentException` - An `IllegalArgumentException` when attempting to operate upon a copy-on-write system. + - `CowFSNoSuchFileException` - A `NoSuchFileException` specifically for a copy-on-write system. + - `CowFSNotDirectoryException` - A `NotDirectoryException` specifically for a copy-on-write system. + - `CowFSSymlinkException` - A `CowFSCreationException` when attempting to use the copy-on-write system with a symlink. +- `net.minecraft.util.worldupdate` + - `UpgradeProgress` + - `getTotalFiles` -> `getTotalFileFixState`, not one-to-one + - `addTotalFiles` -> `addTotalFileFixOperations`, not one-to-one + - `getTypeFileFixStats`, `getRunningFileFixerStats` - Gets the fixer stats for the specific file group. + - `incrementFinishedOperations`, `incrementFinishedOperationsBy` - Increments the number of operations that have finished. + - `setType`, `getType` - Gets the type of the upgrade progress. + - `setApplicableFixerAmount` - Sets the total number of finished operations for the running file fixers. + - `incrementRunningFileFixer` - Increments the number of finished operations. + - `logProgress` - Logs the progress of the upgrade every second. + - `$FileFixStats` - A counter for the operations performed / finished. + - `$Type` - The type of upgrade being performed on the world data. + - `WorldUpgrader` no longer takes in the `WorldData` + - `STATUS_*` messages have been combined in `UpgradeStatusTranslator` + - This also contains the specific datafix type + - `running`, `finished`, `progress`, `totalChunks`, `totalFiles`, `converted`, `skipped`, `progressMap`, `status` have all been moved into `UpgradeProgress`, stored in `upgradeProgress` + - `getProgress` -> `getTotalProgress`, not one-to-one + - `$AbstractUpgrader`, `$SimpleRegionStorageUpgrader` -> `RegionStorageUpgrader`, no longer taking in the supplied `LegacyTagFixer`, not one-to-one + - `$ChunkUpgrader`, `$EntityUpgrader`, `$PoiUpgrader` are now just constructed within `WorldUpgrader#work` + - `$Builder#setLegacyFixer` is removed + - `$ChunkUpgrader#tryProcessOnePosition` has been partially abstracted into `getDataFixContentTag`, `verifyChunkPosAndEraseCache`, `verifyChunkPos` + - `$FileToUpgrade` -> `FileToUpgrade` +- `net.minecraft.world.level.ChunkPos#getRegionX`, `getRegionZ` - Gets the region the chunk is in. +- `net.minecraft.world.level.chunk.ChunkGenerator#getTypeNameForDataFixer` now returns an optional `Identifier` instead of a `ResourceKey` +- `net.minecraft.world.level.chunk.storage` + - `LegacyTagFixer` interface is removed + - `RecreatingSimpleRegionStorage` no longer takes in the supplied `LegacyTagFixer` + - `SimpleRegionStorage` no longer takes in the supplied `LegacyTagFixer` + - `markChunkDone` is removed +- `net.minecraft.world.level.levelgen.structure` + - `LegacyStructureDataHandler` class is removed + - `StructureFeatureIndexSavedData` class is removed +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager` + - `STRUCTURE_RESOURCE_DIRECTORY_NAME` -> `STRUCTURE_DIRECTORY_NAME`, not one-to-one + - `WORLD_STRUCTURE_LISTER`, `RESOURCE_TEXT_STRUCTURE_LISTER` - Id converters for the structure nbts. + - `save` now has an overload that takes in the path, `StructureTemplate`, and `boolean` for whether to write the data as text + - `createAndValidatePathToGeneratedStructure` -> `TemplatePathFactory#createAndValidatePathToStructure`, not one-to-one + - `worldTemplates`, `testTemplates` - The template path factories. +- `net.minecraft.world.level.levelgen.structure.templatesystem.loader` + - `DirectoryTemplateSource` - A template source for some directory. + - `ResourceManagerTemplateSource` - A template source for the resource manager. + - `TemplatePathFactory` - A factory that gets the path to some structure. + - `TemplateSource` - A loader for structure templates. +- `net.minecraft.world.level.storage` + - `LevelStorageSource` + - `getLevelDataAndDimensions` now takes in the `$LevelStorageAccess` + - `readExistingSavedData` - Reads any existing saved data. + - `writeGameRules` - Writes the game rules to the saved data. + - `$LevelStorageAccess#releaseTemporarilyAndRun` - Releases the access and runs before recreating the lock. + - `collectIssues` - Collects any issues when attempting to upgrade the data. + - `getSummary` -> `fixAndGetSummary`, `fixAndGetSummaryFromTag`; not one-to-one + - `getDataTag` -> `getUnfixedDataTag`, not one-to-one + - `getDataTagFallback` -> `getUnfixedDataTagWithFallback`, not one-to-one + - `saveDataTag` no longer takes in the `RegistryAccess` + - `saveLevelData` - Saves the level dat. + - `LevelSummary` now takes in whether it requires file fixing + - `UPGRADE_AND_PLAY_WORLD` - A component telling the user to upgrade their world and play. + - `requiresFileFixing` - Whether the level requires file fixing. + - `$BackupStatus#FILE_FIXING_REQUIRED` - Whether file fixing is require to play this level on this version. + +### Chat Permissions + +The chat system now has an associated set of permissions indicating what messages the player can send or receive. `Permissions#CHAT_SEND_MESSAGES` and `CHAT_SEND_COMMANDS` determine if the player can send messages or commands, respectively. Likewise, `CHAT_RECEIVE_PLAYER_MESSAGES` and `CHAT_RECEIVE_SYSTEM_MESSAGES` if the player can receive messages from other players or the system, respectively. Note that all of these permissions are only handled clientside and are not validated serverside. + +- `net.minecraft.SharedConstants#DEBUG_CHAT_DISABLED` - A flag that disables the chat box. +- `net.minecraft.client` + - `GuiMessage` -> `.multiplayer.chat.GuiMessage` + - `GuiMessageTag` -> `.multiplayer.chat.GuiMessageTag` + - `Minecraft` + - `getChatStatus` -> `computeChatAbilities`, not one-to-one + - `$ChatStatus` -> `ChatRestriction`, not one-to-one +- `net.minecraft.client.gui.Gui#setChatDisabledByPlayerShown`, `isShowingChatDisabledByPlayer` - Handles whether the chat is disabled by the shown player. +- `net.minecraft.client.gui.components` + - `ChatComponent` + - `GO_TO_RESTRICTIONS_SCREEN` - An identifier for redirecting to the restrictions screen. + - `setVisibleMessageFilter` - Sets the message filter function. + - `render`, `captureClickableText` now take in the `$DisplayMode` instead of a `boolean` for if the player is chatting + - `addMessage` is now private + - Split for use into `addClientSystemMessage`, `addServerSystemMessage`, `addPlayerMessage` + - `$DisplayMode` - How the chat should be displayed. + - `CommandSuggestions` + - `USAGE_FORMAT`, `USAGE_OFFSET_FROM_BOTTOM`, `LINE_HEIGHT` - Constants for showing the command suggestions. + - `setRestrictions` - Sets the restrictions of the messages that can be typed. + - `hasAllowedInput` - Whether the chat box can allow input. +- `net.minecraft.client.gui.screens.ChatScreen#USAGE_BACKGROUND_COLOR` - The background color of the command suggestions box. +- `net.minecraft.client.gui.screens.multiplayer.RestrictionsScreen` - A screen for settings the restrictions of the player's chat box. +- `net.minecraft.client.gui.screens.reporting.ReportPlayerScreen` now takes in a `boolean` for if the chat is disabled or blocked +- `net.minecraft.client.multiplayer.chat` + - `ChatAbilities` - The set of restrictions the player has on chatting with the chat box. + - `ChatListener` + - `handleSystemMessage` `boolean` is now used for if the system is remote instead of overlay + - The overlay is now handled through `handleOverlay` + - `GuiMessageSource` - The source the message came from. +- `net.minecraft.client.player.LocalPlayer` now takes in the `ChatAbilities` + - `chatAbilities`, `refreshChatAbilities` - Handles the chat abilities. +- `net.minecraft.server.permissions.Permissions` + - `CHAT_SEND_MESSAGES` - If the player can send chat messages. + - `CHAT_SEND_COMMANDS` - If the player can send commands. + - `CHAT_RECEIVE_PLAYER_MESSAGES` - If the player can receive other player messages. + - `CHAT_RECEIVE_SYSTEM_MESSAGES` - If the player can receive system messages. + - `CHAT_PERMISSIONS` - A set of available chat permissions. +- `net.minecraft.world.entity.player.Player#displayClientMessage` split into `sendSystemMessage` when overlay message was `false`, and `sendOverlayMessage` when the overlay message was `true` + +### More Entity Sound Variant Registries + +Cats, chickens, cows, and pigs now have sound variants: a databack registry object that specifies the sounds an entity plays. This does not need to be directly tied to an actual entity variant, as it only defines the sounds an entity plays, typically during `Mob#finalizeSpawn`. + +For cows: + +```json5 +// A file located at: +// - `data/examplemod/cow_sound_variant/example_cow_sound.json` +{ + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.cow.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.cow.death", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.cow.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.cow.step" +} +``` + +For chickens and pigs: + +```json5 +// A file located at: +// - `data/examplemod/chicken_sound_variant/example_chicken_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.chicken.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.chicken.death", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.chicken.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.chicken.step" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_chicken.ambient", + "death_sound": "minecraft:entity.baby_chicken.death", + "hurt_sound": "minecraft:entity.baby_chicken.hurt", + "step_sound": "minecraft:entity.baby_chicken.step" + } +} +``` + +For pigs: + +```json5 +// A file located at: +// - `data/examplemod/pig_sound_variant/example_pig_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.pig.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.pig.death", + // The registry name of the sound event to play when eating. + "eat_sound": "minecraft:entity.pig.eat", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.pig.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.pig.step" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_pig.ambient", + "death_sound": "minecraft:entity.baby_pig.death", + "eat_sound": "minecraft:entity.baby_pig.eat", + "hurt_sound": "minecraft:entity.baby_pig.hurt", + "step_sound": "minecraft:entity.baby_pig.step" + } +} +``` + +For cats: + +```json5 +// A file located at: +// - `data/examplemod/cat_sound_variant/example_cat_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle when tamed. + "ambient_sound": "minecraft:entity.cat.ambient", + // The registry name of the sound event to play when non-tamed and tempted by food. + "beg_for_food_sound": "minecraft:entity.cat.beg_for_food", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.cat.death", + // The registry name of the sound event to play when fed. + "eat_sound": "minecraft:entity.cat.eat", + // The registry name of the sound event to play when hissing, typically at a pursuing phantom. + "hiss_sound": "minecraft:entity.cat.hiss", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.cat.hurt", + // The registry name of the sound event to play when purring, typically when in love or lying down. + "purr_sound": "minecraft:entity.cat.purr", + // The registry name of the sound event to play randomly on idle when tamed 25% of the time. + "purreow_sound": "minecraft:entity.cat.purreow", + // The registry name of the sound event to play randomly on idle when not tamed. + "stray_ambient_sound": "minecraft:entity.cat.stray_ambient" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_cat.ambient", + "beg_for_food_sound": "minecraft:entity.baby_cat.beg_for_food", + "death_sound": "minecraft:entity.baby_cat.death", + "eat_sound": "minecraft:entity.baby_cat.eat", + "hiss_sound": "minecraft:entity.baby_cat.hiss", + "hurt_sound": "minecraft:entity.baby_cat.hurt", + "purr_sound": "minecraft:entity.baby_cat.purr", + "purreow_sound": "minecraft:entity.baby_cat.purreow", + "stray_ambient_sound": "minecraft:entity.baby_cat.stray_ambient" + } +} +``` + +- `net.minecraft.core.registries.Registries` + - `CAT_SOUND_VARIANT` - The registry key for the sounds a cat should make. + - `CHICKEN_SOUND_VARIANT` - The registry key for the sounds a chicken should make. + - `COW_SOUND_VARIANT` - The registry key for the sounds a cow should make. + - `PIG_SOUND_VARIANT` - The registry key for the sounds a pig should make. +- `net.minecraft.network.synched.EntityDataSerializers` + - `CAT_SOUND_VARIANT` - The entity serializer for the sounds a cat should make. + - `CHICKEN_SOUND_VARIANT` - The entity serializer for the sounds a chicken should make. + - `COW_SOUND_VARIANT` - The entity serializer for the sounds a cow should make. + - `PIG_SOUND_VARIANT` - The entity serializer for the sounds a pig should make. +- `net.minecraft.sounds.SoundEvents` + - `CAT_*` sounds are now either `Holder$Reference`s or stored in the map of `CAT_SOUNDS` + - `CHICKEN_*` sounds are now either `Holder$Reference`s or stored in the map of `CHICKEN_SOUNDS` + - `COW_*` sounds are stored in the map of `COW_SOUNDS` + - `PIG_*` sounds are now either `Holder$Reference`s or stored in the map of `PIG_SOUNDS` +- `net.minecraft.world.entity.animal.chicken` + - `ChickenSoundVariant` - The sounds that are played for a chicken variant. + - `ChickenSoundVariants` - All vanilla chicken variants. +- `net.minecraft.world.entity.animal.cow` + - `AbstractCow#getSoundSet` - Gets the sounds a cow makes. + - `CowSoundVariant` - The sounds that are played for a cow variant. + - `CowSoundVariants` - All vanilla cow variants. +- `net.minecraft.world.entity.animal.feline` + - `CatSoundVariant` - The sounds that are played for a cat variant. + - `CatSoundVariants` - All vanilla cat variants. +- `net.minecraft.world.entity.animal.chicken` + - `ChickenSoundVariant` - The sounds that are played for a chicken variant. + - `ChickenSoundVariants` - All vanilla chicken variants. +- `net.minecraft.world.entity.animal.pig` + - `PigSoundVariant` - The sounds that are played for a pig variant. + - `PigSoundVariants` - All vanilla pig variants. + +### Audio Changes + +Audio devices are now handled through the `DeviceTracker` which, depending on the backing machine, allows for either the machine to send system events when audio devices change, or using a standard polling interval to requery the list of available devices. + +- `com.mojang.blaze3d.audio` + - `AbstractDeviceTracker` - An abstract tracker for managing the changes of audio devices. + - `CallbackDeviceTracker` - A device tracker that uses the SOFT system events callback to determine changes. + - `DeviceList` - A list of all audio devices, including the default device, if available. + - `DeviceTracker` - An interface for managing the changes of audio devices. + - `Library` + - `NO_DEVICE` is now `public` from `private` + - `init` now takes in the `DeviceList` + - `getDefaultDeviceName` moved to `DeviceList#defaultDevice` + - `getCurrentDeviceName` -> `currentDeviceName` + - `hasDefaultDeviceChanged` moved to `AbstractDeviceTracker`, not one-to-one + - `getAvailableSoundDevices` moved to `DeviceList`, not one-to-one + - `createDeviceTracker` - Creates the tracker for managing audio device changes. + - `getDebugString` -> `getChannelDebugString` + - `PollingDeviceTracker` - A device tracker that uses polling intervals to determine changes. + - `SoundBuffer` + - `format` - The format of the sound stream. + - `size` - The number of bytes in the sound stream. + - `isValid` - If the sound stream is in a valid state. +- `net.minecraft.client.Options` + - `DEFAULT_SOUND_DEVICE` is now `private` from `public` + - `isSoundDeviceDefault` - Checks if the device is the default audio device. +- `net.minecraft.client.gui.components.debug` + - `DebugEntrySoundCache` - A debug entry displaying the current cache for loaded sound streams. + - `DebugScreenEntries#SOUND_CACHE` - The identifier for the sound stream cache debug information. +- `net.minecraft.client.sounds` + - `SoundBufferLibrary` + - `enumerate` - Loops through all cached sounds, outputting its id, size, and format. + - `$DebugOutput` - An interface that accepts some sound metadata. + - `$Counter` - An output implementation that keepts track of the number of sound streams and the total size. + - `SoundEngine` + - `getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; not one-to-one + - `$DeviceCheckState` is removed + - `SoundManager#getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; not one-to-one + +### Input Message Editor Support + +Minecraft now has support for Input Message Editors (IME), which allow complex characters from languages like Chinese or Hindi to be inputted instead of the temporary preedit text. The preedit text is displayed as an overlay within the game, while any other IME features provided by the host OS. With this addition, support can be added within screens through `GuiEventListener#preeditUpdated`, or by using an existing vanilla widget which implements the method. + +- `com.mojang.blaze3d.platform` + - `InputConstants#setupKeyboardCallbacks` now takes in the `GLFWCharCallbackI` instead of `GLFWCharModsCallbackI` for the character typed callback, `GLFWPreeditCallbackI` to handle inputting complex characters via an input method editor, and `GLFWIMEStatusCallbackI` for notifying about the status of the editor + - `MessageBox` - A utility for creating OS native messages boxes. + - `TextInputManager` - A manager for handling when text is inputted in the game window. + - `setTextInputArea` - Sets the area where the predicted text cursor should appear. + - `startTextInput`, `stopTextInput` - Handles toggling the input message editor. +- `net.minecraft.client` + - `KeyboardHandler` + - `resubmitLastPreeditEvent` - Repeats the last preedit event that was sent. + - `submitPreeditEvent` - Tells the listener that the preedit text has been updated. + - `Minecraft` + - `textInputManager` - Returns the input manager. + - `onTextInputFocusChange` - Changes the editor input status based on if the text input is focused. +- `net.minecraft.client.gui.GuiGraphics` + - `setPreeditOverlay` - Sets the overlay drawing the preedit text. + - `renderDeferredElements` now takes in the `int`s for the mouse position and the game time delta ticks `float` +- `net.minecraft.client.gui.components` + - `IMEPreeditOverlay` - The overlay for displaying the preedit text for an input message editor. + - `TextCursorUtils` - A utility for drawing the text cursor. +- `net.minecraft.client.gui.components.events.GuiEventListener#preeditUpdated` - Listens for when the preedit text changes. +- `net.minecraft.client.input` + - `CharacterEvent` no longer takes in the modifier `int` set + - `PreeditEvent` - An event containing the preedit text along with the cursor location. + +### Cauldron Interaction Dispatchers + +Cauldron interactions have been reorganized somewhat, with all registration being moved to `CauldronInteractions` from `CauldronInteraction`. In addition, the backing `$InteractionMap` for a cauldron type has been replaced with a `$Dispatcher` that can register interactions for both tags and items. Tags are checked before items. + +```java +CauldronInteractions.EMPTY.put( + // The Item or TagKey to use + ItemTags.WOOL, + // The cauldron interaction to apply + (state, level, pos, player, hand, itemInHand) -> InteractionResult.TRY_WITH_EMPTY_HAND +); +``` + +- `net.minecraft.core.cauldron` + - `CauldronInteraction` + - All fields regarding to registering interactions to a map have been moved to `CauldronInteractions` + - `INTERACTIONS` -> `CauldronInteractions#ID_MAPPER`, now `private` + - `DEFAULT` - The default interaction with a cauldron + - `$InteractionMap` -> `$Dispatcher`, not one-to-one + - `CauldronInteractions` - All vanilla cauldron interactions. + +### Rule-Based Block State Providers + +`RuleBasedStateProvider` now extends `BlockStateProvider`, allowing it to be used wherever a state provider is required. It's implementation hasn't changed, now only requiring `rule_based_state_provider` to be specified as the `type`. As such, all configurations that used `RuleBasedBlockStateProvider` have been broadened to allow any `BlockStateProvider`. + +- `net.minecraft.world.level.levelgen.feature.configurations` + - `DiskConfiguration` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `TreeConfiguration` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `belowTrunkProvider` is now a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `$TreeConfigurationBuilder` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` +- `net.minecraft.world.level.levelgen.feature.stateproviders` + - `BlockStateProvider#getOptionalState` - Gets the state of the block, or otherwise `null`. + - `BlockStateProviderType#RULE_BASED_STATE_PROVIDER` - The type for the rule based state provider. + - `RuleBasedBlockStateProvider` -> `RuleBasedStateProvider`, now a class, implementing `BlockStateProvider` + - The constructor can now take in a nullable fallback `BlockStateProvider` + - `ifTrueThenProvide` - If the predicate is true, provide the given block. + - `simple` -> `always` + - `$Builder` - A builder for constructing the rules for the block to place. + +### Fluid Logic Reorganization + +Generic entity fluid movement has been moved into a separate `EntityFluidInteraction` class, where all tracked fluids are updated and then potentially pushed by the current at a layer time. + +- `net.minecraft.world.entity` + - `Entity` + - `updateInWaterStateAndDoFluidPushing` -> `updateFluidInteraction`, not one-to-one + - `updateFluidHeightAndDoFluidPushing` -> `EntityFluidInteraction#update` + - `getFluidInteractionBox` - Gets the bounding box of the entity during fluid interactions. + - `modifyPassengerFluidInteractionBox` - Returns the modified bounding box of the entity when riding in some vehicle. + - `EntityFluidInteraction` - A handler for managing the fluid interactions and basic movement with an entity. +- `net.minecraft.world.level.chunk.LevelChunkSection#hasFluid` - Whether the chunk section has a fluid block. + +### Removal of Random Patch Feature + +The random patch feature has been completely removed in favor of using placements like most other features. To convert, the `ConfiguredFeature` defined as part of the configuration should be its own file. Then, the placements should specify the `CountPlacement`, followed by the `RandomOffsetPlacement` using a `TrapezoidInt`, and finished with a `BlockPredicateFilter`: + +```json5 +// In `data/examplemod/worldgen/configured_feature/example_configured_feature.json` +{ + // Previously config.feature.feature + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:sweet_berry_bush", + "Properties": { + "age": "3" + } + } + } + } +} + +// In `data/examplemod/worldgen/placed_feature/example_placed_feature.json` +{ + "feature": "examplemod:example_configured_feature", + "placement": [ + { + // Previously config.tries + "type": "minecraft:count", + "count": 96 + }, + { + "type": "minecraft:random_offset", + "xz_spread": { + // Previously config.xz_spread + // The min and max are additive inverses + "type": "minecraft:trapezoid", + "max": 7, + "min": -7, + "plateau": 0 + }, + "y_spread": { + // Previously config.y_spread + "type": "minecraft:trapezoid", + "max": 3, + "min": -3, + "plateau": 0 + } + }, + { + // Previously config.feature.placement + // This contains the placements of the original placed feature + "type": "minecraft:block_predicate_filter", + "predicate": { + "type": "minecraft:all_of", + "predicates": [ + { + "type": "minecraft:matching_block_tag", + "tag": "minecraft:air" + }, + { + "type": "minecraft:matching_blocks", + "blocks": "minecraft:grass_block", + "offset": [ 0, -1, 0 ] + } + ] + } + } + ] +} +``` + +- `net.minecraft.data.worldgen.features` + - `FeatureUtils#simpleRandomPatchConfiguration`, `simplePatchConfiguration` are removed + - Typically replaced by `Feature#SIMPLE_BLOCK` with placements for random offset and filters + - `NetherFeatures#PATCH_*` fields no longer has the `PATCH_*` prefix + - `VegetationFeatures` + - `PATCH_*` fields no longer has the `PATCH_*` prefix + - `WILDFLOWERS_BIRCH_FOREST`, `WILDFLOWERS_MEADOW` -> `WILDFLOWER`, not one-to-one + - `PALE_FOREST_FLOWERS` -> `PALE_FOREST_FLOWER` +- `net.minecraft.world.level.biome.BiomeGenerationSettings#getFlowerFeatures` -> `getBoneMealFeatures` +- `net.minecraft.world.level.levelgen.feature` + - `ConfiguredFeature#getFeatures` -> `getSubFeatures`, now returning a stream of holders-wrapped `ConfiguredFeature`s without this feature + - `Feature` + - `FLOWER`, `NO_BONEMEAL_FLOWER` are removed + - `RANDOM_PATCH` is removed + - `RandomPatchFeature` class is removed +- `net.minecraft.world.level.levelgen.feature.configurations` + - `FeatureConfiguration#getFeatures` -> `getSubFeatures`, now returning a stream of holders-wrapped `ConfiguredFeature`s + - `RandomPatchConfiguration` record is removed +- `net.minecraft.world.level.levelgen.placement.PlacedFeature#getFeatures` now returns a stream of holders-wrapped `ConfiguredFeature`s with this feature concatenated + +### Specific Logic Changes + +- Picture-In-Picture submission calls are now taking in `0xF000F0` instead of `0x000000` for the light coordinates. +- `net.minecraft.client.multiplayer.RegistryDataCollector#collectGameRegistries` `boolean` parameter now handles only updating components from synchronized registries along with tags. +- `net.minecraft.client.renderer.RenderPipelines#VIGNETTE` now blends the alpha with a source of zero and a destination of one. +- `net.minecraft.server.packs.PathPackResources#getResource`, `listPath`, `listResources` resolves the path using the identifier's namespace first. +- `net.minecraft.world.entity.EntitySelector#CAN_BE_PICKED` can now find entities in spectator mode, assuming `Entity#isPickable` is true. +- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#requires` is no longer implemented by default. +- `net.minecraft.world.level.levelgen.WorldOptions#generate_features` field in JSON has been renamed to `generate_structures` to match its java field name. +- `net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate#ONLY_IN_AIR_PREDICATE` now matches the air tag instead of just the air block. +- `net.minecraft.world.level.timers` + - `FunctionCallback`, `FunctionTagCallback` now use `id` instead of `Name` when serializing + - `TimerCallbacks` now uses `type` instead of `Type` when serializing + +### Data Component Additions + +- `dye` - Sets the item as a dye material, used in specific circumstances. +- `additional_trade_cost` - A modifier that offsets the trade cost by the specified amount. +- `pig/sound_variant` - The sounds a pig should make. +- `cow/sound_variant` - The sounds a cow should make. +- `chicken/sound_variant` - The sounds a chicken should make. +- `cat/sound_variant` - The sounds a cat should make. + +### Environment Attribute Additions + +- `visual/block_light_tint` - Tints the color of the light emitted by a block. +- `visual/night_vision_color` - The color when night vision is active. +- `visual/ambient_light_color` - The color of the ambient light in an environment. + +### Tag Changes + +- `minecraft:block` + - `bamboo_plantable_on` -> `supports_bamboo` + - `mushroom_grow_block` -> `overrides_mushroom_light_requirement` + - `small_dripleaf_placeable` -> `supports_small_dripleaf` + - `big_dripleaf_placeable` -> `supports_big_dripleaf` + - `dry_vegetation_may_place_on` -> `supports_dry_vegetation` + - `snow_layer_cannot_survive_on` -> `cannot_support_snow_layer` + - `snow_layer_can_survive_on` -> `support_override_snow_layer` + - `enables_bubble_column_drag_down` + - `enables_bubble_column_push_up` + - `supports_vegetation` + - `supports_crops` + - `supports_stem_crops` + - `supports_stem_fruit` + - `supports_pumpkin_stem` + - `supports_melon_stem` + - `supports_pumpkin_stem_fruit` + - `supports_melon_stem_fruit` + - `supports_sugar_cane` + - `supports_sugar_cane_adjacently` + - `supports_cactus` + - `supports_chorus_plant` + - `supports_chorus_flower` + - `supports_nether_sprouts` + - `supports_azalea` + - `supports_warped_fungus` + - `supports_crimson_fungus` + - `supports_mangrove_propagule` + - `supports_hanging_mangrove_propagule` + - `supports_nether_wart` + - `supports_crimson_roots` + - `supports_warped_roots` + - `supports_wither_rose` + - `supports_cocoa` + - `supports_lily_pad` + - `supports_frogspawn` + - `support_override_cactus_flower` + - `cannot_support_seagrass` + - `cannot_support_kelp` + - `grows_crops` + - `mud` + - `moss_blocks` + - `grass_blocks` + - `substrate_overworld` + - `beneath_tree_podzol_replaceable` + - `beneath_bamboo_podzol_replaceable` + - `cannot_replace_below_tree_trunk` + - `ice_spike_replaceable` + - `forest_rock_can_place_on` + - `huge_brown_mushroom_can_place_on` + - `huge_red_mushroom_can_place_on` + - `prevents_nearby_leaf_decay` +- `minecraft:enchantment` + - `trades/desert_special` is removed + - `trades/jungle_special` is removed + - `trades/plains_special` is removed + - `trades/savanna_special` is removed + - `trades/snow_special` is removed + - `trades/swamp_special` is removed + - `trades/taiga_special` is removed +- `minecraft:entity_type` + - `cannot_be_age_locked` +- `minecraft:fluid` + - `supports_sugar_cane_adjacently` + - `supports_lily_pad` + - `supports_frogspawn` + - `bubble_column_can_occupy` +- `minecraft:item` + - `metal_nuggets` + - `dyeable` is removed, split between: + - `dyes` + - `loom_dyes` + - `loom_patterns` + - `cauldron_can_remove_due` + - `cat_collar_dyes` + - `wolf_collar_dyes` + - `mud` + - `moss_blocks` + - `grass_blocks` +- `minecraft:potion` + - `tradable` +- `minecraft:worldgen/configured_feature` + - `can_spawn_from_bone_meal` + +### List of Additions + +- `net.minecraft.advancements.criterion` + - `FoodPredicate` - A criterion predicate that can check the food level and saturation. + - `MinMaxBounds` + - `validateContainedInRange` - Returns a function which validates the target range and returns as a data result. + - `$Bounds#asRange` - Converts the bounds into a `Range`. +- `net.minecraft.client` + - `Minecraft#sendLowDiskSpaceWarning` - Sends a system toast for low disk space. + - `Options#keyDebugLightmapTexture` - A key mapping to show the lightmap texture. +- `net.minecraft.client.gui.components` + - `AbstractScrollArea` + - `scrollbarWidth` - The width of the scrollbar. + - `defaultSettings` - Constructs the default scrollbar settings given the scroll rate. + - `$ScrollbarSettings` - A record containing the metadata for the scrollbar. + - `DebugScreenOverlay` + - `showLightmapTexture` - Whether to render the lightmap texture on the overlay. + - `toggleLightmapTexture` - Toggles whether the lightmap texture should be rendered. + - `ScrollableLayout` + - `setMinHeight` - Sets the minimum height of the container layout. + - `$ReserveStrategy` - What to use when reserving the width of the scrollbar within the layout. + - `Tooltip` + - `component` - The component of a tooltip to display. + - `style` - The identifier used to compute the tooltip background and frame. +- `net.minecraft.client.gui.components.debug` + - `DebugEntryDetailedMemory` - A debug entry displaying the detailed memory usage. + - `DebugEntryLookingAt#getHitResult` - Gets the hit result of the camera entity. + - `DebugEntryLookingAtEntityTags` - A debug entry for displaying an entity's tags. + - `DebugScreenEntries` + - `DETAILED_MEMORY` - The identifier for the detailed memory usage debug entry. + - `LOOKING_AT_ENTITY_TAGS` - The identifier for the entity tags debug entry. +- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation#with` - Sets the previous focus of the navigation. +- `net.minecraft.client.gui.screens.GenericWaitingScreene#createWaitingWithoutButton` - Creates a waiting screen without showing the button to cancel. +- `net.minecraft.client.gui.screens.options` + - `DifficultyButtons` - A class containing the layout element to create the difficulty buttons. + - `HasGamemasterPermissionReaction` - An interface marking an option screen as able to respond to changing gamemaster permissions. + - `OptionsScreen#getLastScreen` - Returns the previous screen that navigated to this one. + - `WorldOptionsScreen` - A screen containing the options for the current world the player is in. +- `net.minecraft.client.gui.screens.worldselection.EditWorldScreen#conditionallyMakeBackupAndShowToast` - Only makes the backup and shows a toast if the passed in `boolean` is true; otherwise, returns a `false` future. +- `net.minecraft.client.multiplayer.MultiPlayerGameMode#spectate` - Sends a packet to the server that the player will spectate the given entity. +- `net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler#onTeleport` - Runs when a player is moved on the server, typically from some kind of teleportation (e.g. commands, riding an entity). +- `net.minecraft.client.renderer` + - `LightmapRenderStateExtractor` - Extracts the render state for the lightmap. + - `UiLightmap` - The lightmap when in a user interface. + - `RenderPipelines` + - `LINES_DEPTH_BIAS` - A render pipeline that sets the polygon depth offset factor to -1 and the units to -1. + - `ENTITY_CUTOUT_DISSOLVE` - A render pipeline that dissolves an entity model into the background using a mask sampler. +- `net.minecraft.client.renderer.rendertype.RenderType#hasBlending` - Whether the pipeline has a defined blend function. +- `net.minecraft.commands.ArgumentVisitor` - A helper for visiting the arguments for a command. +- `net.minecraft.commands.arguments.selector.EntitySelector#COMPILABLE_CODEC` - A `CompilableString` codec wrapped around an `EntitySelectorParser`. +- `net.minecraft.core.component.predicates` + - `DataComponentPredicates#VILLAGER_VARIANT` - A predicate that checks a villager type. + - `VillagerTypePredicate` - A predicate that checks a villager's type. +- `net.minecraft.core.dispenser.SpawnEggItemBehavior` - The dispenser behavior for spawn eggs. +- `net.minecraft.core.registries.ConcurrentHolderGetter` - A getter that reads references from a local cache, synchronizing to the original when necessary. +- `net.minecraft.data` + - `BlockFamilies` + - `END_STONE` - A family for end stone variants. + - `getFamily` - Gets the family for the base block, when present. + - `BlockFamily` + - `$Builder#tiles`, `$Variant#TILES` - The block that acts as the tiles variant for some base block. + - `$Builder#bricks`, `$Variant#BRICKS` - The block that acts as the bricks variant for some base block. + - `$Builder#cobbled`, `$Variant#COBBLED` - The block that acts as the cobbled variant from some base block. + - `DataGenerator$Uncached` - A data generator which does not cache any information about the files generated. +- `net.minecraft.data.recipes.RecipeProvider` + - `bricksBuilder`, `tilesBuilder` - Builders for the bricks and tiles block variants. + - `generateCraftingRecipe`, `generateStonecutterRecipe` - Generates the appropriate recipes for the given block family. + - `getBaseBlock` -> `getBaseBlockForCrafting` + - `bredAnimal` - Unlocks the recipe if the player has bred two animals together. +- `net.minecraft.gametest.framework` + - `GameTestEvent#createWithMinimumDelay` - Creates a test event with some minimum delay. + - `GameTestHelper` + - `getBoundsWithPadding` - Gets the bounding box of the test area with the specified padding. + - `runBeforeTestEnd` - Runs the runnable at one tick before the test ends. + - `despawnItem` - Despawns all item entities within the distance of the position. + - `discard` - Discards the entity. + - `setTime` - Sets the time of the dimension's default clock. + - `placeBlock` - Places the given block at the relative position and direction. + - `GameTestInstance#padding` - The number of blocks spaced around each game test. + - `GameTestSequence#thenWaitAtLeast` - Waits for at least the specified number of ticks before running the runnable. +- `net.minecraft.nbt.TextComponentTagVisitor` + - `$PlainStyling` - A styling that stores the nbt in a component literal map. + - `$RichStyling` - A styling that stores the nbt with syntax highlighting and formatting. + - `$Styling` - An interface defining how the read tag should be styled. + - `$Token` - The tokens used to more richly represent the tag datas. +- `net.minecraft.network.chat.ResolutionContext` - The context that the component is being resolved to a string within. +- `net.minecraft.network.chat.contents.NbtContents#NBT_PATH_CODEC` - A `CompilableString` codec wrapped around a `NbtPathArgument$NbtPath`. +- `net.minecraft.network.chat.contents.data.BlockDataSource#BLOCK_POS_CDEC` - A `CompilableString` codec wrapped around `Coordinates`. +- `net.minecraft.network.protocol.game` + - `ClientboundGameRuleValuesPacket` - A packet that sends the game rule values in string form to the client. + - `ClientboundGamePacketListener#handleGameRuleValues` - Handles the game rule values sent from the server. + - `ClientboundLowDiskSpaceWarningPacket` - A packet sent to the client warning about low disk space on the machine. + - `ClientGamePacketListener#handleLowDiskSpaceWarning` - Handles the warning packet about low disk space. + - `ServerboundAttackPacket` - A packet sent to the server about what entity the player attacked. + - `ServerboundClientCommandPacket$Action#REQUEST_GAMERULE_VALUES` - Requests the game rule values from the server. + - `ServerboundSetGameRulePacket` - A packet that sends the game rules entries to set from the client. + - `ServerboundSpectateEntityPacket` - A packet sent to the server about what entity the player wants to spectate. + - `ServerGamePacketListener` + - `handleAttack` - Handles the player's attack on an entity. + - `handleSpectateEntity` - Handles the player wanting to spectate an entity. + - `handleSetGameRule` - Handles setting the game rules from the client. +- `net.minecraft.resources` + - `FileToIdConverter#extensionMatches` - Checks if the identifier ends with the specified extension. + - `Identifier` + - `ALLOWED_NAMESPACE_CHARACTERS` - The characters allowed in an identifier's namespace. + - `resolveAgainst` - Resolves the path from the given root by checking `//`. +- `net.minecraft.server` + - `Bootstrap#shutdownStdout` - Closes the stdout stream. + - `MinecraftServer` + - `DEFAULT_GAME_RULES` - The supplied default game rules for a server. + - `warnOnLowDiskSpace` - Sends a warning if the disk space is below 64 MiB. + - `sendLowDiskSpaceWarning` - Sends a warning for low disk space. +- `net.minecraft.server.commands.SwingCommand` - A command that calls `LivingEntity#swing` for all targets. +- `net.minecraft.server.level.ServerPlayer` + - `sendBuildLimitMessage` - Sends an overlay message if the player cannot build anymore in the cooresponding Y direction. + - `sendSpawnProtectionMessage` - Sends an overlay message if the player cannot modify the terrain due to spawn protection. +- `net.minecraft.server.packs.AbstractPackResources#loadMetadata` - Loads the root `pack.mcmeta`. +- `net.minecraft.server.packs.resources.ResourceMetadata$MapBased` - A resource metadata that stores the sections in a map. +- `net.minecraft.tags.TagLoader$ElementLookup#fromGetters` - Constructs an element lookup from the given `HolderGetter`s depending on whether the element is required or not. +- `net.minecraft.util` + - `ARGB#gray` - Gets a grayscale color based on the given brightness. + - `CompilableString` - A utility for taking some string pattern and compiling it to an object through some parser. + - `LightCoordsUtil` - A utility for determining the light coordinates from light values. + - `ProblemReporter$MapEntryPathElement` - A path element for some entry key in a map. + - `Util#allOfEnumExcept` - Gets the set of all enums except the provided value. +- `net.minecraft.util.thread.BlockableEventLoop#hasDelayedCrash` - Whether there is a crash report queued. +- `net.minecraft.util.valueproviders.TrapezoidInt` - Samples a random value with a trapezoidal distribution. +- `net.minecraft.world.InteractionHand#STREAM_CODEC` - The network codec for the interaction hand. +- `net.minecraft.world.attribute` + - `AttributeType#toFloat` - Gets the attribute value as a `float`, or throws an exception if not defined. + - `AttributeTypes#INTEGER` - An integer attribute type. + - `LerpFunction#ofInteger` - A lerp function for an integer value. +- `net.minecraft.world.attribute.modifier` + - `AttributeModifier#INTEGER_LIBRARY` - A library of operators to apply for integers. + - `IntegerModifier` - A modifier that applies some argument to the integer value. +- `net.minecraft.world.entity` + - `AgeableMob` + - `AGE_LOCK_COOLDOWN_TICKS` - The number of ticks to wait before the entity can be age locked/unlocked. + - `ageLockParticleTimer` - The time for displaying particles while age locking/unlocking. + - `Entity` + - `applyEffectsFromBlocksForLastMovements` - Applies any block effects to this entity for the last movement, used by items. + - `$Flags` - An annotation that marks a particular value as a bitset of flags for an entity. + - `LivingEntity#getLiquidCollisionShape` - Return's the bounds of the entity when attempting to collide with a liquid. + - `Mob` + - `asValidTarget` - Checks whether an entity is a valid target (can attack) for this entity. + - `getTargetUnchecked` - Gets the raw target without checking if its valid. + - `canAgeUp` - If the entity can grow up into a more mature variant. + - `setAgeLocked`, `isAgeLocked` - Whether the entity cannot grow up. + - `NeutralMob#getTargetUnchecked` - Gets the raw target without checking if its valid. + - `TamableAnimal#feed` - The player gives the stack as food, healing them either based on the stored component or some default value. +- `net.minecraft.world.entity.ai.behavior` + - `BehaviorControl#getRequiredMemories` - The list of memories required by the behavior. + - `GoAndGiveItemsToTarget$ItemThrower` - An interface that handles what should occur if an item is thrown because of this entity's behavior. +- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder$TriggerWithResult#memories` - The list of memories required by the behavior. +- `net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities#nearbyEntities` - The list of entities within the follow range of this one. +- `net.minecraft.world.entity.decoration.LeashFenceKnotEntity` + - `getKnot` - Finds the knot at the given position, else returns an empty optional. + - `createKnot` - Creates a new knot and adds it to the level. +- `net.minecraft.world.entity.monster.piglin` + - `PiglinAi` + - `MAX_TIME_BETWEEN_HUNTS` - The maximum number of seconds before a piglin begins to hunt again. + - `findNearbyAdultPiglins` - Returns a list of all adult piglins in this piglin's memory. +- `net.minecraft.world.entity.raid.Raid` + - `getBannerComponentPatch` - Gets the components of the banner pattern. + - `getOminousBannerTemplate` - Gets the stack template for the omnious banner. +- `net.minecraft.world.inventory.SlotRanges` + - `MOB_INVENTORY_SLOT_OFFSET` - The start index of a mob's inventory. + - `MOB_INVENTORY_SIZE` - The size of a mob's inventory. +- `net.minecraft.world.item.component.BundleContents#BEEHIVE_WEIGHT` - The weight of a beehive. +- `net.minecraft.world.item.enchantment.EnchantmentTarget#NON_DAMAGE_CODEC` - A codec that only allows the attacker and victim enchantment targets. +- `net.minecraft.world.level.block.BigDripleafBlock#canGrowInto` - Whether the dripleaf can grow into the specified position. +- `net.minecraft.world.level.block.grower.TreeGrower#getMinimumHeight` - If present, gets the base height of the trunk placer. +- `net.minecraft.world.level.block.state` + - `BlockBehaviour$PostProcess` - An interface that gets the position to mark for post-processing. + - `StateDefinition` + - `propertiesCodec` - The map codec for the state properties. + - `isSingletonState` - If the definition only contains one state. + - `StateHolder#isSingletonState` - If the holder only contains one state. +- `net.minecraft.world.level.block.state.properties` + - `NoteBlockInstrument` + - `TRUMPET` - The sound a copper block makes when placed under a note block. + - `TRUMPET_EXPOSED` - The sound an exposed copper block makes when placed under a note block. + - `TRUMPET_OXIDIZED` - The sound an oxidized copper block makes when placed under a note block. + - `TRUMPET_WEATHERED` - The sound a weathered copper block makes when placed under a note block. + - `Property$Value#valueName` - Gets the name of the value. +- `net.minecraft.world.level.dimension.DimensionDefaults` + - `BLOCK_LIGHT_TINT` - The default tint for the block light. + - `NIGHT_VISION_COLOR` - The default color when in night vision. + - `TURTLE_EGG_HATCH_CHANCE` - The chance of a turtle egg hatching on a random tick. +- `net.minecraft.world.level.gamerules.GameRule#getIdentifierWithFallback` - Gets the identifier of the game rule, or else the unregistered identifier. +- `net.minecraft.world.level.levelgen` + - `NoiseBasedChunkGenerator#getInterpolatedNoiseValue` - Gets the interpolated density at the given position, or the not-a-number value if the Y is outside the range of the noise settings. + - `NoiseChunk#getInterpolatedDensity` - Computes the full noise density. +- `net.minecraft.world.level.levelgen.feature.AbstractHugeMushroomFeature#MIN_MUSHROOM_HEIGHT` - The minimum mushroom height. +- `net.minecraft.world.level.levelgen.feature.configurations.BlockBlobConfiguration` - The configuration for the block blob feature. +- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer#getBaseHeight` - Returns the minimum height of the trunk. +- `net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement#ofTriangle` - Creates a trapezoidal distribution to select from for the XZ and Y range. +- `net.minecraft.world.level.material` + - `FluidState#isFull` - If the fluid amount is eight. + - `LavaFluid#LIGHT_EMISSION` - The amount of light the lava fluid emits. +- `net.minecraft.world.level.pathfinder.PathType#BIG_MOBS_CLOSE_TO_DANGER` - A path malus for mobs with an entity width greater than a block. +- `net.minecraft.world.level.storage.LevelStorageSource#writeWorldGenSettings` - Wriets the world generation settings to its saved data location. +- `net.minecraft.world.level.storage.loot.functions` + - `EnchantRandomlyFunction$Builder#withOptions` - Specifies the enchantments that can be used to randomly enchant this item. + - `SetRandomDyesFunction` - An item function that applies a random dye (if the item is in the `dyeable` tag) to the `DYED_COLOR` component from the provided list. + - `SetRandomPotionFunction` - An item function that applies a random potion to the `POTION_CONTENTS` component from the provided list. +- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#ADDITIONAL_COST_COMPONENT_ALLOWED` - Enables a trade to incur an additional cost if desired by the wanted stack or modifiers. +- `net.minecraft.world.level.storage.loot.predicates.EnvironmentAttributeCheck` - A loot condition that checks whether that given attribute matches the provided value. +- `net.minecraft.world.level.storage.loot.providers.number` + - `EnvironmentAttributeValue` - A provider that gets the attribute value as a float. + - `Sum` - A provider that sums the value of all provided number providers. +- `net.minecraft.world.phys.AABB$Builder#isDefined` - Checks if there is at least one point making up the bounding box. + +### List of Changes + +- `net.minecraft.advancements.criterion` + - `EntityTypePredicate#matches` now takes in a holder-wrapped `EntityType` instead of the raw type itself + - `KilledTrigger$TriggerInstance#entityPredicate` -> `entity` + - `PlayerPredicate` now takes in a `FoodPredicate` + - Can be set using `PlayerPredicate$Builder#setFood` +- `net.minecraft.client.gui` + - `GuiGraphics` + - `blit` now has an overload that takes in the `GpuTextureView` and the `GpuSampler` + - `setTooltipForNextFrame` now has an overload that takes in a list of `FormattedCharSequence`s for the tooltip and whether to replace any existing tooltip + - `ItemSlotMouseAction#onSlotClicked` now takes in a `ContainerInput` instead of a `ClickType` +- `net.minecraft.client.gui.components` + - `AbstractContainerWidget` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `AbstractScrollArea` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `scrollbarVisible` -> `scrollable` + - `scrollBarY` is now public + - `scrollRate` is now longer abstract + - `AbstractTextAreaWidget` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `PopupScreen$Builder#setMessage` -> `addMessage`, not one-to-one + - `ScrollableLayout$Container` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `Tooltip#create` now has an overload that takes in an optional `TooltipComponent` and style `Identifier` +- `net.minecraft.client.gui.components.debug` + - `DebugEntryLookingAtBlock`, `DebugEntryLookingAtFluid` -> `DebugEntryLookingAt` + - More specifically, `$BlockStateInfo`, `$BlockTagInfo`, `$FluidStateInfo`, `$FluidTagInfo` + - `DebugEntryLookingAtEntity#GROUP` is now public + - `DebugScreenEntries` + - `LOOKING_AT_BLOCK` -> `LOOKING_AT_BLOCK_STATE`, `LOOKING_AT_BLOCK_TAGS` + - `LOOKING_AT_FLUID` -> `LOOKING_AT_FLUID_STATE`, `LOOKING_AT_FLUID_TAGS` + - `DebugScreenEntryList` now takes in a `DataFixer` +- `net.minecraft.client.gui.components.tabs.TabNavigationBar#setWidth` -> `updateWidth`, not one-to-one +- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation` now takes in a nullable `ScreenRectangle` for the previous focus +- `net.minecraft.client.gui.screens` + - `ConfirmScreen#layout` is now final + - `DemoIntroScreen` replaced by `ClientPacketListener#openDemoIntroScreen`, now private + - `GenericWaitingScreen` now takes in three `boolean`s for showing the loading dots, the cancel button, and whether the screen should close on escape +- `net.minecraft.client.gui.screens.inventory.AbstractMountInventoryScreen#mount` is now final +- `net.minecraft.client.gui.screens.options` + - `OptionsScreen` now implements `HasGamemasterPermissionReaction` + - The constructor now takes in a `boolean` for if the player is currently in a world + - `createDifficultyButton` now handles within `WorldOptionsScreen#createDifficultyButtons`, not one-to-one + - `WorldOptionsScreen` now implements `HasGamemasterPermissionReaction` + - `createDifficultyButtons` -> `DifficultyButtons#create`, now public +- `net.minecraft.client.multiplayer` + - `ClientLevel#syncBlockState` can now take in a nullable player position + - `MultiPlayerGameMode#handleInventoryMouseClick` now takes in a `ContainerInput` instead of a `ClickType` + - `WeatherEffectRenderer#render` no longer takes in the `MultiBufferSource` +- `net.minecraft.client.renderer.block.ModelBlockRenderer$Cache#getLightColor` -> `getLightCoords` +- `net.minecraft.client.renderer.blockentity.state` + - `BrushableBlockRenderState#itemState` is now final + - `EndPortalRenderState` is now a final set of `Direction`s rather than an `EnumSet` + - `ShelfRenderState#items` is now final +- `net.minecraft.client.renderer.entity.state` + - `FallingBlockRenderState#movingBlockRenderState` is now final + - `HumanoidRenderState#attackArm` -> `ArmedEntityRenderState#attackArm` + - `WitherRenderState#xHeadRots`, `yHeadRots` are now final +- `net.minecraft.client.resources.sounds.AbstractSoundInstance#random` is now final +- `net.minecraft.commands.SharedSuggestionProvider#getCustomTabSugggestions` -> `getCustomTabSuggestions` +- `net.minecraft.commands.arguments.ComponentArgument#getResolvedComponent` now takes in a non-nullable `Entity` +- `net.minecraft.commands.arguments.selector.SelectorPattern` replaced by `CompilableString` +- `net.minecraft.core.HolderGetter$Provider#get`, `getOrThrow` now has overloads that take in the `TagKey` +- `net.minecraft.data` + - `BlockFamily` + - `shouldGenerateRecipe` -> `shouldGenerateCraftingRecipe`, `shouldGenerateStonecutterRecipe` + - `$Builder#dontGenerateRecipe` -> `dontGenerateCraftingRecipe`, `generateStonecutterRecipe` + - `DataGenerator` is now abstract + - The constructor now only takes in the `Path` output, not the `WorldVersion` or whether to always generate + - The original implementation can be founded in `DataGenerator$Cached` + - `run` is now abstract + - `Main#addServerProviders` -> `addServerDefinitionProviders`, no longer taking in the dev `boolean`, not one-to-one + - The remaining logic has been put into `addServerConverters`, taking in the dev `boolean` but not the report `boolean` +- `net.minecraft.data.loot.BlockLootSubProvider` + - `explosionResistant` is now private + - `enabledFeatures` is now private + - `map` is now private +- `net.minecraft.data.recipes` + - `RecipeProvider$FamilyRecipeProvider` -> `$FamilyCraftingRecipeProvider`, `$FamilyStonecutterRecipeProvider` + - `SingleItemRecipeBuilder#stonecutting` moved to a parameter on the `BlockFamily` +- `net.minecraft.data.structures.SnbtToNbt` now has an overload that takes in a single input folder path +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `assertBlockPresent` now has an overload that only takes in the block to check for + - `moveTo` now has overloads for taking in the `BlockPos` and `Vec3` for the position + - `assertEntityInstancePresent` now has an overload that inflates (via a `double`) the bounding box to check entities within + - `GameTestServer#create` now takes in an `int` for the number of times to run all matching tests + - `StructureUtils#testStructuresDir` split into `testStructuresTargetDir`, `testStructuresSourceDir` + - `TestData` now takes in an `int` for the number of blocks padding around the test +- `net.minecraft.nbt` + - `NbtUtils` + - `addDataVersion` now uses a generic for the `Dynamic` instead of the explicit nbt tag + - `getDataVersion` now has an overload that defaults to -1 if the version is not specified + - `TextComponentTagVisitor` can now take in a `$Styling` and a `boolean` of whether to sort the keys + - `handleEscapePretty` is now a `private` instance method from `protected` static +- `net.minecraft.network.FriendlyByteBuf` + - `readVec3`, `writeVec3` replaced with `Vec3#STREAM_CODEC` + - `readLpVec3`, `writeLpVec3` replaced with `Vec3#LP_STREAM_CODEC` +- `net.minecraft.network.chat` + - `Component` + - `nbt` now takes in a `CompilableString` instead of a `String` + - `object` now has an overload that takes in a `Component` fallback + - `ComponentContents#resolve` now takes in a `ResolutionContext` instead of the `CommandSourceStack` and `Entity` + - `ComponentUtils#updateForEnttiy` -> `resolve`, taking in the `ResolutionContext` instead of the `CommandSourceStack` and `Entity` + - `LastSeenMessages#EMPTY` is now final +- `net.minecraft.network.chat.contents` + - `NbtContents` is now a record, the constructor taking in a `CompilableString` instead of a `String` + - `ObjectContents` now takes in an optional `Component` for the fallback if its contents cannot be validated +- `net.minecraft.network.chat.contents.data` + - `BlockDataSource` now takes in a `CompilableString` for the `Coordinates` instead of the pattern and compiled position + - `EntityDataSource` now takes in a `CompilableString` for the `EntitySelector` instead of the pattern and compiled selector +- `net.minecraft.network.chat.contents.objects.ObjectInfo#description` -> `defaultFallback` +- `net.minecraft.network.protocol.game` + - `ClientboundSetEntityMotionPacket` is now a record + - `ServerboundContainerClickPacket` now takes in a `ContainerInput` instead of a `ClickType` + - `ServerboundInteractPacket` is now a record, now taking in the `Vec3` interaction location +- `net.minecraft.references` + - `Blocks` -> `BlockIds` + - `Items` -> `ItemIds` +- `net.minecraft.resources` + - `FileToIdConverter` is now a record + - `RegistryDataLoader#load` now returns a `CompletableFuture` of the frozen registry access +- `net.minecraft.server.MinecraftServer` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash + - `throwIfFatalException` -> `BlockableEventLoop#throwDelayedException`, now private, not one-to-one + - `setFatalException` -> `BlockableEventLoop#delayCrash`, `relayDelayCrash`; not one-to-one +- `net.minecraft.server.commands.ChaseCommand#DIMENSION_NAMES` is now final +- `net.minecraft.server.dedicated.DedicatedServerProperties#acceptsTransfers` is now final +- `net.minecraft.server.packs` + - `BuiltInMetadata` has been merged in `ResourceMetadata` + - `get` -> `ResourceMetadata#getSection` + - `of` -> `ResourceMetadata#of` + - `PathPackResources#getNamespaces` now has a static overload that takes in the root directory `Path` + - `VanillaPackResourcesBuilder#setMetadata` now takes in a `ResourceMetadata` instead of a `BuiltInMetadata` +- `net.minecraft.server.players.OldUsersConverter#serverReadyAfterUserconversion` replaced by `areOldUserListsRemoves`, now `public` +- `net.minecraft.tags.TagLoader` + - `loadTagsFromNetwork` now takes in a `Registry` instead of a `WritableRegistry`, returning a map of tag keys to a list of holder entries + - `loadTagsForRegistry` now has an overload which takes in registry key along with an element lookup, returning a map of tag keys to a list of holder entries +- `net.minecraft.util` + - `Brightness` + - `pack` -> `LightCoordsUtil#pack` + - `block` -> `LightCoordsUtil#block` + - `sky` -> `LightCoordsUtil#sky` + - `RandomSource#createNewThreadLocalInstance` -> `createThreadLocalInstance` + - Now has an overload to specify the seed + - `Util#copyAndAdd` now has an overload that takes in a varargs of elements +- `net.minecraft.util.thread` + - `BlockableEventLoop` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash + - `ReentrantBlockableEventLoop` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash +- `net.minecraft.world.InteractionResult$ItemContext#NONE`, `DEFAULT` are now final +- `net.minecraft.world.attribute` + - `AttributeType` now takes in a `ToFloatFunction` for use in a number provider + - `ofInterpolated` now takes in a `ToFloatFunction` + - `EnvironmentAttributeReader#getValue` now has an overload that takes in the `LootContext` +- `net.minecraft.world.entity` + - `Avatar` is now abstract + - `Entity` + - `fluidHeight` is now final + - `getTags` -> `entityTags` + - `getRandomY` now has an overload that specifies the spread `double` + - `Leashable$Wrench#ZERO` is now final + - `LivingEntity` + - `interpolation` is now final + - `swingingArm` is now nullable + - `canAttackType` -> `canAttack`, not one-to-one, taking in the `LivingEntity` instead of the `EntityType` + - `lungeForwardMaybe` -> `postPiercingAttack` + - `entityAttackRange` -> `getAttackRangeWith`, now taking in the `ItemStack` used to attack +- `net.minecraft.world.entity.ai.behavior` + - `GoAndGiveItemsToTarget` now takes in the `$ItemThrower` + - `throwItem` -> `BehaviorUtils#throwItem`, not one-to-one + - `SpearAttack` no longer takes in the approach distance `float` + - `TryLaySpawnOnWaterNearLand` -> `TryLaySpawnOnFluidNearLand`, not one-to-one +- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder#sequence` now takes in a `Oneshot` for the second entry instead of a `Trigger` +- `net.minecraft.world.entity.ai.goal` + - `BoatGoals` -> `FollowPlayerRiddenEntityGoal$FollowEntityGoal` + - `BOAT` is replaced by `ENTITY` + - `FollowBoatGoal` -> `FollowPlayerRiddenEntityGoal`, not one-to-one +- `net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal#targetConditions` is now final +- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#getMemory` -> `getMemoryToSet` +- `net.minecraft.world.entity.decoration.Mannequin#getProfile` -> `Avatar#getProfile`, now `public` and `abstract` + - Still implemented in `Mannequin` +- `net.minecraft.world.entity.item.ItemEntity#DEFAULT_HEALTH` is now `public` from `private` +- `net.minecraft.world.entity.monster.breeze.Breeze#idle`, `slide`, `slideBack`, `longJump`, `shoot`, `inhale` are now final +- `net.minecraft.world.entity.monster.piglin.PiglinAi#isZombified` now takes in the `Entity` instead of the `EntityType` +- `net.minecraft.world.entity.monster.warden.Warden#roarAnimationState`, `sniffAnimationState`, `emergeAnimationState`, `diggingAnimationState`, `attackAnimationState`, `sonicBoomAnimationState` are now final +- `net.minecraft.world.entity.monster.zombie.Zombie#handleAttributes` now takes in the `EntitySpawnReason` +- `net.minecraft.world.entity.player` + - `Input#EMPTY` is now final + - `Player` + - `currentImpulseImpactPos` -> `LivingEntity#currentImpulseImpactPos` + - `currentExplosionCause` -> `LivingEntity#currentExplosionCause` + - `setIgnoreFallDamageFromCurrentImpulse` -> `LivingEntity#setIgnoreFallDamageFromCurrentImpulse` + - `applyPostImpulseGraceTime` -> `LivingEntity#applyPostImpulseGraceTime` + - `isIgnoringFallDamageFromCurrentImpulse` -> `LivingEntity#isIgnoringFallDamageFromCurrentImpulse` + - `tryResetCurrentImpulseContext` -> `LivingEntity#tryResetCurrentImpulseContext` + - `resetCurrentImpulseContext` -> `LivingEntity#resetCurrentImpulseContext` + - `isInPostImpulseGraceTime` -> `LivingEntity#isInPostImpulseGraceTime` + - `isWithinAttackRange` now takes in the `ItemStack` attacked with +- `net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior$MinecartStep#EMPTY` is now final +- `net.minecraft.world.inventory.AbstractContainerMenu#getQuickCraftPlaceCount` now takes in the number of quick craft slots instead of the set of slots itself +- `net.minecraft.world.item` + - `BundleItem#getSelectedItem` -> `getSelectedItemIndex` + - `CreativeModeTab$Output` is now `protected` from `public` + - `EnderpearlItem#PROJECTILE_SHOOT_POWER` is now final + - `Item$Properties#requiredFeatures` now has an overload that takes in a `FeatureFlagSet` + - `Items#register*` methods are now `private` from `public` + - `ItemUtils#onContainerDestroyed` now takes in a `Stream` of `ItemStack`s instead of an `Iterable` + - `SignApplicator#tryApplyToSign`, `canApplyToSign` now take in the `ItemStack` being used + - `SnowballItem#PROJECTILE_SHOOT_POWER` is now final + - `ThrowablePotionItem#PROJECTILE_SHOOT_POWER` is now final + - `WindChargeItem#PROJECTILE_SHOOT_POWER` is now final +- `net.minecraft.world.item.alchemy.Potions` now deal with `Holder$Reference`s instead of the super `Holder` +- `net.minecraft.world.item.component` + - `AttackRange` + - `minRange` -> `minReach` + - `maxRange` -> `maxReach` + - `minCreativeRange` -> `minCreativeReach` + - `maxCreativeRange` -> `maxCreativeReach` + - `BundleContents` + - `weight` now returns a `DataResult`-wrapped `Fraction` instead of the raw object + - `getSelectedItem` -> `getSelectedItemIndex` + - `WrittenBookContent` + - `tryCraftCopy` -> `craftCopy` + - `resolveForItem`, `resolve` now take in the `ResolutionContext` and `HolderLookup$Provider` instead of the `CommandSourceStack` and `Player` +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect#codec` no longer takes in the `ContextKeySet` + - `Enchantment#doLunge` -> `doPostPiercingAttack` + - `EnchantmentHelper#doLungeEffects` -> `doPostPiercingAttackEffects` + - `TargetedConditionalEffect#codec`, `equipmentDropsCodec` no longer take in the `ContextKeySet` +- `net.minecraft.world.item.enchantment.effects.EnchantmentAttributeEffect#CODEC` -> `MAP_CODEC` +- `net.minecraft.world.item.equipment.Equippable#canBeEquippedBy` now takes in a holder-wrapped `EntityType` instead of the raw type itself +- `net.minecraft.world.item.trading.VillagerTrades#LIBRARIAN_5_EMERALD_NAME_TAG` was replaced with `LIBRARIAN_5_EMERALD_YELLOW_CANDLE`, `LIBRARIAN_5_EMERALD_RED_CANDLE`, not one-to-one + - The original trade was moved to `WANDERING_TRADER_EMERALD_NAME_TAG` +- `net.minecraft.world.level` + - `LevelAccessor` no longer implements `LevelReader` + - `LevelHeightAccessor#isInsideBuildHeight` now has an overload that takes in the `BlockPos` +- `net.minecraft.world.level.block` + - `BigDripleafBlock#canPlaceAt` now takes in the `LevelReader` instead of the `LevelHeightAccessor`, and no longer takes in the old state + - `BubbleColumnBlock#updateColumn` now takes in the bubble column `Block` + - `FireBlock#setFlammable` is now `private` from `public` + - `MultifaceSpreader$DefaultSpreaderConfig#block` is now final + - `SnowyDirtBlock` -> `SnowyBlock` + - `SpreadingSnowyDirtBlock` -> `SpreadingSnowyBlock` + - The constructor now takes in the `ResourceKey` for the 'base' block, or the block when the snow or any other decoration (e.g. grass) is removed +- `net.minecraft.world.level.block.entity.TestInstanceBlockEntity` + - `getTestBoundingBox` - The bounding box of the test inflated by its padding. + - `getTestBounds` - The axis aligned bounding box of the test inflated by its padding. +- `net.minecraft.world.level.block.entity.vault` + - `VaultConfig#DEFAULT`, `CODEC` are now final + - `VaultServerData#CODEC` is now final + - `VaultSharedData#CODEC` is now final +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `$BlockStateBase` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `hasPostProcess` -> `getPostProcessPos`, not one-to-one + `$Properties#hasPostProcess` -> `getPostProcessPos`, not one-to-one + - `BlockState` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `StateHolder` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `populateNeighbours` -> `initializeNeighbors`, now package-private instead of `public`; not one-to-one + - `getValues` now returns a stream of `Property$Value`s + - `codec` now takes in the function that gets the state definition from some object +- `net.minecraft.world.level.chunk.ChunkAccess#blendingData` is now final +- `net.minecraft.world.level.chunk.storage.SimpleRegionStorage#upgradeChunkTag` now takes in an `int` for the target version +- `net.minecraft.world.level.gameevent.vibrations.VibrationSystem$Data#CODEC` is now final +- `net.minecraft.world.level.gamerules.GameRules` now has an overload that takes in a list of `GameRule`s +- `net.minecraft.world.level.levelgen` + - `NoiseRouterData#caves` no longer takes in the `HolderGetter` for the `NormalNoise$NoiseParameters` + - `WorldDimensions#keysInOrder` now takes in a set of `LevelStem` keys instead of a stream +- `net.minecraft.world.level.levelgen.blockpredicates` + - `TrueBlockPredicate#INSTANCE` is now final + - `UnobstructedPredicate#INSTANCE` is now final +- `net.minecraft.world.level.levelgen.feature` + - `AbstractHugeMushrromFeature` + - `isValidPosition` now takes in a `WorldGenLevel` instead of the `LevelAccessor` + - `placeTrunk` now takes in the `WorldGenLevel` instead of the `LevelAccessor` + - `makeCap` now takes in the `WorldGenLevel` instead of the `LevelAccessor` + - `BlockBlobFeature` now uses a `BlockBlobConfiguration` generic + - `Feature` + - `FOREST_ROCK` replaced by `BLOCK_BLOB` + - `ICE_SPIKE` replaced by `SPIKE` + - `IceSpikeFeature` -> `SpikeFeature`, not one-to-one + - `SpikeFeature` is now `EndSpikeFeature`, not one-to-one + - `NUMBER_OF_SPIKES` -> `EndSpikeFeature#NUMBER_OF_SPIKES` + - `getSpikesForLevel` -> `EndSpikeFeature#getSpikesForLevel` +- `net.minecraft.world.level.levelgen.feature.configurations` + - `HugeMushroomFeatureConfiguration` is now a record, taking in a can place on `BlockPredicate` + - `SpikeConfiguration` -> `EndSpikeConfiguration` is now a record + - The original `SpikeConfiguration` is now for the ice spike, taking in the blocks to use, along with predicates of where to place and whether it can replace a block present + - `TreeConfiguration` + - `dirtProvider`, `forceDirt` have been replaced by `belowTrunkProvider` + - `dirtProvider` commonly uses `CAN_PLACE_BELOW_OVERWORLD_TRUNKS` + - `forceDirt` commonly uses `PLACE_BELOW_OVERWORLD_TRUNKS` + - `$TreeConfigurationBuilder` + - `dirtProvider`, `dirt`, `forceDirt` have been replaced by `belowTrunkProvider` +- `net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacer` + - `createFoliage` now takes in a `WorldGenLevel` isntead of a `LevelSimulatedReader` + - `placeLeavesRow`, `placeLeavesRowWithHangingLeavesBelow` now take in a `WorldGenLevel` isntead of a `LevelSimulatedReader` + - `tryPlaceExtension`, `tryPlaceLeaf` now take in a `WorldGenLevel` isntead of a `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacer#placeRoots`, `placeRoot` now take in a `WorldGenLevel` instead of a `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.stateproviders` + - `BlockStateProvider#getState` now takes in the `WorldGenLevel` +- `net.minecraft.world.level.levelgen.feature.treedecorators` + - `TreeDecorator$Context` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `level` now returns a `WorldGenLevel` instead of the `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer` + - `placeTrunk` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `setDirtAt` -> `placeBelowTrunkBlock`, now taking in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `placeLog` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `placeLogIfFree` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `validTreePos` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `isFree` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.placement.BiomeFilter#CODEC` is now final +- `net.minecraft.world.level.levelgen.structure.TemplateStructurePiece#template`, `placeSettings` are now final +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `DirectPoolAlias#CODEC` is now final + - `RandomGroupPoolAlias#CODEC` is now final + - `RandomPoolAlias#CODEC` is now final +- `net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings#CODEC` is now final +- `net.minecraft.world.level.levelgen.synth.PerlinNoise#getValue` no longer takes in the `boolean` for whether to flat the Y value instead of applying the frequency factor +- `net.minecraft.world.level.material.FluidState` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` +- `net.minecraft.world.level.pathfinder.PathType` + - `DANGER_POWDER_SNOW` -> `ON_TOP_OF_POWDER_SNOW` + - `DANGER_FIRE` -> `FIRE_IN_NEIGHBOR` + - `DAMAGE_FIRE` -> `FIRE` + - `DANGER_OTHER` -> `DAMAGING_IN_NEIGHBOR` + - `DAMAGE_OTHER` -> `DAMAGING`, + - `DANGER_TRAPDOOR` -> `ON_TOP_OF_TRAPDOOR` +- `net.minecraft.world.level.saveddata.maps.MapItemSavedData#tickCarriedBy` now takes in a nullable `ItemFrame` +- `net.minecraft.world.level.storage.loot.functions` + - `EnchantRandomlyFunction` now takes in a `boolean` of whether to include the additional trade cost component from the stack being enchanted + - Set via `$Builder#includeAdditionalCostComponent` + - `EnchantWithLevelsFunction` now takes in a `boolean` of whether to include the additional trade cost component from the stack being enchanted + - Set via `$Builder#includeAdditionalCostComponent` + - `$Builder#fromOptions` -> `withOptions`, now with overload to take in an optional `HolderSet` + +### List of Removals + +- `net.minecraft.SharedConstants#USE_WORKFLOWS_HOOKS` +- `net.minecraft.client.data.models.BlockModelGenerators#createGenericCube` +- `net.minecraft.client.Minecraft#delayCrashRaw` +- `net.minecraft.client.gui.components.EditBox#setFilter` +- `net.minecraft.client.multiplayer.ClientPacketListener#getId` +- `net.minecraft.client.renderer.Sheets` + - `shieldSheet` + - `bedSheet` + - `shulkerBoxSheet` + - `signSheet` + - `hangingSignSheet` + - `chestSheet` +- `net.minecraft.client.renderer.rendertype.RenderTypes#weather` +- `net.minecraft.data.loot.BlockLootSubProvider(Set, FeatureFlagSet, Map, HolderLookup$Provider)` +- `net.minecraft.gametest.framework.StructureUtils#DEFAULT_TEST_STRUCTURES_DIR` +- `net.minecraft.nbt.NbtUtils` + - `addCurrentDataVersion` + - `prettyPrint(Tag)` +- `net.minecraft.server.packs.AbstractPackResources#getMetadataFromStream` +- `net.minecraft.server.players.PlayerList#getSingleplayerData` +- `net.minecraft.util` + - `Mth#createInsecureUUID` + - `LightCoordsUtil#UI_FULL_BRIGHT` +- `net.minecraft.world` + - `ContainerListener` + - `Difficulty#getKey` + - `SimpleContainer#addListener`, `removeListener` +- `net.minecraft.world.entity.ai.memory.MemoryModuleType#INTERACTABLE_DOORS` +- `net.minecraft.world.entity.monster.Zoglin#MEMORY_TYPES` +- `net.minecraft.world.entity.monster.creaking.Creaking#MEMORY_TYPES` +- `net.minecraft.world.entity.monster.hogling.Hoglin#MEMORY_TYPES` +- `net.minecraft.world.item` + - `BundleItem#hasSelectedItem` + - `Item#getName()` + - `ItemStack` + - `isFramed`, `getFrame` + - `setEntityRepresentation`, `getEntityRepresentation` +- `net.minecraft.world.item.component` + - `BundleContents` + - `getItemUnsafe` + - `hasSelectedItem` + - `WrittenBookContent#MAX_CRAFTABLE_GENERATION` +- `net.minecraft.world.level.block.LiquidBlock#SHAPE_STABLE` +- `net.minecraft.world.level.levelgen.feature` + - `Feature#isStone`, `isDirt`, `isGrassOrDirt` +- `net.minecraft.world.level.levelgen.material.WorldGenMaterialRule` +- `net.minecraft.world.level.storage.loot.functions.SetOminousBottleAmplifierFunction#amplifier` diff --git a/src/detailed-primers/README.md b/src/detailed-primers/README.md new file mode 100644 index 0000000..05feeef --- /dev/null +++ b/src/detailed-primers/README.md @@ -0,0 +1,16 @@ +# Detailed Primers + +These chapters preserve the upstream primer content step by step so the direct guide does not lose version-specific detail. + +Read them in order: + +- [1.21.1 -> 1.21.2/3](1.21.2-from-1.21.1.md) +- [1.21.2/3 -> 1.21.4](1.21.4-from-1.21.2-3.md) +- [1.21.4 -> 1.21.5](1.21.5-from-1.21.4.md) +- [1.21.5 -> 1.21.6](1.21.6-from-1.21.5.md) +- [1.21.6 -> 1.21.7](1.21.7-from-1.21.6.md) +- [1.21.7 -> 1.21.8](1.21.8-from-1.21.7.md) +- [1.21.8 -> 1.21.9](1.21.9-from-1.21.8.md) +- [1.21.9 -> 1.21.10](1.21.10-from-1.21.9.md) +- [1.21.10 -> 1.21.11](1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](26.1-from-1.21.11.md) diff --git a/src/direct-port-guide.md b/src/direct-port-guide.md new file mode 100644 index 0000000..0a829e4 --- /dev/null +++ b/src/direct-port-guide.md @@ -0,0 +1,21598 @@ +# Direct Port Guide + +This is the compiled `1.21.1 -> 26.1` migration guide. + +It is intentionally not a per-version recap. It folds repeated subsystem churn into the direct end state you should target when porting from `1.21.1` straight to `26.1`. The separate primer chapters remain as appendices for edge cases and exhaustive rename lists. + +## Version chain this compilation covers + +This guide compiles the following primer path into one direct migration target: + +1. `1.21.1 -> 1.21.2/3` +2. `1.21.2/3 -> 1.21.4` +3. `1.21.4 -> 1.21.5` +4. `1.21.5 -> 1.21.6` +5. `1.21.6 -> 1.21.7` +6. `1.21.7 -> 1.21.8` +7. `1.21.8 -> 1.21.9` +8. `1.21.9 -> 1.21.10` +9. `1.21.10 -> 1.21.11` +10. `1.21.11 -> 26.1` + +There is no separate `1.21.3` primer upstream. The `1.21.2` primer is the upstream `1.21.1 -> 1.21.2/3` step and is treated that way here. + +## Direct target + +If you are porting directly to `26.1`, this is the state your codebase should end up in: + +- Java 25 toolchain and an IDE release that supports it. +- Mojang names as `Identifier`, not `ResourceLocation`. +- Holder-driven registries, tags, and ingredients. +- Codec-first registration and serialization, especially for loot, recipes, saved data, model definitions, and validation. +- Data-component-driven items instead of old hardcoded item base-class assumptions. +- Client item JSONs for item rendering definitions. +- Newer render infrastructure: material-driven model loading, modern block/item model pipelines, modern GUI pipeline, and the post-`RenderPipeline` rendering backend shape. +- Identifier-based saved-data storage with the `26.1` world/server split. + +## 1. Build, names, imports, and broad mechanical cleanup + +Do this first because it affects nearly every package and symbol: + +- Move the project to Java 25. +- Assume vanilla names are deobfuscated again in `26.1`. +- Replace `ResourceLocation` usages with `Identifier`. +- Reimport utility classes from `net.minecraft.util`. +- Rename `net.minecraft.advancements.critereon` imports to `net.minecraft.advancements.criterion`. +- Reimport moved entity and client-model classes from their new subpackages after the `1.21.11` package shuffle. + +Direct implications: + +- Avoid spending time porting custom wrappers around `ResourceLocation`. Move the code straight to `Identifier`. +- Treat package-level class moves in `1.21.11` as a mass reimport sweep, not as isolated breakages. +- When a pre-`26.1` class or method name only changed because of the rename shuffle, target the `26.1` name directly. + +## 2. Registries, holders, tags, codecs, and validation + +This is the core serialization and registry compilation. + +### Final target + +Your mod should assume: + +- Registries and tags are holder-driven. +- `Ingredient` is holder-set-backed. +- Tag and NBT access lean on codec/generic encoding APIs instead of direct raw handling. +- Validation is `Validatable` plus `ValidationContext`. +- Loot and many provider-style registries register `MapCodec` directly instead of `*Type` wrappers. + +### Direct migration rules + +- Replace raw/tag-key-only patterns with `Holder`, `HolderSet`, `HolderGetter`, and registry lookups. +- For static registries, wrap values as holders when needed. +- For dynamic/datapack registries, use lookup access and `getOrThrow`. +- Build ingredients from `Item`s or resolved holder sets, not the older internal ingredient value model. +- Migrate tag reading/writing and NBT serialization to codec-based flows where possible. +- Expect more optional-returning accessors on tag-like data instead of always getting raw values. +- Convert tag-provider code to the newer appender-style APIs from `1.21.6`. +- Port validation logic to `Validatable#validate` and `ValidationContext`. +- Register loot pool entries, loot functions, loot conditions, NBT providers, number providers, score providers, float providers, and int providers with `MapCodec` as the registry object. + +What to avoid: + +- Do not keep older `Loot*Type`, `FloatProviderType`, or `IntProviderType` wrappers around as your target abstraction. +- Do not keep stringly-typed saved-data ids or ad hoc raw NBT parsing where a codec-backed path now exists. +- Do not treat `TagKey`-only APIs as the final shape if a holder set is now expected. + +This section compiles: + +- `1.21.2`: Holder Set Transition, Ingredient Shift, Recipes in registry format, context-key migration, codecable JSON reload listeners +- `1.21.5`: Tags and Parsing, Saved Data with Types +- `1.21.6`: Tag Providers appender rewrite, Generic Encoding and Decoding +- `1.21.11`: Rename shuffle impact on registry-facing APIs +- `26.1`: Loot Type Unrolling, Validation Overhaul + +## 3. Items, data components, equipment, consumables, and dyes + +This is the direct item-system compilation. + +### Final target + +Your items should be defined around data components and modern item metadata, not old hardcoded item subclasses. + +### Direct migration rules + +- Stop relying on `SwordItem`, `DiggerItem`, and `ArmorItem` as the center of weapon/tool/armor behavior. +- Build item behavior from components such as `WEAPON`, `TOOL`, `ARMOR`, `BLOCKS_ATTACKS`, `ATTRIBUTE_MODIFIERS`, `MAX_DAMAGE`, `REPAIRABLE`, `ENCHANTABLE`, and related item properties. +- Move consumable behavior to `DataComponents.CONSUMABLE`, `USE_REMAINDER`, and `USE_COOLDOWN`. +- Port old food/use logic to `Consumable`, `ConsumableListener`, and `ConsumeEffect`. +- Treat cooldown grouping as component-based instead of item-singleton behavior. +- Port equipment behavior and render metadata through the newer equipment/equippable systems from the `1.21.2` and `1.21.5` waves. +- Use the newer data-component getter APIs introduced later in the chain. +- Apply the `1.21.11` and `26.1` component additions directly on top of this newer model. +- For dyes, use `DataComponents.DYE` and the relevant tags/recipes instead of assuming `DyeItem` is the only meaningful dye input. + +Important end-state notes: + +- `DyeRecipe` is the modern dyeing path, not `ArmorDyeRecipe`. +- Dye-capable items are component-driven, but some use sites still require specific tags. +- `26.1` continues the component migration with data component initializers, dye components, and more component additions. + +This section compiles: + +- `1.21.2`: Armor Materials, Equipment, and Model Textures; Data Components; Equippable; Consumables; Registry Object Id in properties +- `1.21.5`: Weapons, Tools, and Armor; Equipment changes; Data Component Getters +- `1.21.11`: New Data Components +- `26.1`: Data Component Initializers, Item Instances and Stack Templates, Dye Component, Data Component Additions + +## 4. Recipes, loot, trades, and other data-driven gameplay content + +This is the direct data-content target. + +### Final target + +Recipes, loot, and trade content should be treated as codec-backed, registry-oriented, and strongly data-driven. + +### Direct migration rules + +- Port recipe code to the registry-backed recipe model introduced in `1.21.2`. +- Update recipe book integrations around `RecipeDisplay`, `SlotDisplay`, and `PlacementInfo`. +- Expect recipe serializers to be `MapCodec` plus `StreamCodec` pairs. +- Where recipe classes now use common info/book info records or item stack templates, target those final constructor shapes directly. +- Port any custom smithing/crafting/cooking recipes to the new common-info and serializer-record model. +- Move loot registration to direct `MapCodec` registration as described in the registry section. +- If your mod touches villager trades or trade generation, port them to the datapack villager-trade model from `26.1`. +- Treat instruments, trial spawner configs, and similar gameplay data as modern datapack/registry content instead of special hardcoded exceptions. + +What to avoid: + +- Do not keep recipe serializer patterns that assume standalone mutable serializer classes are the final design. +- Do not keep older recipe-book assumptions that predate displays and placement info. + +This section compiles: + +- `1.21.2`: Instruments datapack edition, Trial Spawner Configurations, Recipe Providers, Ingredient Shift, Recipes in registry format +- `26.1`: Loot Type Unrolling, Datapack Villager Trades, Serializer Records and Recipe Info + +## 5. Saved data, world state, clocks, timelines, and level/server storage + +This is the direct world-persistence compilation. + +### Final target + +Saved data should be identifier-based, codec-backed, and stored on the correct server or level data storage depending on scope. + +### Direct migration rules + +- Move any custom saved data to `SavedDataType`. +- Use identifier-based saved-data ids, not old string ids. +- Query saved data through `SavedDataStorage`. +- Re-evaluate whether a given piece of data belongs on the server storage or a level storage. +- Do not assume the overworld remains the universal global storage location. +- If you touch time-based mechanics, port them to world clocks and timelines where applicable. +- Revisit game rules, weather, world-gen settings, trader spawning, boss events, and other former primary-level-data assumptions because `26.1` moves more of that state into dedicated saved-data classes. + +What to avoid: + +- Do not stop at the `1.21.5` saved-data migration. `26.1` changes the storage split again. +- Do not keep APIs that still expect old `WorldData` or `PrimaryLevelData` ownership if `26.1` moved that state elsewhere. + +This section compiles: + +- `1.21.5`: Saved Data, now with Types +- `1.21.11`: Game Rule Shuffle, Environment attribute timelines +- `26.1`: World Clocks and Time Markers, Splitting the Primary Level Data into Saved Data + +## 6. Client item assets, models, block models, and render-facing data + +This is the direct asset-pipeline compilation. + +### Final target + +Your assets should target: + +- Client item JSONs in `assets//items/.json` +- Newer item and block model pipelines +- Material-based texture references and tint sources +- Final `26.1` block/item rendering assumptions + +### Direct migration rules + +- Convert old item override/model-selection logic to Client Items from `1.21.4`. +- Use the appropriate item model types such as basic model, range dispatch, select/conditional models, composite models, and special models. +- Port tint behavior to item tint sources. +- Treat `1.21.5` model rework as the transition point away from the older unified `BakedModel` assumptions. +- Target the `26.1` material-driven block/item model world as the final state. +- Expect materials and baked sprites to replace older raw texture-reference assumptions. +- Expect quad transparency to influence item render types and chunk layers automatically in `26.1`. +- Re-check block model, block state model, fluid model, tint getter, and object-definition transform integrations against the `26.1` system. + +What to avoid: + +- Do not stop at the `1.21.2` shader-file model as if it were final. `1.21.5`, `1.21.11`, and `26.1` all move rendering again. +- Do not stop at the pre-`1.21.4` item override system. Client Items are the correct target. +- Do not keep explicit old item render-type selection code if `26.1` now derives layers/material behavior automatically. + +This section compiles: + +- `1.21.2`: Shader Rewrites, Entity Render States, Model Baking, GUI render types +- `1.21.4`: Client Items, particles through render types +- `1.21.5`: Render Pipeline Rework, Model Rework +- `1.21.6`: Animation baking follow-ups +- `1.21.9`: Feature Submissions, Font Glyph Pipeline, atlas consolidation +- `1.21.11`: Another rendering rewrite, item atlases, block/terrain split +- `26.1`: Even More Rendering Changes + +## 7. GUI, input, debug tooling, feature submission, and developer tooling + +This is the direct client-interaction and tooling compilation. + +### Final target + +GUI and debug tooling should match the modern prepare/render GUI pipeline and the newer event-style input/debug APIs. + +### Direct migration rules + +- Update `GuiGraphics` blits and GUI render-type usage from the early `1.21.2` changes. +- Port GUI rendering to the `1.21.6` prepare/render split through `GuiRenderState` and `GuiRenderer`. +- Re-check dialogs, custom actions, contextual bars, and GUI element ordering under this model. +- Port key and mouse handling to the newer event objects from `1.21.9`. +- Move key mapping categories to `KeyMapping.Category`. +- Update screens, widgets, and listeners to event-object-based input methods and double-click handling. +- If your mod has debugging overlays or renderers, port them to the `1.21.9` debug subscription pipeline. +- If your mod submits custom render features, port them to the `1.21.9` submission flow before reconciling with later rendering changes. +- If you use operator/dev-only visualization, re-check whether it should now be implemented through gizmos from `1.21.11`. +- If you use tests, port them to the `1.21.5` Game Test overhaul before re-enabling them. + +This section compiles: + +- `1.21.2`: GUI render types and minor GUI/client migrations +- `1.21.5`: Game Test Overhaul +- `1.21.6`: GUI Changes, Waypoints +- `1.21.7`: GUI/render follow-ups +- `1.21.9`: Debugging Overhaul, Feature Submissions, Font Glyph Pipeline, JSON-RPC Management Servers, Input Handling Consolidation +- `1.21.11`: Gizmos, Permission Overhaul +- `26.1`: Input message editor support and related client follow-ups + +## 8. Gameplay and API sweep + +After the subsystem migrations above, finish with a targeted API sweep: + +- Re-check block entity removal flow and neighbor updates. +- Re-check voxel-shape helpers and any shape caches. +- Re-check server-player, entity-reference, leash, and permission-adjacent code. +- Re-check game rule and environment attribute usage against the later timeline-based and saved-data-based systems. +- Re-check `Level#isClientSide` and `Level#random` access patterns because they changed visibility in later versions. +- Re-check entity interaction entry points such as `interactAt` removals and similar minor churn in `26.1`. +- Sweep the minor-migration sections from every primer for any APIs your mod directly touches. + +This section compiles the leftover but still important changes from: + +- `1.21.2`, `1.21.4`, `1.21.5`, `1.21.6`, `1.21.7`, `1.21.8`, `1.21.9`, `1.21.10`, `1.21.11`, and `26.1` + +## Straightforward port order + +If you want the shortest route that still respects the compiled subsystem state, do the work in this order: + +1. Move the project to Java 25, `Identifier`, and the `1.21.11` package/import layout. +2. Port registries, holders, ingredients, tags, codecs, and validation. +3. Port items and components, including consumables, equipment, and dye behavior. +4. Port recipes, loot, trades, and other data-driven content. +5. Port saved data, world state, and time/timeline logic. +6. Port client item assets and model/render data. +7. Port GUI, input, debug, and test tooling. +8. Finish with the API sweep against the minor-migration sections. + +## Exhaustive Inlined Primer Merge + +The section below inlines every upstream primer used for this compilation, in order, inside this same document. + +Use the earlier sections in this file for the direct `1.21.1 -> 26.1` end-state guidance. Use the inlined sections below when you need every upstream detail, including minor migrations, short release primers, examples, and rename lists. + +### Step 1: 1.21.1 -> 1.21.2/3 + +## Minecraft 1.21.1 -> 1.21.2 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.1 to 1.21.2. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +### 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](https://misode.github.io/versions/?id=1.21.2&tab=changelog). + +### The Holder Set Transition + +Many of the methods that used `TagKey`s or raw registry objects have been replaced with the direct `HolderSet` object. A `HolderSet` is essentially a list of registry object references that can be dynamically updated and managed as needed by the game. There are effectively two kinds of `HolderSet`s: direct and named. Named `HolderSet`s are the object representation of tags in game. It's called a named set as the `HolderSet` is referenced by the tag's name. Direct `HolderSet`s, on the other hand, are created by `HolderSet#direct`, which functions as an inlined list of values. These are useful when a separate object doesn't need to be defined to construct some value. + +For a JSON example: +```json5 +// HolderSet#direct with one element +{ + "holder_set": "minecraft:apple" +} + +// HolderSet#direct with multiple elements +{ + "holder_set": [ + "minecraft:apple", + "minecraft:stick" + ] +} + +// HolderSet reference (tags) +{ + "holder_set": "#minecraft:planks" +} +``` + +Generally, you should never be constructing holder sets incode except during provider generation. Each set type has a different method of construction. + +First, to even deal with `Holder`s or `HolderSet`s, you will need access to the static registry instance via `Registry` or the datapack registry via `HolderGetter`. The `HolderGetter` is either obtained from a `BootstrapContext#lookup` during datapack registry generation or `HolderLookup$Provider#lookupOrThrow` either as part of generation or `MinecraftServer#registryAccess` during gameplay. + +Once that is available, for direct `HolderSet`s, you will need to get the `Holder` form of a registry object. For static registries, this is done through `Registry#wrapAsHolder`. For datapack registries, this is done through `HolderGetter#getOrThrow`. + +```java +// Direct holder set for Items +HolderSet items = HolderSet.direct(BuiltInRegistries.ITEM.wrapAsHolder(Items.APPLE)); + +// Direct holder set for configured features +// Assume we have access to the HolderGetter> registry +Holderset> features = HolderSet.direct(registry.getOrThrow(OreFeatures.ORE_IRON)); +``` + +For named `HolderSet`s, the process is similar. For both static and dynamic registries, you call `HolderGetter#getOrThrow`. + +```java +// Named holder set for Items +HolderSet items = BuiltInRegistries.ITEM.getOrThrow(ItemTags.PLANKS); + +// Named holder set for biomes +// Assume we have access to the HolderGetter registry +Holderset biomes = registry.getOrThrow(BiomeTags.IS_OCEAN); +``` + +As these changes are permeated throughout the entire codebase, they will be listed in more relevant subsections. + +### Gui Render Types + +Gui rendering methods within `GuiGraphics` now take in a `Function` to determine how to render the image. Also, `blit` methods now require the size of the PNG to be specified. + +```java +// For some GuiGraphics graphics +graphics.blit( + // How to render the texture + RenderType::guiTextured, + // The previous texture parameters + ..., + // The size of the PNG to use + 256, 256); +``` + +This means methods that provided helpers towards setting the texture or other properties that could be specified within a shader have been removed. + +- `com.mojang.blaze3d.pipeline.RenderTarget#blitToScreen(int, int, boolean)` -> `blitAndBlendToScreen` +- `net.minecraft.client.gui.GuiGraphics` + - `drawManaged` is removed + - `setColor` is removed - Now a parameter within the `blit` and `blitSprite` methods + - `blit(int, int, int, int, int, TextureAtlasSprite, *)` is removed + - `bufferSource` -> `drawSpecial`, not one-to-one as this takes in a consumer of the `MultiBufferSource` and ends the current batch instead of just returning the `MultiBufferSource` +- `net.minecraft.client.gui.components.PlayerFaceRenderer` + - All `draw` methods except `draw(GuiGraphics, PlayerSkin, int, int, int)` takes in an additional `int` that defines the color +- `net.minecraft.client.renderer.RenderType` + - `guiTexturedOverlay` - Gets the render type for an image overlayed onto the game screen. + - `guiOpaqueTexturedBackground` - Gets the render type for a GUI texture applied to the background of a menu. + - `guiNauseaOverlay` - Gets the render type for the nausea overlay. + - `guiTextured` - Gets the render type for an image within a GUI menu. +- `net.minecraft.client.resources.metadata.gui.GuiSpriteScaling$NineSlice` now takes in a boolean representing whether the center portion of the texture should be streched to fit the size + +### Shader Rewrites + +The internals of shaders have been rewritten quite a bit. + +#### Shaders Files + +The main changes are the defined samplers and post shaders. + +The `DiffuseSampler` and `DiffuseDepthSampler` have been given new names depending on the target to apply: `InSampler`, `MainSampler`, and `MainDepthSampler`. `InSampler` is used in everything but the `transparency` program shader. + +```json5 +// In some shader JSON +{ + "samplers": [ + { "name": "MainSampler" }, + // ... + ] +} +``` + +Within post effect shaders, they have been changed completely. For a full breakdown of the changes, see `PostChainConfig`, but in general, all targets are now keys to objects, all pass inputs and filters are now lists of sampler inputs. As for how this looks: + +```json5 +// Old post effect shader JSON +// In assets//shaders/post +{ + "targets": [ + "swap" + ], + "passes": [ + { + "name": "invert", + "intarget": "minecraft:main", + "outtarget": "swap", + "use_linear_filter": true, + "uniforms": [ + { + "name": "InverseAmount", + "values": [ 0.8 ] + } + ] + }, + { + "name": "blit", + "intarget": "swap", + "outtarget": "minecraft:main" + } + ] +} + +// New post effect JSON +// In assets//post_effect +{ + "targets": { + "swap": {} // Swap is now a target object (fullscreen unless otherwise specified) + }, + "passes": [ + { + // Name of the program to apply (previously 'name') + // assets/minecraft/shaders/post/invert.json + "program": "minecraft:post/invert", + // Inputs is now a list + "inputs": [ + { + // Targets the InSampler + // Sampler must be available in the program shader JSON + "sampler_name": "In", + // Reading from the main screen (previously 'intarget') + "target": "minecraft:main", + // Use GL_LINEAR (previously 'use_linear_filter') + "bilinear": true + } + ], + // Writes to the swap target (previously 'outtarget') + "output": "swap", + "uniforms": [ + { + "name": "InverseAmount", + "values": [ 0.8 ] + } + ] + }, + { + "program": "minecraft:post/blit", + "inputs": [ + { + "sampler_name": "In", + "target": "swap" + } + ], + "output": "minecraft:main" + } + ] +} +``` + +#### Shader Programs + +All shaders, regardless of where they are used (as part of a program or post effect), have a JSON within `assets//shaders`. This JSON defines everything the shader will use, as defined by `ShaderProgramConfig`. The main addition is the change to `ResourceLocation` relative references, and adding the `defines` header dynamically during load time. + +```json5 +// For some assets/my_mod/shaders/my_shader.json +{ + // Points to assets/my_mod/shaders/my_shader.vsh (previously 'my_shader', without id specification) + "vertex": "my_mod:my_shader", + // Points to assets/my_mod/shaders/my_shader.fsh (previously 'my_shader', without id specification) + "fragment": "my_mod:my_shader", + // Adds '#define' headers to the shaders + "defines": { + // #define + "values": { + "ALPHA_CUTOUT": "0.1" + }, + // #define flag + "flags": [ + "NO_OVERLAY" + ] + }, + // A list of sampler uniforms to use in the shader + // There are 12 texture sampler uniforms Sampler0-Sampler11, though usually only Sampler0 is supplied + // Additionally, there are dynamic '*Sampler' for post effect shaders which are bound to read the specified targets or 'minecraft:main' + "samplers": [ + { "name": "Sampler0" } + ], + // A list of uniforms that can be accessed within the shader + // A list of available uniforms can be found in CompiledShaderProgram#setUniforms + "uniforms": [ + { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, + { "name": "ModelOffset", "type": "float", "count": 3, "values": [ 0.0, 0.0, 0.0 ] }, + { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] } + ] +} +``` + +```glsl +// For some assets/my_mod/shaders/my_shader.vsh (Vertex Shader) + +// GLSL Version +#version 150 + +// Imports Mojang GLSL files +// Located in assets//shaders/include/ +#moj_import + +// Defines are injected (can use 'ALPHA_CUTOUT' and 'NO_OVERLAY') + +// Defined by the VertexFormat passed into the ShaderProgram below +in vec3 Position; // vec3 float +in vec4 Color; // vec4 unsigned byte (0-255) + +// Samplers defined by the JSON +uniform sampler2D Sampler0; + +// Uniforms provided by the JSON +uniform mat4 ModelViewMat; +uniform mat4 ProjMat; +uniform vec3 ModelOffset; + +// Values to output to the fragment shader +out float vertexDistance; +out vec4 vertexColor; +out vec2 texCoord0; + +void main() { + // Out values should be set here +} +``` + +```glsl +// For some assets/my_mod/shaders/my_shader.fsh (Fragment Shader) + +// GLSL Version +#version 150 + +// Imports Mojang GLSL files +// Located in assets//shaders/include/ +#moj_import + +// Defines are injected (can use 'ALPHA_CUTOUT' and 'NO_OVERLAY') + +// Defined by the output of the vertex shader above +in float vertexDistance; +in vec4 vertexColor; +in vec2 texCoord0; + +// Samplers defined by the JSON +uniform sampler2D Sampler0; + +// Uniforms provided by the JSON +uniform vec4 ColorModulator; + +// Values to output to the framebuffer (the color of the pixel) +out vec4 fragColor; + +void main() { + // Out values should be set here +} +``` + +On the code side, shaders are stored internally as either a `ShaderProgram` or a `CompiledShaderProgram`. `ShaderProgram` represents the identifier, while the `CompiledShaderProgram` represents the shader itself to run. Both are linked together through the `ShaderManager`. + +Shader programs are compiled dynamically unless specified as a core shader. This is done by registering the `ShaderProgram` to `CoreShaders#PROGRAMS`. + +```java +// List PROGRAMS access +ShaderProgram MY_SHADER = new ShaderProgram( + // Points to assets/my_mod/shaders/my_shader.json + ResourceLocation.fromNamespaceAndPath('my_mod', 'my_shader'), + // Passed in vertex format used by the shader + DefaultVertexFormat.POSITION_COLOR, + // Lists the '#define' values and flags + // Value: '#define ' + // Flag: '#define ' + ShaderDefines.EMPTY +) +``` + +The shader programs are then set by calling `RenderSystem#setShader` with the `ShaderProgram` in question. In fact, all references to `GameRenderer#get*Shader` should be replaced with a `ShaderProgram` reference. + +```java +// In some rendering method +RenderSystem.setShader(MY_SHADER); + +// Creating a new ShaderStateShard for a RenderType +ShaderStateShard MY_SHARD = new ShaderStateShard(MY_SHADER); +``` + +- `com.mojang.blaze3d.ProjectionType` - An enum which holds the logic for how a projection matrix should be rendered. +- `com.mojang.blaze3d.buffers` + - `BufferType` - An enum that specifies the GL target buffer type. + - `GpuBuffer` - A wrapper around the GL buffer calls for handling the rendering of the screen. + - `GpuFence` - A handle for managing the sync status of the GPU fence. +- `com.mojang.blaze3d.platform.GlStateManager` + - `glShaderSource` now takes in a `String` rather than a `List` + - `_glMapBufferRange` - Delegates to `GL30#glMapBufferRange`. + - `_glFenceSync` - Delegates to `GL32#glFenceSync`. + - `_glClientWaitSync` - Delegates to `GL32#glClientWaitSync`. + - `_glDeleteSync` - Delegates to `GL32#glDeleteSync`. + - `_glBuffserSubData` - Delegates to `GL15#glBufferSubData`. +- `com.mojang.blaze3d.preprocessor.GlslPreprocessor#injectDefines` - Injects any defined sources to the top of a loaded `.*sh` file. +- `com.mojang.blaze3d.shaders` + - `BlendMode`, `Effect`, `EffectProgram`, `Program`, `ProgramManager`, `Shader` has been bundled into `CompiledShader` + - `Unform` no longer takes in a `Shader` + - `glGetAttribLocation` is removed + - `glBindAttribLocation` -> `VertexFormat#bindAttributes` + - `setFromConfig` - Sets the uniform parameters given the values and count of another uniform configuration. +- `com.mojang.blaze3d.systems.RenderSystem` + - `setShader` now takes in the `CompiledShaderProgram`, or `ShaderProgram` + - `clearShader` - Clears the current system shader. + - `runAsFancy` is removed, handled internally by `LevelRenderer#getTransparencyChain` + - `setProjectionMatrix` now takes in a `ProjectionType` than just the `VertexSorting` + - `getVertexSorting` -> `getProjectionType`; not one-to-one, but the `VertexSorting` is accessible on the `ProjectionType` +- `com.mojang.blaze3d.vertex.VertexBuffer` + - `drawWithShader` will now noop when passing in a null `CompiledShaderProgram` + - `$Usage` -> `com.mojang.blaze3d.buffers.BufferUsage` +- `net.minecraft.client.Minecraft#getShaderManager` - Returns the manager that loads all the shaders and post effects. +- `net.minecract.client.renderer` + - `EffectInstance` class is removed, replaced by `CompiledShaderProgram` in most cases + - `GameRenderer` + - `get*Shader` -> `CoreShaders#*` + - `shutdownEffect` -> `clearPostEffect` + - `createReloadListener` -> `ShaderManager` + - `currentEffect` -> `currentPostEffect` + - `ItemBlockRenderTypes#getRenderType` no longer takes in a boolean indicating whether to use the translucent render type + - `ShaderInstance` -> `CompiledShaderProgram` + - `CHUNK_OFFSET` -> `MODEL_OFFSET` + - JSON shaders: `ChunkOffset` -> `ModelOffset` + - `getUniformConfig` - Returns the configuration of a uniform given its name. + - `LevelRenderer#graphicsChanged` is removed, handled internally by `LevelRenderer#getTransparencyChain` + - `PostChainConfig` - A configuration that represents how a post effect shader JSON is constructed. + - `PostPass` now takes in the `ResourceLocation` representing the output target instead of the in and out `RenderTarget`s or the `boolean` filter mode, the `CompiledShaderProgram` to use instead of the `ResourceProvider`, and a list of uniforms for the shader to consume + - No longer `AutoCloseable` + - `addToFrame` no longer takes in the `float` time + - `getEffect` -> `getShader` + - `addAuxAsset` -> `addInput` + - `process` -> `addToFrame` + - `$Input` - Represents an input of the post effect shader. + - `$TargetInput` - An input from a `RenderTarget`. + - `$TextureInput` - An input from a texture. + - `PostChain` constructor is now created via `load` + - No longer `AutoCloseable` + - `MAIN_RENDER_TARGET` is now public + - `getName` is removed, replaced with `ShaderProgram#configId` + - `process` no longer takes in the `DeltaTracker` + - `$TargetBundle` - Handles the getting and replacement of resource handles within the chain. + - `RenderType` + - `entityTranslucentCull`, `entityGlintDirect` is removed + - `armorTranslucent` - A render type which renders armor that can have a translucent texture. + - `ShaderDefines` - The defined values and flags used by the shader as constants. + - `ShaderManager` - The resource listener that loads the shaders. + - `ShaderProgram` - An identifier for a shader. + - `ShaderProgramConfig` - The definition of the program shader JSON. + - `Sheets#translucentCullBlockSheet` is removed + - `SkyRenderer` now implements `AutoCloseable` +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `getFoilBufferDirect` is removed, replaced by `getFoilBuffer` + - `ITEM_COUNT_BLIT_OFFSET` -> `ITEM_DECORATION_BLIT_OFFSET` + +### Entity Render States + +Entity models and renderers have been more or less completely reworked due to the addition of `EntityRenderState`s. `EntityRenderState`s are essentially data object classes that only expose the computed information necessary to render the `Entity`. For example, a `Llama` does not need to know what is has in its inventory, just that it has a chest to render in the layer. + +To start, you need to choose an `EntityRenderState` to use, or create one using a subclass if you need additional information passed to the renderer. The most common states to subclass is either `EntityRenderState` or `LivingEntityRenderState` for living entities. These fields should be mutable, as the state class is created only once for a renderer. + +```java +// Assuming MyEntity extends LivingEntity +public class MyEntityRenderState extends LivingEntityRenderState { + // An example of a field + boolean hasExampleData; +} +``` + +From there, you create the `EntityModel` that will render your `Entity`. The `EntityModel` has a generic that takes in the `EntityRenderState` along with taking in the `ModelPart` root, and optionally the `RenderType` factory as part of its super. The are no methods to implement by default; however, if you need to setup any kind of model movement, you will need to overrride `setupAnim` which modifies the `ModelPart`'s mutable fields using the render state. If your model does not have any animation, then a `Model$Simple` implementation can be used instead. This does not need anything implemented. + +```java +public class MyEntityModel extends EntityModel { + + public MyEntityModel(ModelPart root) { + super(root); + // ... + } + + @Override + public void setupAnim(MyEntityRenderState state) { + // Calls resetPose and whatever other transformations done by superclasses + super.setupAnim(state); + + // Perform transformations to model parts here + } +} +``` + +`EntityModel` also has three `final` methods from the `Model` subclass: `root`, which grabs the root `ModelPart`; `allParts`, which returns a list of all `ModelPart`s flattened; and `resetPose`, which returns the `ModelPart` to their default state. + +`LayerDefinition`s, `MeshDefinition`s, `PartDefinition`s, and `CubeDeformation`s remain unchanged in their implementation and construction for the `ModelLayerLocation` -> `LayerDefinition` map in `LayerDefinitions`. + +What about model transformations? For example, having a baby version of the entity, or where the model switches out altogether? In those cases, a separate layer definition is registered for each. For example, a Llama would have a model layer for the main Llama model, the baby model, the decor for both the adult and baby, and finally one for the spit. Since models are generally similar to one another with only a slight transformation, a new method was added to `LayerDefinition` to take in a `MeshTransformer`. `MeshTransformer`s are basically unary operators on the `MeshDefinition`. For baby models, a `BabyModelTransform` mesh transformer is provided, which can be applied via `LayerDefinition#apply`. + +```java +public class MyEntityModel extends EntityModel { + public static final MeshTransformer BABY_TRANSFORMS = ...; + + public static LayerDefinition create() { + // ... + } +} + +// Wherever the model layers are registered +ModelLayerLocation MY_ENTITY = layers.register("examplemod:my_entity"); +ModelLayerLocation MY_ENTITY_BABY = layers.register("examplemod:my_entity_baby"); + +// Wherever the layer definitions are registered +defns.register(MY_ENTITY, MyEntityModel.create()); +defns.register(MY_ENTITY_BABY, MyEntityModel.create().apply(MyEntityModel.BABY_TRANSFORMS)); +``` + +But how does the model know what render state to use? That's where the `EntityRenderer` comes in. The `EntityRenderer` has two generics: the type of the `Entity`, and the type of the `EntityRenderState`. The `EntityRenderer` takes in a `Context` object, similar to before. Additionally, `getTextureLocation` needs to be implemented, though this time it takes in the render state instead of the entity. The new methods to implement/override are `createRenderState` and `extractRenderState`. `createRenderState` constructs the default render state object. `extractRenderState`, meanwhile, populates the render state for the current entity being rendered. `extractRenderState` will need to be overridden if you are not using an existing render state class. + +Of course, there are also subclasses of the `EntityRenderer`. First, there is `LivingEntityRenderer`. This has an additional generic of the `EntityModel` being rendered, and takes that value in the constructor along with the shadow radius. This renderer also accepts `RenderLayer`s, which largely remain unchanged if you access the previous arguments through the render state. Then, there is the `MobRenderer`, which is what all entities extend. Finally, there is `AgeableMobRenderer`, which takes in two models - the adult and the baby - and decides which to render dependent on `LivingEntityRenderState#isBaby`. `AgeableMobRenderer` should be used with `BabyModelTransform` if the entity has a baby form. Otherwise, you will most likely use `MobRenderer` or `EntityRenderer`. + +```java +public class MyEntityRenderer extends AgeableMobRenderer { + + public MyEntityRenderer(EntityRendererProvider.Context ctx) { + super( + ctx, + new MyEntityModel(ctx.bakeLayer(MY_ENTITY)), // Adult model + new MyEntityModel(ctx.bakeLayer(MY_ENTITY_BABY)), // Baby model + 0.7f // Shadow radius + ); + + // ... + } + + @Override + public ResourceLocation getTextureLocation(MyEntityRenderState state) { + // Return entity texture here + } + + @Override + public MyEntityRenderState createRenderState() { + // Constructs the reusable state + return new MyEntityRenderState(); + } + + @Override + public void extractRenderState(MyEntity entity, MyEntityRenderState state, float partialTick) { + // Sets the living entity and entity render state info + super.extractRenderState(entity, state, partialTick); + // Set our own variables + state.hasExampleData = entity.hasExampleData(); + } +} + +// Wherever the entity renderers are registered +renderers.register(MyEntityTypes.MY_ENTITY, MyEntityRenderer::new); +``` + +- `net.minecraft.client.model` + - `AbstractBoatModel` - A model that assumes there is a `left_paddle` and `right_paddle` that is animated according to the boat's rowing time. + - `AgeableHierarchicalModel`, `ColorableAgeableListModel`, `AgeableListModel` -> `BabyModelTransform` + - `AnimationUtils` + - `animateCrossbowCharge` now takes in a `float` representing the charge duration and `int` representing the use ticks instead of a `LivingEntity` + - `swingWeaponDown` now takes in a `HumanoidArm` instead of a `Mob` + - `BabyModelTransform` - A mesh transformer that applies a baby scaled form of the model. + - `BoatModel` + - `createPartsBuilder` is removed + - `createChildren` -> `addCommonParts`, now private + - `createBodyModel` -> `createBoatModel`, `createChestBoatModel` + - `waterPatch` -> `createWaterPatch` + - `parts` is removed + - `ChestBoatModel` -> `BoatModel#createChestBoatModel` + - `ChestedHorseModel` class is removed and now purely lives in `LlamaModel` and `DonkeyModel` + - `ChestRaftModel` -> `RaftModel#createChestRaftModel` + - `ColorableHierarchicalModel` is now stored in the individual `EntityRenderState` + - `EntityModel` + - The generic now takes in a `EntityRenderState` + - `setupAnim` only takes in the `EntityRenderState` generic + - `prepareMobModel` is removed + - `copyPropertiesTo` is removed, still exists in `HumanoidModel` + - `HierarchicalModel` class is removed + - `HumanoidModel#rotLerpRad` -> `Mth#rotLerpRad` + - `ListModel` class is removed + - `Model` + - `renderToBuffer` is now final + - `root` - Returns the root `ModelPart`. + - `getAnyDescendantWithName` - Returns the first descendant of the root that has the specified name. + - `animate` - Give the current state and definition of the aninmation, transforms the model between the current time and the maximum time to play the animation for. + - `animateWalk` - Animates the walking cycle of the model. + - `applyStatic` - Applies an immediate animation to the specified state. + - `$Simple` - Constructs a simple model that has no additional animation. + - `ModelUtils` class is removed + - `ParrotModel#getState` -> `getPose`, now public + - `PlayerModel` no longer has a generic + - `renderEars` -> `PlayerEarsModel` + - `renderCape` -> `PlayerCapeModel` + - `getRandomModelPart` -> `getRandomBodyPart` + - `getArmPose` - Returns the arm pose of the player given its render state. + - `RaftModel#createBodyModel` -> `createRaftModel` + - `WardenModel#getTendrilsLayerModelParts`, `getHeartLayerModelParts`, `getBioluminescentLayerModelParts`, `getPulsatingSpotsLayerModelParts` now take in the `WardenRenderState` + - `WaterPatchModel` -> `BoatModel#createWaterPatch` and `Model$Simple` +- `net.minecraft.client.model.geom` + - `ModelLayerLocation` is now a record + - `ModelLayers` + - `createRaftModelName`, `createChestRaftModelName` is removed + - `createSignModelName` -> `createStandingSignModelName`, `createWallSignModelName` + - `createBoatModelName`, `createChestBoatModelName` is removed + - `ModelPart` + - `rotateBy` - Rotates the part using the given `Quaternionf`. + - `$Cube#polygons`, `$Polygon`, `$Vertex` is now public + - `PartPose` is now a record + - `translated` - Translates a pose. + - `withScale`, `scaled` - Scales a pose. +- `net.minecraft.client.model.geom.builders` + - `LayerDefinition#apply` - Applies a mesh transformer to the definition and returns a new one. + - `MeshDefinition#transformed` - Applies a transformation to the root pose and returns a new one. + - `MeshTransformer` - Transforms an existing `MeshDefinition` into a given form. + - `PartDefinition` + - `addOrReplaceChild` now has an overload that takes in a `PartDefinition` + - `clearChild` - Removes the child from the part definition. + - `getChildren` - Gets all the children of the current part. + - `transformed` - Applies a transformation to the current pose and returns a new one. +- `net.minecraft.client.renderer.entity` + - `AbstractBoatRenderer` - A boat renderer that contains methods for the boat model and any additions to the boat itself. + - `AgeableMobRenderer` - A mob renderer that takes in the baby and adult model. + - `BoatRenderer` now takes in a `ModelLayerLocation` instead of a `boolean` + - `EntityRenderDispatcher` now takes in a `MapRenderer` + - `render` no longer takes in the entity Y rotation + - `EntityRenderer` now takes in a generic for the `EntityRenderState` + - `getRenderOffset` only takes in the `EntityRenderState` + - `getBoundingBoxForCulling` - Returns the bounding box of the entity to determine whether to cull or not. + - `affectedByCulling` - Returns whether the entity can be culled. + - `render` only takes in the render state, along with the stack, buffer source, and packet light + - `shouldShowName` now takes in a `double` for the camera squared distance from the entity + - `getTextureLocation` is removed, being moved to the classes where it is used, like `LivingEntityRenderer` + - Subsequent implementations of `getTextureLocation` may be protected or private + - `renderNameTag` now takes in the render state instead of the entity and removes the partial tick `float` + - `getNameTag` - Gets the name tag from the entity. + - `getShadowRadius` now takes in the render state instead of the entity + - `createRenderState` - Creates the render state object. + - `extractRenderState` - Reads any data from the entity to the render state. + - `EntityRendererProvider$Context` takes in the `MapRenderer` instead of the `ItemInHandRenderer` + - `LivingRenderer` + - `isShaking` now takes in the render state instead of the entity + - `setupRotations` now takes in the render state instead of the entity + - `getAttackAnim`, `getBob` are now within the render state + - `getFlipDegrees` no longer takes in the entity + - `getWhiteOverlayProgress` now takes in the render state instead of the entity and no longer takes in the entity Y rotation + - `scale` now takes in the render state instead of the entity and no longer takes in the entity Y rotation + - `shouldShowName` now takes in a `double` representing the squared distance to the camera + - `getShadowRadius` now takes in the render state instead of the entity + - `RaftRenderer` - A raft renderer that implements the `AbstractBoatRenderer`. + - `RenderLayerParent#getTextureLocation` is removed +- `net.minecraft.client.renderer.entity.layers` + - `EnergySwirlLayer#isPowered` - Returns whether the energy is powered. + - `CustomHeadLayer` and `#translateToHead` takes in a `CustomHeadLayer$Transforms` instead of a scaling information hardcoding the transform + - `PlayerItemInHandRenderer` takes in an `ItemRenderer` instead of a `ItemInHandRenderer` + - `RenderLayer` takes in an `EntityRenderState` generic instead of an `Entity` generic + - `coloredCutoutModelCopyLayerRender` takes in a single `EntityModel` with the state info bundled into the render state + - `renderColoredCutoutModel` takes in non-generic forms of the rendering information, assuming a `LivingEntityRenderState` + - `getTextureLocation` is removed, instead being passed directly into the appropriate location + - `render` now takes in the render state instead of the entity and parameter information + - `SaddleLayer` has a constructor to take in a baby model. + - `SheepFurLayer` -> `SheepWoolLayer` + - `StuckInBodyLayer` now takes in the model to apply the stuck objects to, the texture of the stuck objects, and the placement style of the objects + - `numStuck` now takes in the render state instead of the entity + - `renderStuckItem` is now private + - `WardenEmissiveLayer` -> `LivingEntityEmissiveLayer`, a more generalized implementation +- `net.minecraft.client.renderer.entity.player.PlayerRenderer` + - `renderRightHand`, `renderLeftHand` now take in a `ResourceLocation` instead of the `AbstractClientPlayer` and a `boolean` whether to render the left and/or right sleeve + - `setupRotations` now takes in the render state instead of the entity and parameter information +- `net.minecraft.world.entity` + - `AnimationState#copyFrom` - Copies the animation state from another state. + - `Entity` + - `noCulling` -> `EntityRenderer#affectedByCulling` + - `getBoundingBoxForCulling` -> `EntityRenderer#getBoundingBoxForCulling` + - `LerpingModel` class is removed + - `PowerableMob` class is removed + +#### Model Baking + +`UnbakedModel`s now have a different method to resolve any dependencies. Instead of getting the dependencies and resolving the parents, this is now done through a single method called `resolveDependencies`. This method takes in the `Resolver`. The `Resolver` is responsible for getting the `UnbakedModel` for the `ResourceLocation`. + +```java +// For some UnbakedModel instance +public class MyUnbakedModel implements UnbakedModel { + + @Nullable + protected ResourceLocation parentLocation; + @Nullable + protected UnbakedModel parent; + private final List overrides; + + // ... + + @Override + public void resolveDependencies(UnbakedModel.Resolver resolver) { + // Get parent model for delegate resolution + if (this.parentLocation != null) { + this.parent = resolver.resolve(this.parentLocation); + } + } +} +``` + +- `net.minecraft.client.renderer.block` + - `BlockModel#getDependencies`, `resolveParents` -> `resolveDependencies` + - `BlockModelDefintion` now takes in a `MultiPart$Definition`, no `List` constructor exists + - `fromStream`, `fromJsonElement` no longer take in a `$Context` + - `getVariants` is removed + - `isMultiPart` is removed + - `instantiate` -> `MultiPart$Definition#instantiate` + - `MultiVariant` is now a record + - `UnbakedBlockStateModel` - An interface that represents a block state model, contains a single method to group states together with the same model. + - `VariantSelector` - A utility for constructing the state definitions from the model descriptor. +- `net.minecraft.client.renderer.block.model` + - `BlockModel` + - `MISSING_MATERIAL` - The material of the missing block texture. + - `bake` no longer takes in the `ModelBaker` and `BlockModel` + - `$LoopException` class is removed +- `net.minecraft.client.renderer.block.model.multipart.MultiPart` now implements `UnbakedBlockStateModel` + - `getSelectors` -> `$Definition#selectors` + - `getMultiVariants` ->` $Definition#getMultiVariants` +- `net.minecraft.client.resources.model` + - `BakedModel#getOverrides` -> `overrides`, method is defaulted to an empty override + - `BlockStateModelLoader` only takes in the missing unbaked model + - `loadAllBlockStates` is removed + - `definitionLocationToBlockMapper` - Gets the state definition from a given resource location + - `loadBlockStateDefinitions` -> `loadBlockStateDefinitionStack` + - `getModelGroups` -> `ModelGroupCollector` + - `$LoadedJson` -> `$LoadedBlockModelDefinition` + - `$LoadedModel` is now public + - `$LoadedModels` - A record which maps a model location to a loaded model. + - `BuiltInModel` no longer takes in the `ItemOverrides` + - `DelegateBakedModel` - A utility implementation that delegates all logic to the supplied `BakedModel` + - `Material#buffer` takes in another `boolean` that handles whether to apply the glint + - `MissingBlockModel` - The missing model for a block. + - `ModelBaker#getModel` is removed, implementation in `ModelBakery$ModelBakerImpl` is private + - `ModelBakery` only takes in the top models, all unbacked models, and the missing model + - `BUILTIN_SLASH` -> `SpecialModels#builtinModelId` + - `BUILTIN_SLASH_GENERATED` -> `SpecialModels#BUILTIN_GENERATED` + - `BUILTIN_BLOCK_ENTITY` -> `SpecialModels#BUILTIN_BLOCK_ENTITY` + - `MISSING_MODEL_LOCATION` -> `MissingBlockModel#LOCATION` + - `MISSING_MODEL_VARIANT` -> `MissingBlockModel#VARIANT` + - `GENERATION_MARKER` -> `SpecialModels#GENERATED_MARKER` + - `BLOCK_ENTITY_MARKER` -> `SpecialModels#BLOCK_ENTITY_MARKER` + - `getModelGroups` -> `ModelGroupCollector` + - `ModelDiscovery` - A loader for block and item models, such as how to resolve them when reading. + - `ModelGroupCollector` - A blockstate collector meant to map states to their associated block models. + - `ModelResourceLocation#vanilla` is removed + - `MultiPartBakedModel` fields are now obtained from the first model in the selector and are private + - `$Builder` class is removed, replaced with `$Selector` + - `SimpleBakedModel`, `SimpleBakedModel$Builder` no longer takes in the `ItemOverrides` + - `SpecialModels` - A utility for builtin models. + - `UnbakedModel` + - `getDependencies`, `resolveParents` -> `resolveDependencies` + - `bake` is no longer nullable + - `$Resolver` - Determines how the unbaked model should be loaded when on top or on override. + - `WeightedBakedModel` now takes in a `SimpleWeightedRandomList` rather than a list of `WeightedEntry`s + +### Equipments and Items, Models and All + +Equipments and Items have had a major overhaul, most of which is spread throughout this documentation. This is some of the core change which, while they are important, do not deserve more than a cursory explanation due to their ease of change. + +#### Item Names and Models + +The item name and model is now set directly within the properties using the `ITEM_NAME` and `ITEM_MODEL` data components, respectively. By default, this will use the same name and model location as previously, but these can be set via `Item$Properties#overrideDescription` and `#overrideModel`. `overrideDescription` takes in the translation key to use. There is also `useBlockDescriptionPrefix` and `useItemDescriptionPrefix` to change it to the default block and item translation keys, respectively. `overrideModel` takes in the relative `ResourceLocation` of the model JSON. For example, a value of `examplemod:example_item` will map to a `ModelResourceLocation` of `examplemod:example_item#inventory`. This is intended to link to the model JSON at `assets/examplemod/models/item/example_item.json`. + +> There is a slight quirk to item models. The same key can also point to `assets/examplemod/models/example_item.json` if the modder decides to for a special model to load at that location under the `inventory` variant. So, it is recommended to avoid having model names with the same name in the root `models` and `models/item` subdirectory. + +#### Enchantable, Repairable Items + +The enchantment value and repair item checks are being replaced with data components: `DataComponents#ENCHANTABLE` and `DataComponents#REPAIRABLE`, respectively. These can be set via the `Item$Properties#enchantable` and `#repairable`. As a result, `Item#getEnchantmentValue` and `isValidRepairItem` are removed. + +#### Elytras -> Gliders + +Any item can act similarly to an elytra if they have the `DataComponents#GLIDER` value equipped. This essentially functions as a flag to indicate that the item can be used to glide. This works only if the item also has a `DataComponents#EQUIPPABLE` entry. + +```java +new Item( + new Item.Properties() + .component(DataComponents.GLIDER, Unit.INSTANCE) // Sets as a glider + .component(DataComponents.EQUIPPABLE, /*...*/) // Determines the slot to check whether it can be used +); +``` + +#### Tools, via Tool Materials + +`Tier`s within items have been replaced with `ToolMaterial`, which better handles the creation of tools and swords without having to implement each method manually. `ToolMaterial` takes in the same arguments as `Tier`, just as parameters to a single constructor rather than as implementable methods. From there, the `ToolMaterial` is passed to the `DiggerItem` subtypes, along with two floats representing the attack damage and attack speed. Interally, `ToolMaterial#apply*Properties` is called, which applies the `ToolMaterial` info to the `DataComponents#TOOL` and the attributes from the given `float`s. + +```java +// Some tool material +public static final ToolMaterial WOOD = new ToolMaterial( + BlockTags.INCORRECT_FOR_WOODEN_TOOL, // Tier#getIncorrectBlocksForDrops + 59, // Tier#getUses + 2.0F, // Tier#getSpeed + 0.0F, // Tier#getAttackDamageBonus + 15, // Tier#getEnchantmentValue + ItemTags.WOODEN_TOOL_MATERIALS // Tier#getRepairIngredient +); + +// When constructing the digger item subtype +new PickaxeItem( + WOOD, // Tool material + 1.0f, // Attack damage + -2.8f, // Attack speed + new Item.Properties() +) +``` + +### Armor Materials, Equipment, and Model (Textures) + +This is, by far, the largest change outside of consumables to items. `ArmorMaterial`s have effectively been made obsolete, as almost all of the logic is handled within data components, and attached to some resource pack JSON to load the associated textures. It is annoyingly complicated to understand at first glance, but is rather intuitive once you are familiar with the process. + +#### `ArmorMaterial` + +`ArmorMaterial` is essentially a record that converts a list of properties to their proper location on the data components, NOT a registry object. This is done by passing in the item properties and an additional setting to either `#humanoidProperties` or `#animalProperties`. These settings should be familiar, as they remained unchanged from the previous version, the only difference is that they now specify a 'model id', which we will go into below. The armor material is used in conjunction with the `ArmorType`: an enum which defines the equipment slot the armor is placed into, the unit durability of each armor type, and the name (which is only used to construcct the attribute modifier id). + +```java +ArmorMaterial exampleArmorMaterial = new ArmorMaterial( + 15, // The scalar durability to multiply the armor type against + // A map of ArmorType -> half armor bars to apply to the entity ARMOR attribute + // Should be set for all ArmorTypes + Util.make(new EnumMap<>(ArmorType.class), map -> { + map.put(ArmorType.BOOTS, 2); + map.put(ArmorType.LEGGINGS, 5); + map.put(ArmorType.CHESTPLATE, 6); + map.put(ArmorType.HELMET, 2); + map.put(ArmorType.BODY, 5); + }, + 25, // The enchantment value of the armor + SoundEvents.ARMOR_EQUIP_IRON, // The holder wrapped sound event on what sound to make when the item is equipped + 0f, // The ARMOR_TOUGHNESS attribute value + 2f, // The KNOCKBACK_RESISTANCE attribute value, + ItemTags.REPAIRS_DIAMOND_ARMOR, // An item tag representing the items that can repair this armor + // The relative location of the EquipmentModel JSON + // Points to assets/examplemod/models/equipment/example_armor_material.json + ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material") +) +``` + +With the `ArmorMaterial`, this is either applied to the item properties by calling `humanoidProperties`, to apply the armor to a specific `ArmorType`; or `animalProperties` to apply the armor to the `BODY` and only allow specific entities to wear them. + +Does this mean that `ArmorItem` and `AnimalArmorItem` are effectively pointless? For `AnimalArmorItem`, this can be argued. The only thing that `AnimalArmorItem` does is have a `$BodyType` parameter, which means that the armor can only be applied to a horse or a wolf, and specifies the item breaking sound. `ArmorItem`, on the other hand, only has one specific usecase: determining whether the item can be taken off or swapped. This implicity checks the currently wearing armor item to see whether it can't be taken off (via `PREVENT_ARMOR_CHANGE` enchantment) and calculating the properties on the replacing armor material so that any hotswaps will only improve their wearer's armor attribute values. + +Let's go one level deeper. + +#### The Data Components + +`ArmorMaterial` specifies eight data components to apply to item: + +- `MAX_DAMAGE` - Set to the maximum durability of the item multiplied by the `ArmorType` unit durability +- `MAX_STACK_SIZE` - Set to 1 +- `DAMAGE` - Set to 0 +- `ATTRIBUTE_MODIFIERS` - Sets `ARMOR` and `ARMOR_TOUGHNESS` attributes, and `KNOCKBACK_RESISTANCE` when greater than 0 +- `ENCHANTABLE` - Set to the enchantment value (not set when calling `animalProperties`) +- `REPAIRABLE` - Set to the `HolderSet` of the tag key representing the repairing ingredients +- `EQUIPPABLE` - Sets the slot, equip sound, model id, what entities can wear the item, and whether it is dispensible + +Everything but `EQUIPPABLE` has already been explained above or has been around from a prior version, so this primer will only focus on `EQUIPPABLE` from now on. + +#### Equippable + +`Equippable`, which used to be an interface, is now a data component that contains how an entity can equip this item and if the equipment should be rendered. Because of this, an item can only be equipped to a single slot. This can be done using the `Equippable` constructor or through the builder via `Equippable#builder`. + +```java +new Item( + new Item.Properties() + .component(DataComponents.EQUIPPABLE, new Equippable( + EquipmentSlot.HEAD, // The slot the item can be equipped to + SoundEvents.ARMOR_EQUIP_IRON, // The sound to play when equipping the item + // The relative location of the EquipmentModel JSON + // Points to assets/examplemod/models/equipment/example_armor_material.json + // When set to an empty optional, the item does not attempt to render as equipment + Optional.of(ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material")), + // The relative location over the texture to overlay on the player screen when wearing + // Points to assets/examplemod/textures/example_overlay.png + // When set to an empty optional, does not render on the player screen + Optional.of(ResourceLocation.withDefaultNamespace("examplemod", "example_overlay")), + // A HolderSet of entities (direct or tag) that can equip this item + // When set to an empty optional, any entity can equip this item + Optional.of(HolderSet.direct(EntityType::builtInRegistryHolder, EntityType.ZOMBIE)), + // Whether the item can be equipped when dispensed from a dispenser + true, + // Whether the item can be swapped off the player during a quick equip + false, + // Whether the item should be damaged when attacked (for equipment typically) + // Must also be a damageable item + false + )) +); +``` + +#### Equipment Models? + +So, as mentioned previously, `Equippable` items, and by extension the `ArmorMaterial` delegate, can specify a model id to determine how the equipment should render. However, what does this id link to? Well, it points to an `EquipmentModel` serialized as a JSON within `models/equipment` of the resource pack. This JSON defines the layers and textures of the equippable item to render. This does NOT specify the model, making the record a misnomer. It is better to think of this as the equipment textures applied to the passed in model. + +`EquipmentModel` functions as a more feature generic version of the previous `ArmorMaterial$Layer`, which has been removed. Each `EquipmentModel` is functionally a map of `$LayerType`s to a list of `$Layer` to render. + +A `$LayerType` is an enum representing the layer to render the equipment model as. While these are non-specific, they are implemented and read by specific entity renderer through the layer renderers. For example, `HUMANOID` is used by the `HumanoidArmorLayer` to render the head, chest, and feet; so any usage of `HUMANOID` will be rendered using that system. Another example is `WOLF_BODY` is used by `WolfArmorLayer` to render the body armor. As such, if using existing layer types (which is the only scenario unless your mod loader supports enum extensions), make sure that they are compatible with the existing renderers in place. + +The `$Layer` list specifies the texture and dyeable options to use when rendering over the passed in model. The first parameter specifes the texture location, relative to `textures/entity/equipment`. The second parameter specifies an optional indicating whether the texture can be tinted (stored via the `ItemTags#DYEABLE` in conjunction with the `DYED_COLOR` data component). When specified, an optional color can be specified for when the item is not dyed. If empty, the armor will be invisible when not dyed. The final parameter indicates whether it should use the texture provided to the renderer instead, such as when rendering a custom elytra texture for the player. + +```json5 +// In assets/examplemod/models/equipment/example_armor_material.json +{ + // The layer map + "layers": { + // The serialized name of the EquipmentModel$LayerType to apply to + "humanoid": [ + // A list of layers to render in the order provided in the list + { + // The relative texture of the layer + // Points to assets/examplemod/textures/entity/equipment/example.png + "texture": "examplemod:example", + // When specified, allows the texture to be tinted the color in DYED_COLOR data component + // Otherwise, cannot be tinted + "dyeable": { + // An RGB value (always opaque color) + // 0x7683DE as decimal + // When not specified, set to 0 (meaning transparent or invisible) + "color_when_undyed": 7767006 + }, + // When true, uses the texture passed into the layer renderer instead + "use_player_texture": true + } + // ... + ] + // ... + } +} +``` + +```java +EquipmentModel.builder() + .addLayers(EquipmentModel.LayerType.HUMANOID, new EquipmentModel.Layer( + // The relative texture of the layer + // Points to assets/examplemod/textures/entity/equipment/example.png + ResourceLocation.fromNamespaceAndPath("examplemod", "example"), + // When specified, allows the texture to be tinted the color in DYED_COLOR data component + // Otherwise, cannot be tinted + Optional.of(new EquipmentModel.Dyeable( + // An RGB value (always opaque color) + // When not specified, set to 0 (meaning transparent or invisible) + Optional.of(0x7683DE) + )), + // When true, uses the texture passed into the layer renderer instead + true + )/*, ... */) + .build(); +``` + +The equipment model is then rendered by calling `EquipmentLayerRenderer#renderLayers` in the render function of an `EntityRenderer` or `RenderLayer`. `EquipementLayerRenderer` is passed in as part of the render context via `EntityRendererProvider$Context#getEquipmentRenderer`. + +```java +// In some render method where EquipmentLayerRenderer equipmentLayerRenderer is a field +this.equipmentLayerRenderer.renderLayers( + // The layer type to render + EquipmentModel.LayerType.HUMANOID, + // The model id representing the EquipmentModel JSON + // This would be set in the `EQUIPPABLE` data component via `model` + ResourceLocation.fromNamespaceAndPath("examplemod", "example_armor_material"), + // The model to apply the textures to + // These are usually separate models from the entity model + // and are separate ModelLayers linking to a LayerDefinition + model, + // The item stack representing the item being rendered as a model + // This is only used to get the dyeable, foil, and armor trim information + stack, + // The stack used to render the model in the correct location + poseStack, + // The source of the buffers to get the vertex consumer of the render type + bufferSource, + // The packed light texture + lighting, + // An absolute path of the texture to render when use_player_texture is true for one of the layer if not null + ResourceLocation.fromNamespaceAndPath("examplemod", "textures/other_texture.png"); +) +``` + +#### Technical Changes to Items + +- `net.minecraft.client.Minecraft#getEquipmentModels` - Gets the `EquipmentModelSet` that contains the current equipment model textures. +- `net.minecraft.client.gui.GuiGraphics#renderTooltip`, `renderComponentTooltip` now has a parameter to take in the relative directory of the background and frame textures of the tooltip, or the default if `null` +- `net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil#renderTooltipBackground` now has a parameter to take in the relative directory of the background and frame textures of the tooltip, or the default if `null` +- `net.minecraft.client.renderer.block.model` + - `ItemOverrides` -> `BakedOverrides` + - The construct no longer takes in the parent `BlockModel` + - `resolve` -> `findOverride`, does not take in the fallback model + - `ItemOverride`, `ItemOverride$Predicate` is now a record + - `getPredicates` is removed, use `predicates` + - `getModel` -> `model` +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher` now takes in the `EquipmentModelSet` + - `EntityRendererProvider$Context` + - `getEquipmentModels` - Gets the current equipment textures. + - `getEquipmentRenderer` - Gets the renderer for the equipment. + - `ItemRenderer` no longer takes in the `Minecraft` instance and `TextureManager` + - `TRIDENT_MODEL`, `SPYGLASS_MODEL` is now public + - `TRIDENT_IN_HAND_MODEL`, `SPYGLASS_IN_HAND_MODEL` is removed + - `getItemModelShaper` is removed + - `renderBundleWithSelectedItem` -> `renderBundleItem`, not one-to-one +- `net.minecraft.client.renderer.entity.layers` + - `CapeLayer` now takes in the `EquipmentModelSet` + - `ElytraLayer` -> `WingsLayer` + - The constructor now takes in the `EquipmentLayerRenderer` + - `EquipmentLayerRenderer` - A renderer for equipment layers on the provided model. + - `HorseArmorLayer` now takes in the `EquipmentLayerRenderer` + - `HumanoidArmorLayer` now teaks in the `EquipmentLayerRenderer` instead of the `ModelManager` + - `shouldRender` - Returns whether the equippable item should be rendered in the given slot. + - `LlamaDecorLayer` now takes in the `EquipmentLayerRenderer` + - `WolfArmorLayer` now takes in the `EquipmentLayerRenderer` +- `net.minecraft.client.renderer.entity.player.PlayerRenderer#getArmPose` is now private, replaced publically with a method that only takes in the `HumanoidArm` and `PlayerRenderState` +- `net.minecraft.client.resources.model` + - `EquipmentModelSet` - A resource listener that loads the `EquipmentModel`s from `models/equipment`. + - `ItemModel` - A model for an item. +- `net.minecraft.core.component.DataComponents` + - `ITEM_MODEL` - Returns the model of the item. The `item/` is stripped, meaning that `minecraft:apple` points to `minecraft/textures/models/item/apple.json`. + - `EQUIPPABLE` - Indicates that an item is equippable in the given slot. Also contains the model to render for the equipment. + - `GLIDER` - Indicates that an item can be used to glide across the air. Must also be used in conjunction with `EQUIPPABLE`. + - `TOOLTIP_STYLE` - Determines the relative location representing how the tooltip should render +- `net.minecraft.core.dispenser.EquipmentDispenseItemBehavior` - Handles how equipment is dispensed from a dispenser. +- `net.minecraft.core.registries.BuiltInRegistries#`, `Registries#ARMOR_MATERIAL` is no longer a registry, handled purely through data components +- `net.minecraft.world.entity` + - `EquipmentSlot#getFilterFlag` -> `getId` + - Also a method `getFilterBit` for converting the ID to a bit mask + - `LivingEntity` + - `canContinueToGlide` -> `canGlide`, no longer takes in the `ItemStack` + - `canTakeItem` replaced by `DataComponents#EQUIPPABLE` + - `canEquipWithDispenser` - Returns whether the stack can be equipped when spat from a dispenser. + - `canDispenserEquipIntoSlot` - An entity override that specifies whether a dispenser can put eequipment into a given slot. + - `isEquippableInSlot` - Returns whether the stack can be equipped in the given slot. + - `canGlideUsing` - Whether the entity can glide with the stack in the provided slot. + - `Mob` + - `canReplaceCurrentItem` now takes in the `EquipmentSlot` + - `isBodyArmorItem` replaced by `DataComponents#EQUIPPABLE` +- `net.minecraft.world.entity.animal.horse` + - `Horse#isBodyArmorItem` replaced by `DataComponents#EQUIPPABLE` + - `Llama#isBodyArmorItem`, `getSwag` replaced by `DataComponents#EQUIPPABLE` +- `net.minecraft.world.item` + - `AnimalArmorItem` no longer extends `ArmorItem` + - The constructor no longer takes in a boolean indicating the overlay texture, as that is now part of the `EquipmentModel` + - The constructor can take in an optional `Holder` of the equip sound + - The constructor can take in a `boolean` representing whether the armor should be damaged if the entity is hurt + - `$BodyType` no takes in the allowed entities to wear the armor rather than the path factory to the texture + - `ArmorItem` is no longer equipable + - Basically functions as an item class where its only remaining usage is to prevent armor change when enchanted and get the associated attributes + - `$Type` -> `ArmorType` + - `ArmorMaterial` -> `.equipment.ArmorMaterial` + - Bascially a dummy record to easily handle applying the associated data components (`MAX_DAMAGE`, `ATTRIBUTE_MODIFIERS`, `ENCHANTABLE`, `EQUIPPABLE`, `REPAIRABLE`) + - `ArmorMaterials` -> `.equipment.ArmorMaterials` + - `BookItem`, `EnchantedBookItem` -> `DataComponents#WRITTEN_BOOK_CONTENT` + - `BundleItem` now takes in a `ResourceLocation` for the model rather than just strings + - `$Mutable#setSelectedItem` -> `toggleSelectedItem` + - `ComplexItem` class is removed + - `ElytraItem` class is removed, now just and item with `DataComponents#GLIDER` + - `Equippable` -> `.equipment.Equippable`, now a record which defines how an item can be equipped + - `FoodOnAStackItem` parameter order has been switched + - `InstrumentItem` parameter order has been switched + - `Item` + - `descriptionId` is now protected + - `getDescription` -> `getName` + - `getOrCreateDescriptionId` is removed + - `getDescriptionId(ItemStack)` -> `DataComponents#ITEM_NAME` + - `isEnchantable`, `getEnchantmentValue` is removed + - `isValidRepairItem` is removed + - `getDefaultAttributeModifiers` is removed + - `getDamageSource` - Returns the damage source this item makes against the `LivingEntity` + - `isComplex` is removed + - `$Properties` + - `equippable` - Sets an equippable component, defining how an item can be equipped + - `equippableUnswappable` - Sets an equippable commponent that cannot be swapped via a key shortcut. + - `overrideDescription` - Sets the translation key of the item. + - `overrideModel` - Sets the model resource location. + - `getCraftingRemainingItem`, `hasCraftingRemainingItem` -> `getCraftingRemainder` + - `ItemNameBlockItem` class is removed, just a normal `Item` `useItemDescriptionPrefix` as a property + - `ItemStack` + - `ITEM_NON_AIR_CODEC` -> `Item#CODEC` + - `isValidRepairItem` - Returns whether the stack can be repaired by this stack. + - `nextDamageWillBreak` - Checks if the next damage taken with break the item. + - `getDescriptionId` -> `getItemName`, not one-to-one, as now it returns the full component + - `ShieldItem` no longer implements `Equippable`, passed in through `DataComponents#EQUIPPABLE` + - `SignItem` parameter order has been switched + - `SmithingTemplateItem` parameter order has been swtiched, removes `FeatureFlag`s + - `StandingAndWallBlockItem` paramter order has been switched + - `AxeItem` now takes in two floats representing the attack damage and attack speed + - `DiggerItem` now takes in two floats representing the attack damage and attack speed + - `createAttributes` -> `ToolMaterial#applyToolProperties` + - `HoeItem` now takes in two floats representing the attack damage and attack speed + - `PickaxeItem` now takes in two floats representing the attack damage and attack speed + - `ShovelItem` now takes in two floats representing the attack damage and attack speed + - `SwordItem` now takes in two floats representing the attack damage and attack speed + - `createAttributes` -> `ToolMaterial#applySwordProperties` + - `Tier` -> `ToolMaterial` + - `TieredItem` class is removed + - `Tiers` constants are stored on `ToolMaterial` +- `net.minecraft.world.item.alchemy.Potion` name is now required + - `getName` -> `name`, not one-to-one as this is stored directly on the potion without any other processing +- `net.minecraft.world.item.armortrim.*` -> `.equipment.trim.*` +- `net.minecraft.world.item.component` + - `Tool` methods that return `Tool$Rule` now only take the `HolderSet` of blocks and not a list or tag key + - `DamageResistant` - A component that holds a tag of damage types the item is resistant to as an entity or being worn +- `net.minecraft.world.item.enchantment` + - `Enchantable` - The data component object for the item's enchantment value. + - `Repairable` - The data component object for the items that can repair this item. +- `net.minecraft.world.level.block` + - `AbstractSkullBlock` no longer implements `Equippable` + - `EquipableCarvedPumpkinBlock` class is removed, as replaced by `DataComponents#EQUIPPABLE` + - `WoolCarpetBlock` no longer implements `Equippable` + +### Interaction Results + +`InteracitonResult`s have been completely modified to encompass everything to one series of sealed implementations. The new implementation of `InteractionResult` combines both `InteractionResultHolder` and `ItemInteractionResult`, meaning that all uses have also been replcaed. + +`InteractionResult` is now an interface with four implementations depending on the result type. First there is `$Pass`, which indicates that the interaction check should be passed to the next object in the call stack. `$Fail`, when used for items and blocks, prevents anything further in the call stack for executing. For entities, this is ignored. Finally, `$TryEmptyHandInteraction` tells the call stack to try to apply the click with no item in the hand, specifically for item-block interactions. + +There is also `$Success`, which indicates that the interaction was successful and can be consumed. A success specifies two pieces of information: the `$SwingSource`, which indicates where the source of the swing originated from (`CLIENT` or `SERVER`) or `NONE` if not specified, and `$ItemContext` that handles whether there was an iteraction with the item in the hand, and what the item was transformed to. + +None of the objects should be directly initialized. The implementations are handled through six constants on the `InteractionResult` interface: + +- `SUCCESS` - A `$Success` object that swings the hand on the client. +- `SUCCESS_SERVER` - A `$Success` object that swings the hand on the server. +- `CONSUME` - A `$Success` object that does not swing the hand. +- `FAIL` - A `$Fail` object. +- `PASS` - A `$Pass` object. +- `TRY_WITH_EMPTY_HAND` - A `$TryEmptyHandInteraction` object. + +```java +// For some method that returns an InteractionResult +return InteractionResult.PASS; +``` + +For success objects, if the item interaction should transform the held stack, then you call `$Success#heldItemTransformedTo`, or `$Success#withoutItem` if no item was used for the interaction. + +```java +// For some method that returns an InteractionResult +return InteractionResult.SUCCESS.heldItemTransformedTo(new ItemStack(Items.APPLE)); + +// Or +return InteractionResult.SUCCESS.withoutItem(); +``` + +- `net.minecraft.core.cauldron.CauldronInteraction` + - `interact` now returns an `InteractionResult` + - `fillBucket`, `emptyBucket` now returns an `InteractionResult` +- `net.minecraft.world` + - `InteractionResultHolder`, `ItemInteractionResult` -> `InteractionResult` +- `net.minecraft.world.item` + - `Equipable#swapWithEquipmentSlot` now returns an `InteractionResult` + - `Item#use`, `ItemStack#use` now returns an `InteractionResult` + - `ItemUtils#startUsingInstantly` now returns an `InteractionResult` + - `JukeboxPlayable#tryInsertIntoJukebox` now returns an `InteractionResult` +- `net.minecraft.world.level.block.state.BlockBehaviour#useItemOn`, `$BlockStateBase#useItemOn` now returns an `InteractionResult` + +### Instruments, the Datapack Edition + +`Instrument`s (not `NoteBlockInstrument`s) are now a datapack registry, meaning they must be defined in JSON or datagenned. + +```json5 +// In data/examplemod/instrument/example_instrument.json +{ + // The registry name of the sound event + "sound_event": "minecraft:entity.arrow.hit", + // How many seconds the instrument is used for + "use_duration": 7.0, + // The block range, where each block is 16 units + "range": 256.0, + // The description of the instrument + "description": { + "translate": "instrument.examplemod.example_instrument" + }, +} +``` + +```java +// For some RegistrySetBuilder builder +builder.add(Registries.INSTRUMENT, bootstrap -> { + bootstrap.register( + ResourceKey.create(Registries.INSTRUMENT, ResourceLocation.fromNamespaceAndPath("examplemod", "example_instrument")), + new Instrument( + BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.ARROW_HIT), + 7f, + 256f, + Component.translatable(Util.makeDescriptionId("instrument", ResourceLocation.fromNamespaceAndPath("examplemod", "example_instrument"))) + ) + ) +}); +``` + +- `net.minecraft.world.item` + - `Instrument` takes in a `float` for the use duration and a `Component` description. + - `InstrumentItem#setRandom` is removed + +### Trial Spawner Configurations, now in Datapack Form + +`TrialSpawnConfig` are now a datapack registry, meaning they must be defined in JSON or datagenned. + +```json5 +// In data/examplemod/trial_spawner/example_config.json +{ + // The range the entities can spawn from the trial spawner block + "spawn_range": 2, + // The total number of mobs that can be spawned + "total_mobs": 10.0, + // The number of mobs that can be spawned at one time + "simultaneous_mobs": 4.0, + // The number of mobs that are added for each player in the trial + "total_mobs_added_per_player": 3.0, + // The number of mobs that can be spawned at one time that are added for each player in the trial + "simultaneous_mobs_added_per_player": 2.0, + // The ticks between each spawn + "ticks_between_spawn": 100, + // A weighted list of entities to select from when spawning + "spawn_potentials": [ + { + // The SpawnData + "data": { + // Entity to spawn + "entity": { + "id": "minecraft:zombie" + } + }, + // Weighted value + "weight": 1 + } + ], + // A weight list of loot tables to select from when the reward is given + "loot_tables_to_eject": [ + { + // The loot key + "data": "minecraft:spawners/ominous/trial_chamber/key", + // Weight value + "weight": 1 + } + ], + // Returns the loot table to use when the the trial spawner is ominous + "items_to_drop_when_ominous": "minecraft:shearing/bogged" +} +``` + +```java +// For some RegistrySetBuilder builder +builder.add(Registries.TRIAL_SPAWNER_CONFIG, bootstrap -> { + var entityTag = new CompoundTag(); + entityTag.putString("id", BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ZOMBIE).toString()); + + bootstrap.register( + ResourceKey.create(Registries.INSTRUMENT, ResourceLocation.fromNamespaceAndPath("examplemod", "example_config")), + TrialSpawnerConfig.builder() + .spawnRange(2) + .totalMobs(10.0) + .simultaneousMobs(4.0) + .totalMobsAddedPerPlayer(3.0) + .simultaneousMobsAddedPerPlayer(2.0) + .ticksBetweenSpawn(100) + .spawnPotentialsDefinition( + SimpleWeightedRandomList.single(new SpawnData(entityTag, Optional.empty(), Optional.empty())) + ) + .lootTablesToEject( + SimpleWeightedRandomList.single(BuiltInLootTables.SPAWNER_OMINOUS_TRIAL_CHAMBER_KEY) + ) + .itemsToDropWhenOminous( + BuiltInLootTables.BOGGED_SHEAR + ) + .build() + ) +}); +``` + +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner` now takes in a `Holder` of the `TrialSpawnerConfig` + - `canSpawnInLevel` now takes in a `ServerLevel` + - `TrialSpawnerConfig` + - `CODEC` -> `DIRECT_CODEC` + - `$Builder`, `builder` - A builder for a trial spawner configuration + +### Recipe Providers, the 'not actually' of Data Providers + +`RecipeProvider` is no longer a `DataProvider`. Instead, a `RecipeProvider` is constructed via a `RecipeProvider$Runner` by implementing `createRecipeProvider`. The name of the provider must also be specified. + +```java +public class MyRecipeProvider extends RecipeProvider { + + // The parameters are stored in protected fields + public MyRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + super(registries, output); + } + + @Override + protected void buildRecipes() { + // Register recipes here + } + + // The runner class, this should be added to the DataGenerator as a DataProvider + public static class Runner extends RecipeProvider.Runner { + + public Runner(PackOutput output, CompletableFuture registries) { + super(output, registries) + } + + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new VanillaRecipeProvider(registries, output); + } + + @Override + public String getName() { + return "My Recipes"; + } + } +} +``` + +- `net.minecraft.data.recipes` + - `RecipeOutput#includeRootAdvancement` - Generates the root advancement for recipes. + - `RecipeProvider` no longer extends `DataProvider` + - The constructor takes in the lookup provider and a `RecipeOutput`, which are protected fields + - `buildRecipes` does not take in any parameters + - All generation methods do not take in a `RecipeOutput` and are instance methods + - `$FamilyRecipeProvider` - Creates a recipe for a `BlockFamily` by passing in the `Block` the resulting block and the base block. + - `$Runner` - A `DataProvider` that constructs the `RecipeProvider` via `createRecipeProvider` + - `ShapedRecipeBuilder`, `ShapelessRecipeBuilder` now have private constructors and take in a holder getter for the items + +### The Ingredient Shift + +`Ingredient`s have be reimplemented to use a `HolderSet` as its base rather that it own internal `Ingredient$Value`. This most changes the call to `Ingredient#of` as you either need to supply it with `Item` objects or the `HolderSet` representing the tag. For more information on how to do this, see the [holder set section](#the-holder-set-transition). + +- `net.minecraft.world.item.crafting.Ingredient` + - `EMPTY` -> `Ingredient#of`, though the default usecases do not allow empty ingredients + - `CODEC` is removed + - `CODEC_NONEMPTY` -> `CODEC` + - `testOptionalIngredient` - Tests whether the stack is within the ingredient if present, or default to an empty check if not. + - `getItems` -> `items` + - `getStackingIds` is removed + - `of(ItemStack...)`, `of(Stream)` is removed + - `of(TagKey)` -> `of(HolderSet)`, need to resolve tag key + +### BlockEntityTypes Privatized! + +`BlockEntityType`s have been completely privatized and the builder being removed! This means that if a mod loader or mod does not provide some access widening to the constructor, you will not be able to create new block entities. The only other change is that the `Type` for data fixers was removed, meaning that all that needs to be supplied is the client constructor and the set of valid blocks the block entity can be on. + +```java +// If the BlockEntityType constructor is made public +// MyBlockEntity(BlockPos, BlockState) constructor +BlockEntityType type = new BlockEntityType(MyBlockEntity::new, MyBlocks.EXAMPLE_BLOCK); +``` + +### Consumables + +Consuming an item has been further expanded upon, with most being transitioned into separate data component entries. + +#### The `Consumable` Data Component + +The `Consumable` data component defines how an item is used when an item is finished being used. This effectively functions as `FoodProperties` used to previously, except all consumable logic is consolidated in this one component. A consumable has five properties: the number of seconds it takes to consume or use the item, the animation to play while consuming, the sound to play while consuming, whether particles should appear during consumption, and the [effects to apply once the consumption is complete](#consumeeffect). + +A `Consumable` can be applied using the `food` item property. If only the `Consumable` should be added, then `component` should be called. A list of vanilla consumables and builders can be found in `Consumables`. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().component(DataComponents.CONSUMABLE, + Consumable.builder() + .consumeSeconds(1.6f) // Will use the item in 1.6 seconds, or 32 ticks + .animation(ItemUseAnimation.EAT) // The animation to play while using + .sound(SoundEvents.GENERIC_EAT) // The sound to play while using the consumable + .soundAfterConsume(SoundEvents.GENERIC_DRINK) // The sound to play after consumption (delegates to 'onConsume') + .hasConsumeParticles(true) // Sets whether to display particles + .onConsume( + // When finished consuming, applies the effects with a 30% chance + new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.3F) + ) + // Can have multiple + .onConsume( + // Teleports the entity randomly in a 50 block radius + new TeleportRandomlyConsumeEffect(100f) + ) + .build() +)); +``` + +##### `OnOverrideSound` + +Sometimes, an entity may want to play a different sound when consuming an item. In that case, the entity can implement `Consumable$OverrideConsumeSound` and return the sound event that should be played. + +```java +// On your own entity +public class MyEntity extends Mob implements Consumable.OverrideCustomSound { + // ... + + @Override + public SoundEvent getConsumeSound(ItemStack stack) { + // Return the sound event to play + } +} +``` + +#### `ConsumableListener` + +`ConsumableListener`s are data components that indicate an action to apply once the stack has been 'consumed'. This means whenever `Consumable#consumeTicks` has passed since the player started using the consumable. An example of this would be `FoodProperties`. `ConsumableListener` only has one method `#onConsume` that takes in the level, entity, stack doing the consumption, and the `Consumable` that has finished being consumed. + +```java +// On your own data component +public record MyDataComponent() implements ConsumableListener { + + // ... + + @Override + public void onConsume(Level level, LivingEntity entity, ItemStack stack, Consumable consumable) { + // Perform stuff once the item has been consumed. + } +} +``` + +#### `ConsumeEffect` + +There is now a data component that handles what happens when an item is consumed by an entity, aptly called a `ConsumeEffect`. The current effects range from adding/removing mob effects, teleporting the player randomly, or simply playing a sound. These are applied by passing in the effect to the `Consumable` or `onConsume` in the builder. + +```java +// When constructing a consumable +Consumable exampleConsumable = Consumable.builder() + .onConsume( + // When finished consuming, applies the effects with a 30% chance + new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.3F) + ) + // Can have multiple + .onConsume( + // Teleports the entity randomly in a 50 block radius + // NOTE: CURRENTLY BUGGED, only allows for 8 block raidus + new TeleportRandomlyConsumeEffect(100f) + ) + .build(); +``` + +#### On Use Conversion + +Converting an item into another stack on consumption is now handled through `DataComponents#USE_REMAINDER`. The remainder will only be converted if the stack is empty after this use. Otherwise, it will return the current stack, just with one item used. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().usingConvertsTo( + Items.APPLE // Coverts this into an apple on consumption +)); +Item exampleItem2 = new Item(new Item.Properties().component(DataComponents.USE_REMAINDER, + new UseCooldown( + new ItemStack(Items.APPLE, 3) // Converts into three apples on consumption + ) +)); +``` + +#### Cooldowns + +Item cooldowns are now handled through `DataComponents#USE_COOLDOWN`; however, they have been expanded to apply cooldowns to stacks based on their defined group. A cooldown group either refers to the `Item` registry name if not specified, or a custom resource location. When applying the cooldown, it will store the cooldown instance on anything that matches the defined group. This means that, if a stack has some defined cooldown group, it will not be affected when a normal item is used. + +```java +// For some item +Item exampleItem = new Item(new Item.Properties().useCooldown( + 60 // Wait 60 seconds + // Will apply cooldown to items in the 'my_mod:example_item' group (assuming that's the registry name) +)); +Item exampleItem2 = new Item(new Item.Properties().component(DataComponents.USE_COOLDOWN, + new UseCooldown( + 60, // Wait 60 seconds + // Will apply cooldown to items in the 'my_mod:custom_group' group + Optional.of(ResourceLocation.fromNamespaceAndPath("my_mod", "custom_group")) + ) +)); +``` + +- `net.minecraft.core.component.DataComponents#FOOD` -> `CONSUMABLE` +- `net.minecraft.world.entity.LivingEntity` + - `getDrinkingSound`, `getEatingSound` is removed, handled via `ConsumeEffect` + - `triggerItemUseEffects` is removed + - `eat` is removed +- `net.minecraft.world.entity.npc.WanderingTrader` now implements `Consumable$OverrideConsumeSound` +- `net.minecraft.world.food` + - `net.minecraft.world.food.FoodData` + - `tick` now takes in a `ServerPlayer` + - `getLastFoodLevel`, `getExhaustionLevel`, `setExhaustion` is removed + - `FoodProperties` is now a `ConsumableListener` + - `eatDurationTicks`, `eatSeconds` -> `Consumable#consumeSeconds` + - `usingConvertsTo` -> `DataComponents#USE_REMAINDER`, + - `effects` -> `ConsumeEffect` +- `net.minecraft.world.item` + - `ChorusFruitItem` class is removed + - `HoneyBottleItem` class is removed + - `Item` + - `getDrinkingSound`, `#getEatingSound` is removed, handled via `ConsumeEffect` + - `releaseUsing` now returns a `boolean` whether it was successfully released + - `$Properties#food` can now take in a `Consumable` for custom logic + - `$Properties#usingConvertsTo` - The item to convert to after use. + - `$Properties#useCooldown` - The amount of seconds to wait before the item can be used again. + - `ItemCooldowns` now take in `ItemStack`s or `ResourceLocation`s to their methods rather than just an `Item` + - `getCooldownGroup` - Returns the key representing the group the cooldown is applied to + - `ItemStack#getDrinkingSound`, `getEatingSound` is removed + - `MilkBucketItem` class is removed + - `OminousBottleItem` class is removed + - `SuspiciousStewItem` class is removed +- `net.minecraft.world.item.alchemy.PotionContents` now implements `ConsumableListener` + - The constructor takes in an optional string representing the translation key suffix of the custom name + - `applyToLivingEntity` - Applies all effects to the provided entity. + - `getName` - Gets the name component by appending the custom name to the end of the provided contents string. +- `net.minecraft.world.item.component` + - `Consumable` - A data component that defines when an item can be consumed. + - `ConsumableListener` - An interface applied to data components that can be consumed, executes once consumption is finished. + - `SuspiciousStewEffects` now implements `ConsumableListener` + - `UseCooldown` - A data component that defines how the cooldown for a stack should be applied. + - `UseRemainder` - A data component that defines how the item should be replaced once used up. + - `DeathProtection` - A data component that contains a list of `ConsumeEffect`s on what to do when using the item to survive death. +- `net.minecraft.world.item.consume_effects.ConsumeEffect` - An effect to apply after the item has finished being consumed. + +### Registry Objcet Id, in the Properties? + +When providing the `BlockBehaviour$Properties` to the `Block` or the `Item$Properties` to the `Item`, it must set the `ResourceKey` in the block directly by calling `#setId`. An error will be thrown if this is not set before passing in. + +```java +new Block(BlockBehaviour.Properties.of() + .setId(ResourceKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("examplemod", "example_block")))); + +new BlockItem(exampleBlock, new Item.Properties() + .useBlockDescriptionPrefix() // Makes the description id for a block item + .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")))); + +new Item(new Item.Properties() + .setId(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")))); +``` + +- `net.minecraft.world.item.Item$Properties` + - `setId` - Sets the resource key of the item to get the default description and model from. This property must be set. + - `useBlockDescriptionPrefix` - Creates the description id using the `block.` prefix. + - `useItemDescriptionPrefix` - Creates the description id using the `item.` prefix. +- `net.minecraft.world.level.block.state.BlockBehaviour$Properties#setId` - Sets the resource key of the block to get the default drops and description from. This property must be set. + +### Properties Changes + +`DirectionProperty` has been removed, and must now be called and referenced via `EnumProperty#create` with a `Direction` generic. Additionally, all property classes have been made final and must be constructed through one of the exposed `create` methods. + +- `net.minecraft.world.level.block.state.properties` + - `BooleanProperty` is now final + - `DirectionProperty` class is removed + - `EnumProperty` is now final + - `create` now takes in a `List` instead of a `Collection` + - `IntegerProperty` is now final + - `Property#getPossibleValues` now returns a `List` instead of a `Collection` + +### Recipes, now in Registry format + +Recipes have been upgraded to a data pack registry, similar to how loot tables are handled. They are still queried in the same fashion, it just simply using a pseudo-registry-backed instance. Some of the more common changes is that `RecipeHolder` may be replaced by `RecipeDisplayId`, `RecipeDisplay`, or `RecipeDisplayEntry` if the holder itself is not needed. With this, there are a few changes to how recipe books are handled. + +#### Recipe Books + +`RecipeBookComponent`s have been modified somewhat to hold a generic instance of the menu to render. As such, the component no longer implements `PlacedRecipe` and instead takes in a generic representing the `RecipeBookMenu`. The menu is passed into the component via its constructor instead of through the `init` method. This also menas that `RecipeBookMenu` does not have any associated generics. To create a component, the class needs to be extended. + +```java +// Assume some MyRecipeMenu extends AbstractContainerMenu +public class MyRecipeBookComponent extends RecipeBookComponent { + + public MyRecipeBookComponent(MyRecipeMenu menu, List tabInfos) { + super(menu, tabInfos); + // ... + } + + @Override + protected void initFilterButtonTextures() { + // ... + } + + @Override + protected boolean isCraftingSlot(Slot slot) { + // ... + } + + @Override + protected void selectMatchingRecipes(RecipeCollection collection, StackedItemContents contents) { + // ... + } + + @Override + protected Component getRecipeFilterName() { + // ... + } + + @Override + protected void fillGhostRecipe(GhostSlots slots, RecipeDisplay display, ContextMap ctx) { + + } +} + +public class MyContainerScreen extends AbstractContainerScreen implements RecipeUpdateListener { + + public MyContainerScreen(MyRecipeMenu menu, List tabInfos, ...) { + super(menu, ...); + this.recipeBookComponent = new MyRecipeBookComponent(menu, tabInfos); + } + + + // See AbstractFurnaceScreen for a full implementation +} +``` + +#### Recipe Displays + +However, how does a recipe understand what should be displayed in a recipe book? This falls under two new static registries: the `RecipeDisplay` and the `SlotDisplay`. + +The `SlotDisplay` represents what displays in a single slot within a recipe. The display only has one method (ignoring types): `resolve`. `resolve` takes in the `ContextMap` holding the data and the `DisplayContentsFactory` which accepts the stacks and remainders that will be displayed in this slot. `SlotDisplay` also has a lot of helper implementations, such as `$Composite` that takes in a list of displays or `$ItemStackSlotDisplay` that takes in the stack to display. The display is registered by its `$Type`, which takes in the map codec and stream codec. + +The slot also has methods to get for the associated stacks that can be displayed via `resolveForStacks` and `resolveForFirstStack`. + +```java +public static record MySlotDisplay() implements SlotDisplay { + + @Override + public Stream resolve(ContextMap ctx, DisplayContentsFactory output) { + // Call output.forStack(...) or addRemainder(..., ...) using instanceof to display items + if (output instanceof ForStacks stacks) { + stacks.forStack(...); + } else if (output instanceof ForRemainders remainders) { + remainders.addRemainder(..., ...); + } + } + + @Override + public SlotDisplay.Type type() { + // Return the registered object here registered to Registries#SLOT_DISPLAY + } +} +``` + +`RecipeDisplay` represents how a recipe is displayed. As an implementation detail, the `RecipeDisplay` only needs to be aware of the result (via `result` slot display) and the place the recipe is being used (via `craftingStation` slot display) as those are the only two details the recipe book cares about. However, it is recommended to also have slot displays for the ingredients and then have those consumed by your `RecipeBookComponent`. The display is registered by its `$Type`, which takes in the map codec and stream codec. + + +```java +public record MyRecipeDisplay(SlotDisplay result, SlotDisplay craftingStation, ...) implements RecipeDisplay { + + @Override + public RecipeDisplay.Type type() { + // Return the registered object here registered to Registries#RECIPE_DISPLAY + } +} +``` + +#### Recipe Placements + +Recipe ingredients and placements within the recipe book are now handled through `Recipe#placementInfo`. A `PlacementInfo` is basically a definition of items the recipe contains and where they should be placed within the menu if supported. If the recipe cannot be placed, such as if it is not an `Item` or uses stack information, then it should return `PlacementInfo#NOT_PLACEABLE`. + +A `PlacementInfo` can be created either from an `Ingredient`, a `List`, or a `List>` using `create` or `createFromOptionals`, respectively. + +```java +public class MyRecipe implements Recipe { + + private PlacementInfo info; + + public MyRecipe(Ingredient input) { + // ... + } + + // ... + + @Override + public PlacementInfo placementInfo() { + // This delegate is done as the HolderSet backing the ingredient may not be fully populated in the constructor + if (this.info == null) { + this.info = PlacementInfo.create(input); + } + + return this.info; + } +} +``` + +If an `Optional` is used, they can be tested via `Ingredient#testOptionalIngredient`. + +- `net.minecraft.world.item.crafting` + - `Ingredient#display` - Returns the `SlotDisplay` that shows this ingredient. + - `PlacementInfo` - Defines all ingredients necessary to construct the result of a recipe. + - `Recipe` + - `getToastSymbol` -> `getCategoryIconItem` + - `getIngredients`, `isIncomplete` -> `placementInfo` + - `getIngredients` -> `PlacementInfo#stackedRecipeContents`, + - `isIncomplete` -> `PlacementInfo#isImpossibleToPlace` + - `RecipeManager#getSynchronizedRecipes` - Returns all recipes that can be placed and sends them to the client. No other recipes are synced. + - `ShapedRecipePattern` now takes in a `List>` instead of a `NonNullList` + - `ShapelessRecipe` now takes in a `List` instead of a `NonNullList` + - `SmithingTransformRecipe`, `SmithingTrimRecipe` now takes in `Optional`s instead of `Ingredient`s + - `SuspiciousStewRecipe` class is removed + +#### Recipe Changes + +There have been a few changes within the recipe class itself, which mirror all of the above changes. First, `canCraftInDimensions` is removed and now hardcoded into the match function. `getResultItem` and `getCategoryIconItem` has been replaced by `RecipeDisplay` via `display`. `getRemainingItems` has moved to `CraftingRecipe`. Finally, all recipes now return their `RecipeBookCategory` via `recipeBookCategory`. + +```java +public class MyRecipe implements Recipe { + + @Override + public String group() { + // Return here what `getGroup` was + } + + @Override + public List display() { + return List.of( + // Some recipe display instance + // RecipeDisplay#result should return `getResultItem` + // RecipeDisplay#craftingStation should return `getCategoryIconItem` + ) + } + + @Override + public RecipeBookCategory recipeBookCategory() { + // Functions similar to the book category passed into the recipe builders during data generation + return RecipeBookCategories.CRAFTING_MISC; + } +} +``` + +#### Creating Recipe Book Categories + +Recipe book categories are unified by `ExtendedRecipeBookCategory` and split into two sections: `RecipeBookCategory` for actual categories, and `SearchRecipeBookCategory` for aggregate categories. While `SearchRecipeBookCategory`s are enums, `RecipeBookCategory` is like any other static registry object. This is done by creating a new `RecipeBookCategory`. + +```java +// Using the standard vanilla registry method +public static final RecipeBookCategory EXAMPLE_CATEGORY = Registry.register( + BuiltInRegistries.RECIPE_BOOK_CATEGORY, + // The registry object name + ResourceLocation.fromNamespaceAndPath("examplemod", "example_category"), + // This creates a new recipe book category. It functions as a marker object. + new RecipeBookCategory() +); +``` + +#### Technical Changes + +- `net.minecraft.advancements.AdvancementRewards` now takes in a list of `ResourceKey`s instead of `ResourceLocation`s for the recipe + - `$Builder#recipe`, `addRecipe` now takes in a `ResourceKey` +- `net.minecraft.advancements.critereon` + - `PlayerPredicate` now takes in a `ResourceKey` for the recipe map + - `$Builder#addRecipe` now takes in a `ResourceKey` + - `RecipeCraftedTrigger` + - `trigger` now takes in a `ResourceKey` + - `$TriggerInstance` now takes in a `ResourceKey` + - `$TriggerInstance#craftedItem`, `crafterCraftedItem` now takes in a `ResourceKey` + - `RecipeUnlockedTrigger` + - `unlocked` now takes in a `ResourceKey` + - `$TriggerInstance` now takes in a `ResourceKey` +- `net.minecraft.client` + - `ClientRecipeBook` + - `setupCollections` -> `rebuildCollections`, not one-to-one + - `getCollection(RecipeBookCategories)` -> `getCollection(ExtendedRecipeBookCategory)` + - `add`, `remove` - Handles adding/removing a recipe entry to display within the recipe book. + - `addHighLight`, `removeHighlight`, `hasHighlight` - Handles if the entry is highlighted when filtered or selected by the player. + - `clear` - Clears the known and highlighted recipes. + - `RecipeBookCategories#*_MISC` -> `SearchRecipeBookCategory#*` + - This can also be replaced within methods by `RecipeBookComponent$TabInfo`, `ExtendedRecipeBookCategory`, or `RecipeBookCategory` +- `net.minecraft.client.gui.components.toasts` + - `RecipeToast(RecipeHolder)` -> `RecipeToast()`, now private + - `addOrUpdate` now takes in a `RecipeDisplay` instead of a `RecipeHolder` +- `net.minecraft.client.gui.screens.inventory.AbstractFurnaceScreen` + - `recipeBookComponent` is now private + - `AbstractFurnaceScreen(T, AbstractFurnaceRecipeBookComponent, Inventory, Component, ResourceLocation, ResourceLocation, ResourceLocation)` - `AbstractFurnaceRecipeBookComponent` has been replaced with a `Component` as the recipe book is not constructed internally and now takes in a list of `RecipeBookComponent$TabInfo` +- `net.minecraft.client.gui.screens.recipebook` + - `AbstractFurnaceReipceBookComponent`, `BlastingFurnaceReipceBookComponent`, `SmeltingFurnaceReipceBookComponent`, `SmokingFurnaceReipceBookComponent` -> `FurnaceReipceBookComponent` + - `GhostRecipe` -> `GhostSlots` not one-to-one, as the recipe itself is stored as a private field in `RecipeBookComponent` as a `RecipeHolder` + - `addResult` -> `setResult`, not one-to-one + - `addIngredient` -> `setIngredient`, not one-to-one + - `setSlot`, `setInput`, `setResult` now take in a `ContextMap` + - `OverlayRecipeComponent()` -> `OverlayRecipeComponent(SlotSelectTime, boolean)` + - `init` takes in a `ContextMap` containing registry data to display within the components and a `boolean` representing whether the recipe book is filtering instead of computing it from the `Minecraft` instance + - `getLastRecipeClicked` now returns a `RecipeDisplayId` + - `$OverlayRecipeButton` is now an abstract package-private class, taking in the `ContextMap` + - `$Pos` is now a record + - `RecipeBookComponent` no longer implements `RecipeShownListener` + - The constructor takes in a list of `$TabInfo`s containing the tabs shown in the book + - `init` no longer takes in a `RecipeBookMenu` + - `initVisuals` is now private + - `initFilterButtonTextures` is now abstract + - `updateCollections` now takes in another boolean representing if the book is filtering + - `renderTooltip` now takes in a nullable `Slot` instead of an `int` representing the slot index + - `renderGhostRecipe` no longer takes in a float representing the delay time + - `setupGhostRecipe` -> `fillGhostRecipe`, no longer takes in the `List` to place, that is stored within the component itself + - `selectMatchingRecipes` no longer takes in the `RecipeBook` + - `recipesShown` now takes in a `RecipeDisplayId` + - `setupGhostRecipeSlots` -> `fillGhostRecipe`, taking in the `ContextMap` + - `$TabInfo` - A record that denotes the icons and categories of recipe to display within a recipe book page. + - `RecipeBookPage()` -> `RecipeBookPage(RecipeBookComponent, SlotSelectTime, boolean)` + - `updateCollections` now takes in a boolean representing if the book is filtering + - `getMinecraft` is removed + - `addListener` is removed + - `getLastRecipeClicked` now returns a `RecipeDisplayId` + - `recipesShown` now takes in a `RecipeDisplayId` + - `getRecipeBook` now returns a `ClientRecipeBook` + - `RecipeBookTabButton` now takes in a `RecipeBookComponent$TabInfo` + - `startAnimation(Minecraft)` -> `startAnimation(ClientRecipeBook, boolean)` + - `getCategory` now returns a `ExtendedRecipeBookCategory` + - `RecipeButton()` -> `RecipeButton(SlotSelectTime)` + - `init` now takes in a `boolean` representing if the book is filtering and a `ContextMap` holding the registry data + - `getRecipe` -> `getCurrentRecipe`, not one-to-one + - `getDisplayStack` - Returns the result stack of the recipe. + - `getTooltipText` now takes in the `ItemStack` + - `RecipeCollection(RegistryAccess, List)` -> `RecipeCollection(List)` + - `canCraft` -> `selectRecipes` + - `getRecipes`, `getDisplayRecipes` -> `getSelectedRecipes` + - `registryAccess`, `hasKnownRecipes`, `updateKnownRecipes` is removed + - `isCraftable` now takes in a `RecipeDisplayId` + - `hasFitting` -> `hasAnySelected` + - `getRecipes` now returns a list of `RecipeDisplayEntry`s + - `RecipeShownListener` class is removed + - `RecipeUpdateListener` + - `getRecipeBookComponent` is removed + - `fillGhostRecipe` -> Fills the ghost recipe given the `RecipeDisplay` + - `SearchRecipeBookCategory` - An enum which holds the recipe book categories for aggregate types. + - `SlotSelectTime` - Represents the current index of the slot selected by the player. +- `net.minecraft.client.multiplayer` + - `ClientPacketListener#getRecipeManager` -> `recipes`, returns `RecipeAccess` + - `ClientRecipeContainer` - A client side implementation of the `RecipeAccess` when synced from the server. + - `MultiPlayerGameMode#handlePlaceRecipe` now takes in a `RecipeDisplayId` + - `SessionSearchTrees#updateRecipes` now takes in a `Level` instead of the `RegistryAccess$Frozen` +- `net.minecraft.client.player.LocalPlayer#removeRecipeHightlight` now takes in a `RecipeDisplayId` +- `net.minecraft.commands.SharedSuggestionProvider#getRecipeNames` is removed as it can be queried from the registry access +- `net.minecraft.commands.arguments.ResourceLocationArgument` + - `getRecipe` -> `ResourceKeyArgument#getRecipe` + - `getAdvancement` -> `ResourceKeyArgument#getAdvancement` +- `net.minecraft.commands.synchronization.SuggestionProviders#ALL_RECIPES` is removed +- `net.minecraft.core.component.DataComponents#RECIPES` now takes in a list of `ResourceKey`s +- `net.minecraft.data.recipes` + - `RecipeBuilder#save` now takes in a `ResourceKey` instead of a `ResourceLocation` + - `RecipeOutput#accept` now takes in a `ResourceKey` instead of a `ResourceLocation` + - `RecipeProvider#trimSmithing` now takes in a `ResourceKey` instead of a `ResourceLocation` +- `net.minecraft.network.protocol.game` + - `ClientboundPlaceGhostRecipePacket` - A packet that contains the container id and the `RecipeDisplay` + - `ClientboundRecipeBookAddPacket` - A packet that adds entries to the recipe book + - `ClientboundRecipeBookRemovePacket` - A packet that removes entries to the recipe book + - `ClientboundRecipeBookSettingsPacket` - A packet that specifies the settings of the recipe book + - `ClientboundRecipePacket` class is removed + - `ClientboundUpdateRecipesPacket` is now a record, taking in the property sets of the recipes and the stonecutter recipes + - `getRecipes` is removed + - `ServerboundPlaceRecipePacket` is now a record + - `ServerboundRecipeBookSeenRecipePacket` is now a record +- `net.minecraft.recipebook` + - `PlaceRecipe` -> `PlaceRecipeHelper` + - `addItemToSlot` -> `$Output#addItemToSlot` + - `placeRecipe` now takes in a `Recipe` instead of the `RecipeHolder` + - There is an overload that takes in two more ints that represent the pattern height and width for a `ShapedRecipe`, or just the first two integers repeated + - `RecipeBook` + - `add`, `contains`, `remove` -> `ServerRecipeBook#add`, `contains`, `remove` + - `addHighlight`, `removeHighlight`, `willHighlight` -> `ServerRecipeBook#addHighlight`, `removeHighlight`, `ClientRecipeBook#hasHighlight` + - `bookSettings` is now protected + - `RecipeBookSettings#read`, `write` is now private + - `ServerPlaceRecipe` is not directly accessible anymore, instead it is accessed and returned as a `RecipeBookMenu$PostPlaceAction` via `#placeRecipe` + - `$CraftingMenuAccess` - Defines how the placable recipe menu can be interacted with. + - `ServerRecipeBook` + - `fromNbt` now takes in a predicate of a `ResourceKey` instead of the `RecipeManager` + - `copyOverData` - Reads the data from another recipe book. + - `$DisplayResolver` - Resoluves the recipes to display by passing in a `RecipeDisplayEntry` +- `net.minecraft.stats.RecipeBook#isFiltering(RecipeBookMenu)` is removed +- `net.minecraft.world.entity.player` + - `Player#awardRecipesByKey` now takes in a list of `ResourceKey`s + - `StackedItemContents#canCraft` overloads that take in a list of ingredient infos +- `net.minecraft.world.inventory` + - `AbstractCraftingMenu` - A menu for a crafting interface. + - `AbstractFurnaceMenu` now takes in the `RecipePropertySet` key + - `CraftingMenu#slotChangedCraftingGrid` now takes in a `ServerLevel` instead of a `Level` + - `ItemCombinerMenu` now takes in an `ItemCombinerMenuSlotDefinition` + - `mayPickup` now defaults to `true` + - `ItemCombinerMenuSlotDefinition#hasSlot`, `getInputSlotIndexes` is removed + - `RecipeBookMenu` no longer takes in any generics + - `handlePlacement` is now abstract and returns a `$PostPlaceAction`, taking in an additional `ServerLevel` + - This remove all basic placement recipes calls, as that would be handled internally by the `ServerPlaceRecipe` + - `RecipeCraftingHolder#setRecipeUser` no longer takes in a `Level` + - `SmithingMenu#hasRecipeError` - Returns whether the recipe had an error when placing items in the inventory. +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now implements `SingleItemRecipe` + - The constructor no longer takes in the `RecipeType`, making the user override the `getType` method + - `getExperience` -> `experience` + - `getCookingTime` -> `cookingTime` + - `furnaceIcon` - Returns the icon of the furnace. + - `$Serializer` - A convenience implementation for the cooking recipe serializer instance. + - `CookingBookCategory` now has an integer id + - `CraftingRecipe#defaultCrafingRemainder` - Gets the stacks that should remain behind in the crafting recipe. + - `CustomRecipe$Serializer` - A convenience implementation for the custom recipe serializer instance. + - `ExtendedRecipeBookCategory` - A unifying interface that denotes a category within the recipe book. + - `Ingredient#optionalIngredientToDisplay` - Converts an optional ingredient to a `SlotDisplay`. + - `Recipe#getRemainingItems` -> `CraftingRecipe#getRemainingItems` + - `RecipeAccess` - An accessor that returns the property sets that contain the inputs of available recipes. + - `RecipeBookCategory` - An object that represents a single category within the recipe book. + - `RecipeCache#get` now takes in a `ServerLevel` instead of a `Level` + - `RecipeHolder` now takes in a `ResourceKey` + - `RecipeManager` now extends `SimplePreparableReloadLsitener` and implements `RecipeAccess` + - `prepare` - Creates the recipe map from the recipe registry + - `logImpossibleRecipes`, `hasErrorsLoading` is removed + - `getRecipeFor` now takes in a `ResourceKey` where there was a `ResourceLocation` repviously + - `getRecipesFor`, `getAllRecipesFor` -> `RecipeMap#getRecipesFor` + - `byType` is removed + - `getRemainingItemsFor` is Removed + - `byKey`.`byKeyTyped` now takes in a `ResourceKey` + - `getOrderedRecipes` is revmoed + - `getSynchronizedRecipes` -> `getSynchronizedItemProperties`, `getSynchronizedStonecutterRecipes`; not one-to-one + - `getRecipeIds` is removed + - `getRecipeFromDisplay` - Gets the recipe display info given its id. + - `listDisplaysForRecipe` - Accepts a list of display entries of the recipes to display. + - `replaceRecipes` is removed + - `$CachedCheck#getRecipeFor` now takes in a `ServerLevel` instead of a `Level` + - `$IngredientCollector` - A recipe consumer that extracts the ingredient from a recipe and adds it to a `RecipePropertySet` + - `$IngredientExtractor` - A method that gets the ingredients of a recipe when present. + - `$ServerDisplayInfo` - A record that links a display entry to its recipe holder. + - `RecipeMap` - A class which maps recipe holders by their recipe type and resource key. + - `RecipePropertySet` - A set of ingredients that can be used as input to a given recipe slot. Used to only allow specific inputs to slots on screens. + - `SelectableRecipe` - A record that holds the slot display and its associated recipe. Currently only used for the stonecutting menu. + - `SimpleCookingSerializer` -> `AbstractCookingRecipe$Serializer` + - `SingleItemRecipe` no longer takes in the `RecipeType` or `RecipeSerializer` + - `ingredient`, `result`, `group` is now private + - `input`, `result` - The slots of the recipe. +- `net.minecraft.world.item.crafting.display` + - `DisplayContentsFactory` - A factory for accepting contents of a recipe. Its subtypes accepts the stacks of the recipe and the remainder. + - `RecipeDisplay` - A display handler to show the contents of a recipe. + - `RecipeDisplayEntry` - A record that links the recipe display to its identifier, category, and crafting requirements. + - `RecipeDisplayId` - An identifier for the recipe display. + - `SlotDisplay` - A display handler to show the contents of a slot within a recipe. + - `SlotDisplayContext` - Context keys used by slot displays. +- `net.minecraft.world.level.Level#getRecipeManager` -> `recipeAccess`, returns `RecipeAccess` on level but `RecipeManager` on `ServerLevel` +- `net.minecraft.world.level.block.CrafterBlock#getPotentialResults` now takes in a `ServerLevel` instead of a `Level` +- `net.minecraft.world.level.block.entity.CampfireBlockEntity` + - `getCookableRecipe` is removed + - `placeFood` now takes in a `ServerLevel` instead of a `Level` + +### 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. + +#### Language File Removals and Renames + +All removals and renames to translations keys within `assets/minecraft/lang` are now shown in a `deprecated.json`. + +#### Critereons, Supplied with HolderGetters + +All critereon builders during construction now take in a `HolderGetter`. While this may not be used, this is used instead of a direct call to the static registry to grab associated `Holder`s and `HolderSet`s. + +- `net.minecraft.advancement.critereon` + - `BlockPredicate$Builder#of` + - `ConsumeItemTrigger$TriggerInstance#usedItem` + - `EntityEquipmentPredicate#captainPredicate` + - `EntityPredicate$Builder#of` + - `EntityTypePredicate#of` + - `ItemPredicate$Builder#of` + - `PlayerTrigger$TriggerInstance#walkOnBlockWithEquipment` + - `ShotCrossbowTrigger$TriggerInstance#shotCrossbow` + - `UsedTotemTrigger$TriggerInstance#usedToItem` + +#### MacosUtil#IS_MACOS + +`com.mojang.blaze3d.platform.MacosUtil#IS_MACOS` has been added to replace specifying a boolean during the render process. + +- `com.mojang.blaze3d.pipeline` + - `RenderTarget#clear(boolean)` -> `clear()` + - `TextureTarget(int, int, boolean, boolean)` -> `TextureTarget(int, int, boolean)` +- `com.mojang.blaze3d.platform.GlStateManager#_clear(boolean)` -> `_clear()` +- `com.mojang.blaze3d.systems.RenderSystem#clear(int, boolean)` -> `clear(int)` + +#### Fog Parameters + +Fog methods for individual values have been replaced with a `FogParameters` data object. + +- `com.mojang.blaze3d.systems.RenderSystem` + - `setShaderFogStart`, `setShaderFogEnd`, `setShaderFogColor`, `setShaderFogShape` -> `setShaderFog` + - `getShaderFogStart`, `getShaderFogEnd`, `getShaderFogColor`, `getShaderFogShape` -> `getShaderFog` +- `net.minecraft.client.renderer.FogRenderer` + - `setupColor` -> `computeFogColor`, returns a `Vector4f` + - `setupNoFog` -> `FogParameters#NO_FOG` + - `setupFog` now takes in a `Vector4f` for the color and returns the `FogParameters` + - `levelFogColor` is removed + +#### New Tags + +- `minecraft:banner_pattern` + - `bordure_indented` + - `field_masoned` +- `minecraft:block` + - `bats_spawnable_on` + - `pale_oak_logs` +- `minecraft:damage_type` + - `mace_smash` +- `minecraft:item` + - `diamond_tool_materials` + - `furnace_minecart_fuel` + - `gold_tool_materials` + - `iron_tool_materials` + - `netherite_tool_materials` + - `villager_picks_up` + - `wooden_tool_materials` + - `piglin_safe_armor` + - `repairs_leather_armor` + - `repairs_chain_armor` + - `repairs_iron_armor` + - `repairs_gold_armor` + - `repairs_diamond_armor` + - `repairs_netherite_armor` + - `repairs_turtle_helmet` + - `repairs_wolf_armor` + - `duplicates_allays` + - `brewing_fuel` + - `panda_eats_from_ground` + - `shulker_boxes` + - `bundles` + - `map_invisibility_equipment` + - `pale_oak_logs` + - `gaze_disguise_equipment` +- `minecraft:entity_type` + - `boat` + +#### Smarter Framerate Limiting + +Instead of simply limiting the framerate when the player is not in a level or when in a screen or overlay, there is different behavior depending on different actions. This is done using the `InactivityFpsLimit` via the `FramerateLimitTracker`. This adds two additional checks. If the window is minimized, the game runs at 10 fps. If the user provides no input for a minute, then the game runs at 30 fps. 10 fps after ten minutes of no input. + +- `com.mojang.blaze3d.platform.FramerateLimitTracker` - A tracker that limits the framerate based on the set value. +- `com.mojang.blaze3d.platform#Window#setFramerateLimit`, `getFramerateLimit` is removed +- `net.minecraft.client` + - `InactivityFpsLimit` - An enum that defines how the FPS should be limited when the window is minimzed or the player is away from keyboard. + - `Minecraft#getFramerateLimitTracker` - Returns the framerate limiter. + +#### Fuel Values + +`FuelValues` has replaced the static map within `AbstractFurnaceBlockEntity`. This functions the same as that map, except the fuel values are stored on the `MinecraftServer` itself and made available to individual `Level` instances. The map can be obtained with access to the `MinecraftServer` or `Level` and calling the `fuelValues` method. + +- `net.minecraft.client.multiplayer.ClientPacketListener#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.server.MinecraftServer#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.server.level.Level#fuelValues` - Returns the burn times for fuel. +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity` + - `invalidateCache`, `getFuel` -> `Level#fuelValues` + - `getBurnDuration` now takes in the `FuelValues` + - `isFuel` -> `FuelValues#isFuel` + - `FuelValues` - A class which holds the list of fuel items and their associated burn times + +#### Light Emissions + +Light emission data is now baked into the quad and can be added to a face using the `light_emission tag`. + +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` now takes in an `int` representing the light emission + - `getLightEmission` - Returns the light emission of a quad. + - `BlockElement` now takes in an `int` representing the light emission + - `FaceBakery#bakeQuad` now takes in an `int` representing the light emission + +#### Map Textures + +Map textures are now handled through the `MapTextureManager`, which handles the dynamic texture, and the `MapRenderer`, which handles the map rendering. Map decorations are still loaded through the `map_decorations` sprite folder. + +- `net.minecraft.client` + - `Minecraft` + - `getMapRenderer` - Gets the renderer for maps. + - `getMapTextureManager` - Gets the texture manager for maps. +- `net.minecraft.client.resources#MapTextureManager` - Handles creating the dynamic texture for the map. +- `net.minecraft.client.gui.MapRenderer` -> `net.minecraft.client.renderer.MapRenderer` +- `net.minecraft.client.renderer#GameRenderer#getMapRenderer` -> `Minecraft#getMapRenderer` + +#### Orientations + +With the edition of the redstone wire experiments comes a new class provided by the neighbor changes: `Orientation`. `Orientation` is effectively a combination of two directions and a side bias. `Orientation` is used as a way to propogate updates relative to the connected directions and biases of the context. Currently, this means nothing for people not using the new redstone wire system as all other calls to neighbor methods set this to `null`. However, it does provide a simple way to propogate behavior in a stepwise manner. + + +- `net.minecraft.client.renderer.debug.RedstoneWireOrientationsRenderer` - A debug renderer for redstone wires being oriented. +- `net.minecraft.world.level.Level` + - `updateNeighborsAt` - Updates the neighbor at the given position with the specified `Orientation`. + - `updateNeighborsAtExceptFromFacing`, `neighborChanged` now takes in an `Orientation` +- `net.minecraft.world.level.block.RedStoneWireBlock` + - `getBlockSignal` - Returns the strength of the block signal. +- `net.minecraft.world.level.block.state.BlockBehaviour` + - `neighborChanged`, `$BlockStateBase#handleNeighborChanged` now takes in an `Orientation` instead of the neighbor `BlockPos` + - `updateShape` now takes in the `LevelReader`, `ScheduledTickAccess`, and a `RandomSource` instead of the `LevelAccessor`; the `Direction` and `BlockState` parameters are reordered + - `$BlockStateBase#updateShape` now takes in the `LevelReader`, `ScheduledTickAccess`, and a `RandomSource` instead of the `LevelAccessor`; the `Direction` and `BlockState` parameters are reordered +- `net.minecraft.world.level.redstone` + - `CollectingNeighborUpdater$ShapeUpdate#state` -> `neighborState` + - `NeighborUpdater` + - `neighborChanged`, `updateNeighborsAtExceptFromFacing`, `executeUpdate` now takes in an `Orientation` instead of the neighbor `BlockPos` + - `executeShapeUpdate` switches the order of the `BlockState` and neighbor `BlockPos` + - `Orientation` - A group of connected `Directions` on a block along with a bias towards either the front or the up side. + - `RedstoneWireEvaluator` - A strength evaluator for incoming and outgoing signals. + +#### Minecart Behavior + +Minecarts now have a `MinecartBehavior` class that handles how the entity should be moved and rendered. + +- `net.minecraft.core.dispenser.MinecartDispenseItemBehavior` - Defines how a minecart should behave when dispensed from a dispenser. +- `net.minecraft.world.entity.vehicle` + - `AbstractMinecart` + - `getMinecartBehavior` - Returns the behavior of the minecart. + - `exits` is now public + - `isFirstTick` - Returns whether this is the first tick the entity is alive. + - `getCurrentBlockPosOrRailBelow` - Gets the current position of the minecart or the rail beneath. + - `moveAlongTrack` -> `makeStepAlongTrack` + - `setOnRails` - Sets whether the minecart is on rails. + - `isFlipped`, `setFlipped` - Returns whetherh the minecart is upside down. + - `getRedstoneDirection` - Returns the direction the redstone is powering to. + - `isRedstoneConductor` is now public + - `applyNaturalSlowdown` now returns the vector to slowdown by. + - `getPosOffs` -> `MinecartBehavior#getPos` + - `setInitialPos` - Sets the initial position of the minecart. + - `createMinecart` is now abstract in its creation, meaning it can be used to create any minecart given the provided parameters + - `getMinecartType` is removed + - `getPickResult` is now abstract + - `$Type` and `getMinecartType` is replaced by `isRideable` and `isFurnace`, which is not one-to-one. + - `AbstractMinecartContainer(EntityType, double, double, double, Level)` is removed + - `MinecartBehavior` - holds how the entity should be rendered and positions during movement. + - `MinecartFurnace#xPush`, `zPush` -> `push` +- `net.minecraft.world.level.block.state.properties.RailShape#isAscending` -> `isSlope` +- `net.minecraft.world.phys.shapes.MinecartCollisionContext` - An entity collision context that handles the collision of a minecart with some other collision object. + +#### EXPLOOOOSSSION! + +`Explosion` is now an interface that defines the metadata of the explosion. It does not contain any method to actually explode itself. However, `ServerExplosion` is still used internally to handle level explosions and the like. + +- `net.minecraft.world.level` + - `Explosion` -> `ServerExplosion` + - `Explosion` - An interface that defines how an explosion should occur. + - `getDefaultDamageSource` - Returns the default damage source of the explosion instance. + - `shouldAffectBlocklikeEntities` - Returns whether block entites should be affected by the explosion. + - `level` - Gets the `ServerLevel` + - `ExplosionDamageCalculator#getEntityDamageAmount` now takes in an additional `float` representing the seen percent + - `Level#explode` no longer returns anything +- `net.minecraft.world.level.block.Block#wasExploded` now takes in a `ServerLevel` instead of a `Level` +- `net.minecraft.world.level.block.state.BlockBehaviour#onExplosionHit`, `$BlockStateBase#onExplosionHit` now takes in a `ServerLevel` instead of a `Level` + + +#### The Removal of the Carving Generation Step + +`GenerationStep$Carving` has been removed, meaning that all `ConfiguredWorldCarver`s are provided as part of a single `HolderSet`. + +```json +// In some BiomeGenerationSettings JSON +{ + "carvers": [ + // Carvers here + ] +} +``` + +- `net.minecraft.world.level.biome.BiomeGenerationSettings` + - `getCarvers` no longer takes in a `GenerationStep$Carving` + - `$Builder#addCarver` no longer takes in a `GenerationStep$Carving` + - `$PlainBuilder#addCarver` no longer takes in a `GenerationStep$Carving` +- `net.minecraft.world.level.chunk` + - `ChunkGenerator#applyCarvers` no longer takes in a `GenerationStep$Carving` + - `ProtoChunk#getCarvingMask`, `getOrCreateCarvingMask`, `setCarvingMask` no longer takes in a `GenerationStep$Carving` +- `net.minecraft.world.level.levelgen.placement` + - `CarvingMaskPlacement` class is removed + - `PlacementContext#getCarvingMask` no longer takes in a `GenerationStep$Carving` + +#### Codecable Json Reload Listener + +The `SimpleJsonResourceReloadListener` has been rewritten to use codecs instead of pure `Gson`. + +```java +public class MyJsonListener extends SimpleJsonResourceReloadListener { + + // If you do not need registry access, the HolderLookup$Provider parameter can be removed + public MyJsonListener(HolderLookup.Provider registries, Codec codec, String directory) { + super(registries, codec, directory); + } +} +``` + +- `net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener` now takes in a generic representing the data object of the JSON + - The constructor is now protected, taking in the codec of the data object, the string of the directory, and an optional `HolderLookup$Provider` to construct the `RegistryOps` serialization context as necessary + - `prepare` now returns a map of names to objects + - `scanDirectory` now takes in the `DynamicOps` and `Codec` + +#### Consecutive Executors + +`ProcessorMailbox` and `ProcessorHandle` have been replaced with `AbstractConsecutiveExecutor` and `TaskScheduler`, respectively. These are effectively the same in their usage, just with potentially different method names. + +- `net.minecraft.util.thread` + - `ProcessorMailbox` -> `AbstractConsecutiveExecutor`, not one-to-one + - `ConsecutiveExecutor` would be the equivalent implementation + - `PriorityConsecutiveExecutor` - An executor that specifies the priority of the task to run when scheduling. + - `BlockableEventLoop#wrapRunnable` -> `AbstractConsecutiveExecutor#wrapRunnable` + - `ProcessorHandle` -> `TaskScheduler`, where the generic is a subtype of `Runnable` + - `tell` -> `schedule` + - `ask`, `askEither` -> `scheduleWithResult`, not one-to-one + - `of` -> `wrapExecutor` + - `StrictQueue` no longer takes in an `F` generic and makes `T` a subtype of `Runnable` + - `pop` now returns a `Runnable` + - `$IntRunnable` -> `$RunnableWithPriority` + + +#### Mob Conversions + +Mobs, converted via `#convertTo`, have their logic handled by `ConversionType`, `ConversionParams`. `ConversionType` is an enum that dictates the logic to apply when copying the information from one mob to another via `#convert`. The common properties are handled via `#convertCommon`, which is called within the `#convert` method. There are currently two types: `SINGLE`, where the entity is converted one-to-one to another entity; and `SPLIT_ON_DEATH`, where the `Mob#convertTo` method is called mutiple times such as when a slime dies. `ConversionParams` contains the metadata about the conversion process: the type, whether the entity can keep its equipment or pick up loot, and what team the entity is on. `Mob#convertTo` also takes in a mob consumer to apply any finalization settings to the entity itself. + +```java +// For some Mob exampleMob +exampleMob.convertTo( + EntityType.SHEEP, // The entity to convert to + new ConversionParams( + ConversionType.SINGLE, // One-to-one + true, // Keep equipment + false // Do not preserve pick up loot + ), + EntitySpawnReason.CONVERSION, // Reason entity spawned + sheep -> { + // Perform any other settings to set on the newly converted entity + }, +) +``` + +- `net.minecraft.world.entity` + - `ConversionParams` - A record containing the settings of what happens when a mob is converted to another entity + - `ConversionType` - An enum that defines how one mob is transformed to another. Currently either `SINGLE` for one-to-one, or `SPLIT_ON_DEATH` for one-to-many (only used for slimes) + - `Mob#convertTo` now takes in the `ConversionParams`, an optional `EntitySpawnReason` of the entity (default `CONVERSION`), and a mob consumer to set any other information after conversion + +#### Ender Pearl Chunk Loading + +Ender pearls now load the chunks they cross through by adding a ticket to the chunk source and storing the entity on the player. + +- `net.minecraft.server.level.ServerPlayer` + - `registerEnderPearl`, `deregisterEnderPearl`, `getEnderPearls` - Handles the ender pearls thrown by the player. + - `registerAndUpdateEnderPearlTicket`, `placeEnderPearlTicket` - Handles the region tickets for the thrown ender pearls. + +#### Profilers and the Tracy Client + +Profilers have been separated from the minecraft instance, now obtained through `Profiler#get`. A new profiler instance can be added via a try-resource block on `Profiler#use`. In addition, the profiler addds a new library called Tracy, made to track the current stack frame along with capturing images on the screen, if the associated `--tracy` argument is passed in. These sections can be split into 'zones' to more granularly distinguish what is happening. + +```java +Profiler.get().push("section"); +// Do code here +Profiler.get().pop(); +``` + +- `com.mojang.blaze3d.systems.RenderSystem#flipFrame` now takes in a `TracyFrameCapture`, or `null` +- `net.minecraft.client.Minecraft#getProfiler` -> `Profiler#get` +- `net.minecraft.client.main.GameConfig$GameData` now takes in a boolean on whether to capture the screen via the tracy client. +- `net.minecraft.client.multiplayer.ClientLevel` no longer takes in the `ProfilerFiller` +- `net.minecraft.server.MinecraftServer#getProfiler` -> `Profiler#get` +- `net.minecraft.server.packs.resources.PreparableReloadListener#reload` no longer takes in the `ProfilerFiller`s +- `net.minecraft.util.profiling` + - `Profiler` - A static handler for managing the currently active `ProfilerFiller`. + - `ProfilerFiller` + - `addZoneText` - Adds text to label when profiling the current frame. + - `addZoneValue` - Adds the value of the zone when profiling the current frame. + - `setZoneColor` - Sets the color of the zone when profiling the current frame. + - `zone` - Adds a profiler section while creating a new zone to call the above methods for. + - `tee` -> `combine` + - `$CombinedProfileFiller` - A profiler that writes to multiple profilers. + - `TracyZoneFiller` - A profiler used by the tracy client to keep track of the currently profiling zones. + - `Zone` - A section that is current being profiled and interpreted by Tracy. +- `net.minecraft.world.entity.ai.goal.GoalSelector` no longer takes in the supplied `ProfilerFiller` +- `net.minecraft.world.level` + - `Level` no longer takes in the `ProfilerFiller` + - `getProfiler`, `getProfilerSupplier` -> `Profiler#get` + - `PathNavigationRegion#getProfiler` -> `Profiler#get` +- `net.minecraft.world.ticks.LevelTicks` no longer takes in the `ProfilerFiller` + +#### Tick Throttler + +To prevent the player from spamming certain actions, `TickThrottler` was added. The throttler takes in the threshold and the increment to add to the count. If the count is less than the threshold, the action can occur. The count is reduced every tick. + +- `net.minecraft.util.TickThrottler` - A utility for throttling certain actions from happening too often. + +#### Context Keys + +Loot context parameters have been replaced with Context keys, which is simply a more general naming scheme for the previous classes. This also caused the context keys to be used in other contexts that may have arbitrary data. + +For a brief description, the context key system is effectively a general typed dictionary, where each `ContextKey` holds the value type, which is then stored in a backed-map within a `ContextMap`. To enforce required and optional parameters, a `ContextMap` is built with a `ContextKeySet`, which defines the keys of the dictionary map. + +- `net.minecraft.advancements.critereon.CriterionValidator#validate` now takes in a `ContextKeySet` instead of a `LootContextParamSet` +- `net.minecraft.data.loot.LootTableProvider$SubProviderEntry#paramSet` now takes in a `ContextKeySet` instead of a `LootContextParamSet` +- `net.minecraft.util.context` + - `ContextKey` - A key that represents an object. It can be thought of a dictionary key that specifies the value type. + - `ContextKeySet` - A key set which indicates what keys the backing dictionary must have, along with optional keys that can be specified. + - `ContextMap` - A map of context keys to their typed objects. +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect#codec` now takes in a `ContextKeySet` instead of a`LootContextParamSet` + - `TargetedConditionalEffect#codec` now takes in a `ContextKeySet` instead of a`LootContextParamSet` +- `net.minecraft.world.level.storage.loot` + - `LootContext` + - `hasParam` -> `hasParameter` + - `getParam` -> `getParameter` + - `getParamOrNull` - `getOptionalParameter` + - `$EntityTraget#getParam` now returns a `ContextKey` instead of a `LootContextParam` + - `LootContextUser#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + - `LootParams` now takes in a `ContextMap` instead of a map of params to objects + - `hasParam`, `getParameter`, `getOptionalParameter`, `getParamOrNull` are accessible through the `ContextMap` under different names + - `$Builder#withParameter`, `withOptionalParameter`, `getParameter`, `getOptionalParameter` now takes in a `ContextKey` instead of a `LootContextParam` + - `$Builder#create` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `LootTable` + - `getParameSet` now returns a `ContextKeySet` instead of a `LootContextParamSet` + - `$Builder#setParamSet` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `ValidationContext` now takes in a `ContextKeySet` instead of a `LootContextParamSet` + - `validateUser` -> `validateContextUsage` + - `setParams` - `setContextKeySet` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction$Source#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s +- `net.minecraft.world.level.storage.loot.parameters` + - `LootContextParam` -> `net.minecraft.util.context.ContextKey` + - `LootContextParamSet` -> `net.minecraft.util.context.ContextKeySet` +- `net.minecraft.world.level.storage.loot.providers.nbt` + - `ContextNbtProvider$Getter#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + - `NbtProvider#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s +- `net.minecraft.world.level.storage.loot.providers.score.ScoreboardNameProvider#getReferencedContextParams` now takes in a set of `ContextKey`s rather than a set of `LootContextParam`s + +#### List of Additions + +- `com.mojang.blaze3d.framegraph` + - `FrameGraphBuilder` - A builder that constructs the frame graph that define the resources used and the frame passes to render. + - `FramePass` - An interface that defines how to read/write resources and execute them for rendering within the frame graph. +- `com.mojang.blaze3d.platform` + - `ClientShutdownWatchdog` - A watchdog created for what happens when the client is shutdown. + - `NativeImage#getPixelsABGR` - Gets the pixels of the image in ABGR format. + - `Window` + - `isIconified` - Returns whether the window is currently iconified (usually minimized onto the taskbar). + - `setWindowCloseCallback` - Sets the callback to run when the window is closed. +- `com.mojang.blaze3d.resource` + - `CrossFrameResourcePool` - Handles resources that should be rendered across multiple frames + - `GraphicsResourceAllocator` - Handles resources to be rendered and removed. + - `RenderTargetDescriptor` - Defines a render target to be allocated and freed. + - `ResourceDescriptor` - Defines a resource and how it is allocated and freed. + - `ResourceHandle` - Defines a pointer to an individual resource. +- `com.mojang.blaze3d.systems.RenderSystem#overlayBlendFunc` - Sets the default overlay blend function between layers with transparency. +- `com.mojang.blaze3d.vertex` + - `PoseStack#translate(Vec3)` - Translates the top pose using a vector + - `VertexConsumer#setNormal(PoseStack$Pose, Vec3)` - Sets the normal of a vertex using a vector +- `net.minecraft` + - `Optionull#orElse` - If the first object is null, return the second object. + - `TracingExecutor` - An executor that traces the stack frames of the class references executing. + - `Util` + - `allOf` - ANDs all predicates or a list of predicates provided. If there are no supplied predicates, the method will default to `true`. + - `anyOf` - ORs all predicates or a list of predicates provided. If there are no supplied predicates, the method will default to `false`. + - `makeEnumMap` - Creates an enum map given the enum class and a function to convert the enum to a value. +- `net.minecraft.advancements.critereon` + - `InputPredicate` - A predicate that matches the input the player is making. + - `SheepPredicate` - A predicate for when the entity is a sheep. +- `net.minecraft.client` + - `Minecraft` + - `saveReport` - Saves a crash report to the given file. + - `triggerResourcePackRecovery` - A function that attempts to save the game when a compilation exception occurs, currently used by shaders when loading. + - `Options#highContrastBlockOutline` - When enabled, provides a greater contrast when hovering over a block in range. + - `ScrollWheelHandler` - A handler for storing information when a mouse wheel is scrolled. +- `ItemSlotMouseAction` - An interface that defines how the mouse interacts with a slot when hovering over. +- `net.minecraft.client.gui.components` + - `AbstractSelectionList#setSelectedIndex` - Sets the selected entry based on its index. + - `AbstractWidget#playButtonClickSound` - Plays the button click sound. + - `DebugScreenOverlay#getProfilerPieChart` - Gets the pie chart profiler renderer. +- `net.minecraft.client.gui.components.debugchart.AbstractDebugChart#getFullHeight` - Returns the height of the rendered chart. +- `net.minecraft.client.gui.components.toasts` + - `Toast` + - `getWantedVisbility` - Returns the visbility of the toast to render. + - `update` - Updates the data within the toast. + - `TutorialToast` has a constructor that takes in an `int` to represent the time to display in milliseconds. +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` + - `renderChar` - Renders a character in the specified color. + - `$GlyphInstance` - An instance of a glyph with the metadata of its screen location. +- `net.minecraft.client.gui.screens` + - `BackupConfirmScreen` has a constructor that takes in another `Component` that represents the prompt for erasing the cache. + - `Screen` + - `getFont` - Returns the current font used for rendering the screen. + - `showsActiveEffects` - When true, shows the mob effects currently applied to the player, assuming that such functionality is added to the screen in question. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen` + - `BACKGROUND_TEXTURE_WIDTH`, `BACKGROUND_TEXTURE_HEIGHT` - Both set to 256. + - `addItemSlotMouseAction` - Adds a mouse action when hovering over a slot. + - `renderSlots` - Renders all active slots within the menu. + - `AbstractRecipeBookScreen` - A screen that has a renderable and interactable `RecipeBookComponent` supplied from the constructor. +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent#showTooltipWithItemInHand`- Returns whether the tooltip should be rendered when the item is in the player's hand. +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldCallback` - An interface that creates the world given the current screen, registries, level data, and path directory. + - `CreateWorldScreen#testWorld` - Tries to open the world create screen with the provided generation settings context. + - `InitialWorldCreationOptions` - Contains the options set when creating the world to generate. + - `WorldCreationContextMapper` - An interface that creates the world context from the available resource reloaders and registries. +- `net.minecraft.client.multiplayer` + - `ClientChunkCache` + - `getLoadedEmptySections` - Returns the sections that have been loaded by the game, but has no data. + - `ClientLevel` + - `isTickingEntity` - Returns whether the entity is ticking in the level. + - `setSectionRangeDirty`- Marks an area as dirty to update during persistence and network calls. + - `onSectionBecomingNonEmpty` - Updates the section when it has data. + - `PlayerInfo#setTabListOrder`, `getTabListOrder` - Handles the order of players to cycle through in the player tab. +- `net.minecraft.client.multiplayer.chat.report.ReportReason#getIncompatibleCategories` - Gets all reasons that cannot be reported for the given type. +- `net.minecraft.client.particle.TrailParticle` - A particle to trail from its current position to the target position. +- `net.minecraft.client.player.LocalPlayer#getDropSpamThrottler` - Returns a throttler that determines when the player can drop the next item. +- `net.minecract.client.renderer` + - `CloudRenderer` - Handles the rendering and loading of the cloud texture data. + - `DimensionSpecialEffects#isSunriseOrSunset` - Returns whether the dimension time represents sunrise or sunset in game. + - `LevelEventHandler` - Handles the events sent by the `Level#levelEvent` method. + - `LevelRenderer` + - `getCapturedFrustrum` - Returns the frustrum box of the renderer. + - `getCloudRenderer` - Returns the renderer for the clouds in the skybox. + - `onSectionBecomingNonEmpty` - Updates the section when it has data. + - `LevelTargetBundle` - Holds the resource handles and render targets for the rendering stages. + - `LightTexture` + - `getBrightness` - Returns the brightness of the given ambient and sky light. + - `lightCoordsWithEmission` - Returns the packed light coordinates. + - `RenderType` + - `entitySolidZOffsetForward` - Gets a solid entity render type where the z is offset from the individual render objects. + - `flatClouds` - Gets the render type for flat clouds. + - `debugTriangleFan` - Gets the render type for debugging triangles. + - `vignette` - Gets the vignette type. + - `crosshair` - Gets the render type for the player crosshair. + - `mojangLogo` - Gets the render type for the mojang logo + - `Octree` - A traversal implementation for defining the order sections should render in the frustum. + - `ShapeRenderer` - Utility for rendering basic shapes in the Minecraft level. + - `SkyRenderer` - Renders the sky. + - `WeatherEffectRenderer` - Renders weather effects. + - `WorldBorderRenderer` - Renders the world border. +- `net.minecraft.client.renderer` + - `SectionOcclusionGraph#getOctree` - Returns the octree to handle traversal of the render sections. + - `ViewArea#getCameraSectionPos` - Gets the section position of the camera. +- `net.minecraft.client.renderer.culling.Frustum` + - `getFrustumPoints` - Returns the frustum matrix as an array of `Vector4f`s. + - `getCamX`, `getCamY`, `getCamZ` - Returns the frustum camera coordinates. +- `net.minecraft.client.renderer.chunk.CompileTaskDynamicQueue` - A syncrhonized queue dealing with the compile task of a chunk render section. +- `net.minecraft.client.renderer.debug` + - `ChunkCullingDebugRenderer` - A debug renderer for when a chunk is culled. + - `DebugRenderer` + - `renderAfterTranslucents` - Renders the chunk culling renderer after translucents have been rendered. + - `renderVoxelShape` - Renders the outline of a voxel shape. + - `toggleRenderOctree` - Toggles whether `OctreeDebugRenderer` is rendered. + - `OctreeDebugRenderer` - Renders the order of the section nodes. +- `net.minecraft.client.renderer.texture.AbstractTexture#defaultBlur`, `getDefaultBlur` - Returns whether the blur being applied is the default blur. +- `net.minecraft.client.resources.DefaultPlayerSkin#getDefaultSkin` - Returns the default `PlayerSkin`. +- `net.minecraft.commands.CommandBuildContext#enabledFeatures` - Returns the feature flags +- `net.minecraft.commands.arguments.selector.SelectorPattern` - A record that defines an `EntitySelector` resolved from some pattern. +- `net.minecraft.core` + - `BlockPos#betweenClosed` - Returns an iterable of all positions within the bounding box. + - `Direction` + - `getYRot` - Returns the Y rotation of a given direction. + - `getNearest` - Returns the nearest direction given some XYZ coordinate, or the fallback direction if no direction is nearer. + - `getUnitVec3` - Returns the normal unit vector. + - `$Axis#getPositive`, `getNegative`, `getDirections` - Gets the directions along the axis. + - `GlobalPos#isCloseEnough` - Returns whether the distance from this position to another block position in a dimension is within the given radius. + - `HolderLookup$Provider` + - `listRegistries` - Returns the registry lookups for every registry. + - `allRegistriesLifecycle` - Returns the lifecycle of all registries combined. + - `HolderSet#isBound` - Returns whether the set is bound to some value. + - `Registry$PendingTags#size` - Gets the number of tags to load. + - `Vec3i#distChessboard` - Gets the maximum absolute distance between the vector components. +- `net.minecraft.core.component` + - `DataComponentHolder#getAllOfType` - Returns all data components that are of the specific class type. + - `DataComponentPredicate` + - `someOf` - Constructs a data component predicate where the provided map contains the provided component types. + - `$Builder#expect` - Adds that we should expect the data component has some value. + - `PatchedDataComponentMap#clearPatch` - Clears all patches to the data components on the object. +- `net.minecraft.core.particles.TargetColorParticleOption` - A particle option that specifies a target location and a color of the particle. +- `net.minecraft.data.DataProvider` + - `saveAll` - Writes all values in a resource location to value map to the `PathProvider` using the provided codec. + - `saveStable` - Writes a value to the provided path given the codec. +- `net.minecraft.data.loot#BlockLootSubProvider` + - `createMossyCarpetBlockDrops` - Creates a loot table for a mossy carpet block. + - `createShearsOrSlikTouchOnlyDrop` - Creates a loot table that can only drop its item when mined with shears or an item with the silk touch enchantment. +- `net.minecraft.data.worldgen.Pools#createKey` - Creates a `ResourceKey` for a template pool. +- `net.minecraft.data.models.EquipmentModelProvider` - A model provider for equipment models, only includes vanilla bootstrap. +- `net.minecraft.data.info.DatapackStructureReport` - A provider that returns the structure of the datapack. +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `absoluteAABB`, `relativeAABB` - Moves the bounding box between absolute coordinates and relative coordinates to the test location + - `assertEntityData` - Asserts that the entity at the provided block position matches the predicate. + - `hurt` - Hurts the entity the specified amount from a source. + - `kill` - Kills the entity. + - `GameTestInfo#getTestOrigin` - Gets the origin of the spawn structure for the test. + - `StructureUtils#getStartCorner` - Gets the starting position of the test to run. +- `net.minecraft.network` + - `FriendlyByteBuf` + - `readVec3`, `writeVec3` - Static methods to read and write vectors. + - `readContainerId`, `writeContainerId` - Methods to read and write menu identifiers. + - `readChunkPos`, `writeChunkPos` - Methods to read and write the chunk position. + - `StreamCodec#composite` - A composite method that takes in seven/eight parameters. +- `net.minecraft.network.codec.ByteBufCodecs` + - `CONTAINER_ID` - A stream codec to handle menu identifiers. + - `ROTATION_BYTE` - A packed rotation into a byte. + - `LONG` - A stream codec for a long, or 64 bytes. + - `OPTIONAL_VAR_INT` - A stream codec for an optional integer, serializing `0` when not present, or one above the stored value. + - `-1` cannot be sent properly using this stream codec. +- `net.minecraft.network.protocol.game` + - `ClientboundEntityPositionSyncPacket` - A packet that syncs the entity's position. + - `ClientboundPlayerRotationPacket` - A packet that contains the player's rotation. +- `net.minecraft.server` + - `MinecraftServer` + - `tickConnection` - Ticks the connection for handling packets. + - `reportPacketHandlingException` - Reports a thrown exception when attempting to handle a packet + - `pauseWhileEmptySeconds` - Determines how many ticks the server should be paused for when no players are on. + - `SuppressedExceptionCollector` - A handler for exceptions that were supressed by the server. +- `net.minecraft.server.commands.LookAt` - An interface that defines what should happen to an entity when the command is run, typically moving it to look at another. +- `net.minecraft.server.level` + - `ChunkHolder#hasChangesToBroadcast` - Returns whether there is any updates within the chunk to send to the clients. + - `ChunkTaskDispatcher` - A task scheduler for chunks. + - `DistanceManager` + - `getSpawnCandidateChunks` - Returns all chunks that the player can spawn within. + - `getTickingChunks` - Returns all chunks that are currently ticking. + - `ServerChunkCache#onChunkReadyToSend` - Adds a chunk holder to broadcast to a queue. + - `ServerEntityGetter` - An entity getter interface implementation that operates upon the `ServerLevel`. + - Replcaes the missing methods from `EntityGetter` + - `ServerPlayer` + - `getTabListOrder` - Handles the order of players to cycle through in the player tab. + - `getLastClientInput`, `setLastClientInput`, `getLastClientMoveIntent` - Handles how the server player interprets the client impulse. + - `commandSource` - Returns the player's source of commands. + - `createCommandSourceStack` - Creates the source stack of the player issuing the command. + - `ThrottlingChunkTaskDispatcher` - A chunk task dispatcher that sets a maximum number of chunks that can be executing at once. + - `TickingTracker#getTickingChunks` - Returns all chunks that are currently ticking. +- `net.minecraft.server.packs.repository.PackRepository#isAbleToClearAnyPack` - Rebuilds the selected packs and returns whether it is different from the currently selected packs. +- `net.minecraft.resources.DependantName` - A reference object that maps some registry object `ResourceKey` to a value. Acts similarly to `Holder` except as a functional interface. +- `net.minecraft.tags.TagKey#streamCodec` - Constructs a stream codec for the tag key. +- `net.minecraft.util` + - `ARGB#vector3fFromRGB24` - Creates a `Vector3f` containing the RGB components using the low 24 bits of an integer. + - `BinaryAnimator` - A basic animator that animates between two states using an easing function. + - `ExtraCodecs` + - `NON_NEGATIVE_FLOAT` - A float codec that validates the value cannot be negative. + - `RGB_COLOR_CODEC` - An integer, float, or three vector float codec representing the RGB color. + - `nonEmptyMap` - A map codec that validates the map is not empty. + - `Mth` + - `wrapDegrees` - Sets the degrees to a value within (-180, 180]. + - `lerp` - Linear interpolation between two vectors using their components. + - `length` - Gets the length of a 2D point in space. + - `easeInOutSine` - A cosine function that starts at (0,0) and alternates between 1 and 0 every pi. + - `packDegrees`, `unpackDegrees` - Stores and reads a degree in `float` form to a `byte`. + - `RandomSource#triangle` - Returns a random `float` between the two `floats` (inclusive, exclusive) using a trangle distribution. + - `StringRepresentable$EnumCodec#byName` - Gets the enum by its string name or the provided supplier value if null. + - `TriState` - An enum that represents three possible states: true, false, or default. +- `net.minecraft.util.datafix.ExtraDataFixUtils` + - `patchSubType` - Rewrites the second type to the third type within the first type. + - `blockState` - Returns a dynamic instance of the block state + - `fixStringField` - Modifies the string field within a dynamic. +- `net.minecraft.util.thread.BlockableEventLookup` + - `BLOCK_TIME_NANOS` - Returns the amount of time in nanoseconds that an event will block the thread. + - `isNonRecoverable` - Returns whether the exception can be recovered from. +- `net.minecraft.world.damagesource.DamageSources` + - `enderPearl` - Returns a damage source from when an ender pearl is hit. + - `mace` - Returns a damage source where a direct entity hits another with a mace. +- `net.minecraft.world.entity` + - `Entity` + - `applyEffectsFromBlocks` - Applies any effects from blocks via `Block#entityInside` or hardcoded checks like snow or rain. + - `isAffectedByBlocks` - Returns whether the entity is affect by the blocks when inside. + - `checkInsideBlocks` - Gets all blocks that teh player has traversed and checks whether the entity is inside one and adds them to a set when present. + - `oldPosition`, `setOldPosAndrot`, `setOldPos`, `setOldRot` - Helpers for updating the last position and rotation of the entity. + - `getXRot`, `getYRot` - Returns the linearly interpolated rotation of the entity given the partial tick. + - `isAlliedTo(Entity)` - Returns whether the entity is allied to this entity. + - `teleportSetPosition` - Sets the position and rotation data of the entity being teleported via a `DimensionTransition` + - `getLootTable` - Returns the `ResourceKey` of the loot table the entity should use, if present. + - `isControlledByOrIsLocalPlayer` - Return whether the entity is the local player or is controlled by a local player. + - `shouldPlayLavaHurtSound` - When `true`, plays the lava hurt sound when the entity is hurt by lava. + - `onRemoval` - A method that gets called when the entity is removed. + - `cancelLerp` - Stops any lerped movement. + - `forceSetRotation` - Sets the rotation of the entity. + - `isControlledByClient` - Returns whether the entity is controlled by client inputs. + - `EntityType` + - `getDefaultLootTable` now returns an `Optional` in case the loot table is not present + - `$Builder#noLootTable` - Sets the entity type to have no loot spawn on death. + - `$Builder#build` now takes in the resouce key of the entity type + - `EntitySelector#CAN_BE_PICKED` - Returns a selector that gets all pickable entities not in spectator. + - `LivingEntity` + - `dropFromShearingLootTable` - Resolves a loot table with a shearing context. + - `getItemHeldByArm` - Returns the stack held by the specific arm. + - `getEffectiveGravity` - Returns the gravity applied to the entity. + - `canContinueToGlide` - Returns whether the entity can stil glide in the sky. + - `getItemBlockingWith` - Returns the stack the player is currently blocking with. + - `canPickUpLoot` - Returns whether the entity can pick up items. + - `dropFromGiftLootTable` - Resolves a loot table with a gift context. + - `handleExtraItemsCreatedOnUse` - Handles when a living entity gets a new item as a result of using another item. + - `isLookingAtMe` - Checks whether the provided entity is looking at this entity. + - `PositionMoveRotation` - A helper for handling the position and rotation of the entity in context. + - `WalkAnimationState#stop` - Stops the walking animation of the entity. +- `net.minecraft.world.entity.ai.attributes` + - `AttributeInstance` + - `getPermanentModifiers` - Returns all permanent modifiers applied to the entity. + - `addPermanentModifiers` - Adds a collection of permanent modifiers to apply. + - `AttributeMap#assignPermanentModifiers` - Copies the permanent modifiers from another map. +- `net.minecraft.world.entity.ai.control.Control#rotateTowards` - Returns a float that rotates to some final rotation by the provided difference within a clamped value. +- `net.minecraft.world.entity.ai.goal.Goal#getServerLevel` - Gets the server level given the entity or a level. +- `net.minecraft.world.entity.ai.navigation.PathNavigation` + - `updatePathfinderMaxVisitedNodes` - Updates the maximum number of nodes the entity can visit. + - `setRequiredPathLength` - Sets the minimum length of the path the entity must take. + - `getMaxPathLength` - Returns the maximum length of the path the entity can take. +- `net.minecraft.world.entity.ai.sensing` + - `PlayerSensor#getFollowDistance` - Returns the following distance of this entity. + - `Sensor#wasEntityAttackableLastNTicks` - Returns a predicate that checks whether the entity is attackable within the specified number of ticks. +- `net.minecraft.world.entity.ai.village.poi.PoiRecord#pack`, `PoiSection#pack` - Packs the necessary point of interest information. This only removes the dirty runnable. +- `net.minecraft.world.entity.animal` + - `AgeableWaterCreature` - A water creature that has an age state. + - `Animal` + - `createAnimalAttributes` - Creates the attribute supplier for animals. + - `playEatingSound` - Plays the sound an animal makes while eating. + - `Bee#isNightOrRaining` - Returns whether the current level has sky light and is either at night or raining. + - `Cat#isLyingOnTopOfSleepingPlayer` - Returns whether the cat is on top of a sleeping player. + - `Salmon#getSalmonScale` - Returns the scale factor to apply to the entity's bounding box. + - `Wolf#DEFAULT_TAIL_ANGLE` - Returns the default tail angle of the wolf. +- `net.minecraft.world.entity.boss.enderdragon.DragonFlightHistory` - Holds the y and rotation of the dragon when flying through the sky. Used for animating better motion of the dragon's parts. +- `net.minecraft.world.entity.monster.Zombie#canSpawnInLiquids` - When true, the zombie can spawn in a liquid. +- `net.minecraft.world.entity.player` + - `Inventory` + - `isUsableForCrafting` - Returns whether the state can be used in a crafting recipe. + - `createInventoryUpdatePacket` - Creates the packet to update an item in the inventory. + - `Player` + - `handleCreativeModeItemDrop` - Handles what to do when a player drops an item from creative mode. + - `shouldRotateWithMinecart` - Returns whether the player should also rotate with the minecart. + - `canDropItems` - When `true`, the player can drop items from the menu. + - `getPermissionLevel`, `hasPermissions` - Returns the permissions of the player. + - `StackedContents` - Holds a list of contents along with their associated size. + - `$Output` - An interface that defines how the contents are accepted when picked. +- `net.minecraft.world.entity.projectile.Projectile` + - `spawnProjectileFromRotation` - Spawns a projectile and shoots from the given rotation. + - `spawnProjectileUsingShoot` - Spawns a projectile and sets the initial impulse via `#shoot`. + - `spawnProjectile` - Spawns a projectile. + - `applyOnProjectileSpawned` - Applies any additional configurations from the given level and `ItemStack`. + - `onItemBreak` - Handles what happens when the item that shot the projectile breaks. + - `shouldBounceOnWorldBorder` - Returns whether the projectile should bounce off the world border. + - `setOwnerThroughUUID` - Set the owner of the projectile by querying it through its UUID. + - `$ProjectileFactory` - Defines how a projectile is spawned from some `ItemStack` by an entity. +- `net.minecraft.world.entity.vehicle` + - `AbstractBoat` - An entity that represents a boat. + - `AbstractChestBoat` - An entity that represent a boat with some sort of inventory. + - `ChestRaft` - An entity that represents a raft with some sort of inventory. + - `Raft` - An entity that represents a raft. +- `net.minecraft.world.inventory.AbstractContainerMenu` + - `addInventoryHotbarSlots` - Adds the hotbar slots for the given container at the x and y positions. + - `addInventoryExtendedSlots` - Adds the player inventory slots for the given container at the x and y positions. + - `addStandardInventorySlots` - Adds the hotbar and player inventory slots at their normal location for the given container at the x and y positions. + - `setSelectedBundleItemIndex` - Toggles the selected bundle in a slot. +- `net.minecraft.world.item` + - `BundleItem` + - `getOpenBundleModelFrontLocation`, `getOpenBundleModelBackLocation` - Returns the model locations of the bundle. + - `toggleSelectedItem`, `hasSelectedItem`, `getSelectedItem`, `getSelectedItemStack` - Handles item selection within a bundle. + - `getNumberOfItemsToShow` - Determines the number of items in the bundle to show at once. + - `getByColor` - Handles the available links from bundle to dyed bundles. + - `getAllBundleItemColors` - Returns a stream of all dyed bundles. + - `ItemStack` + - `clearComponents` - Clears the patches made to the stack, not the item components. + - `isBroken` - Returns wheter the stack has been broken. + - `hurtWithoutBreaking` - Damages the stack without breaking the stack. + - `getStyledHoverName` - Gets the stylized name component of the stack. +- `net.minecraft.world.item.component.BundleContents` + - `canItemBeInBundle` - Whether the item can be put into the bundle. + - `getNumberOfItemsToShow` - Determines the number of items in the bundle to show at once. + - `hasSelectedItem`, `getSelectedItem` - Handles item selection within a bundle. +- `net.minecraft.world.item.enchantment.EnchantmentHelper` + - `createBook` - Creates an enchanted book stack. + - `doPostAttackEffectsWithItemSourceOnBreak` - Applies the enchantments after attack when the item breaks. +- `net.minecraft.world.level` + - `BlockCollisions` has a constructor to take in a `CollisionContext` + - `BlockGetter#boxTraverseBlocks` - Returns an iterable of the positions traversed along the vector in a given bounding box. + - `CollisionGetter` + - `noCollision` - Returns whether there is no collision between the entity and blocks, entities, and liquids if the `boolean` provided is `true`. + - `getBlockAndLiquidCollisions` - Returns the block and liquid collisions of the entity within the bounding box. + - `clipIncludingBorder` - Gets the block hit result for the specified clip context, clamped by the world border if necessary. + - `EmptyBlockAndTintGetter` - A dummy `BlockAndTintGetter` instance. + - `GameType#isValidId` - Checks whether the id matches an existing game type. + - `LevelHeightAccessor#isInsideBuildHeight` - Returns whether the specified Y coordinate is within the bounds of the level. +- `net.minecraft.world.level.block` + - `Block#UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE` - A block flag that, when enabled, does not update the shape of a redstone wire. + - `BonemealableFeaturePlacerBlock` - A block that places a configured feature and can be bonemealed. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData#resetStatistics` - Resets the data of the spawn to an empty setting, but does not clear the current mobs or the next spawning entity. +- `net.minecraft.world.level.block.piston.PistonMovingBlockEntity#getPushDirection` - Returns the push direction of the moving piston. +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `getEntityInsideCollisionShape`, `$BlockStateBase#getEntityInsideCollisionShape` - Determines the voxel shape of the block when the entity is within it. + - `$Properties#overrideDescription` - Sets the translation key of the block name. + - `StateHolder` + - `getValueOrElse` - Returns the value of the property, else the provided default. + - `getNullableValue` - Returns the value of the property, or null if it does not exist. +- `net.minecraft.world.level.block.state.properties.Property#getInternalIndex` - Converts the provided boolean to a 0 when true, or 1 otherwise. +- `net.minecraft.world.level.border.WorldBorder#clampVec3ToBound` - Clamps the vector to within the world border. +- `net.minecraft.world.level.chunk` + - `ChunkAccess#canBeSerialized` - Returns true, allows the chunk to be written to disk. + - `ChunkSource#onSectionEmptinessChanged` - Updates the section when it has data. + - `LevelChunkSection` + - `copy` - Makes a shallow copy of the chunk section. + - `setUnsavedListener` - Adds a listener which takes in the chunk position whenever the chunk is marked dirty. + - `$UnsavedListener` - A consumer of a chunk position called when the chunk is marked dirty. + - `PalettedContainerRO#copy` - Creates a shallow copy of the `PalettedContainer`. + - `UpgradeData#copy` - Creates a deep copy of `UpgradeData`. +- `net.minecraft.world.level.chunk.storage.IOWorker#store` - Stores the writes of the chunk to the worker. +- `net.minecraft.world.level.levelgen` + - `SurfaceRules$Context#getSeaLevel`, `SurfaceSystem#getSeaLevel` - Gets the sea level of the generator settings. + - `WorldOptions#testWorldWithRandomSeed` - Creates a test world with a randomly generated seed. +- `net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecorator$Context#checkBlock` - Checks if the block at the given position matches the predicate. +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate` + - `getJigsaws` - Returns the jigsaw blocks that are at the provided position with the given rotation. + - `getJointType` - Returns the joint type of the jigsaw block. + - `$JigsawBlockInfo` - A record which contains the block info for a jigsaw block. + - Most methods that involve jigsaws have replaced the `$StructureBlockInfo` with a `$JigsawBlockInfo`. +- `net.minecraft.world.level.lighting.LayerLightSectionStorage#lightOnInColumn` - Returns whether there is light in the zero node section position. +- `net.minecraft.world.level.pathfinder.PathFinder#setMaxVisitedNodes` - Sets the maximum number of nodes that can be visited. +- `net.minecraft.world.level.portal` + - `DimensionTransition#withRotation` - Updates the entity's spawn rotation. + - `PortalShape#findAnyShape` - Finds a `PortalShape` that can be located at the given block position facing the specific direction. +- `net.minecraft.world.phys` + - `AABB` + - `clip` - Clips the vector inside the given bounding box, or returns an empty optional if there is no intersection. + - `collidedAlongVector` - Returns whether this box collided with one of the bounding boxes provided in the list along the provided movement vector. + - `getBottomCenter` - Gets the bottom center of the bounding box as a vector. + - `Vec3` + - `add`, `subtract` - Translates the vector and returns a new object. + - `horizontal` - Returns the horizontal components of the vector. + - `projectedOn` - Gets the unit vector representing this vector projected onto another vector. +- `net.minecraft.world.phys.shapes` + - `CollisionContext` + - `of(Entity, boolean)` - Creates a new entity collision context, where the `boolean` determines whether the entity can always stand on the provided fluid state. + - `getCollisionShape` - Returns the collision shape collided with. + - `VoxelShape#move(Vec3)` - Offsets the voxel shape by the provided vector. +- `net.minecraft.world.ticks.ScheduledTick#toSavedTick` - Converts a scheduled tick to a saved tick. + +#### List of Changes + +- `F3 + F` now toggles fog rendering +- `com.mojang.blaze3d.platform` + - `NativeImage` + - `getPixelRGBA`, `setPixelRGBA` are now private. These are replaced by `getPixel` and `setPixel`, respectively + - `getPixelsRGBA` -> `getPixels` + - `Window#updateDisplay` now takes in a `TraceyFrrameCapture`, or `null` +- `net.minecraft.Util` + - `backgroundExecutor`, `ioPool`, and `nonCriticalIoPool` now return a `TracingExecutor` instead of an `ExecutorService` + - `wrapThreadWithTaskName` -> `runNamed` with its parameters flipped and no return value +- `net.minecraft.advancements.critereon` + - `KilledByCrossbowTrigger` -> `KilledByArrowTrigger`, not one-to-one, takes in the stack in question + - `PlayerPredicate` can now match the player's input +- `net.minecraft.client` + - `Minecraft` + - `debugFpsMeterKeyPress` -> `ProfilerPieChart#profilerPieChartKeyPress` obtained via `Minecraft#getDebugOverlay` and then `DebugScreenOverlay#getProfilerPieChart` + - `getTimer` -> `getDeltaTracker` + - `getToasts` -> `getToastManager` + - `Options#setModelPart` is now public, replaces `toggleModelPart` but without broadcasting the change + - `ParticleStatus` -> `net.minecraft.server.level.ParticleStatus` +- `net.minecraft.client.animation.KeyframeAnimations#animate` now takes in a `Model` instead of a `HierarchicalModel` +- `net.minecraft.client.gui.Font` + - `drawInBatch(String, float, float, int, boolean, Matrix4f, MultiBufferSource, Font.DisplayMode, int, int, boolean)` is removed and should use the `Component` replacement + - There is also a delegate that sets the inverse depth boolean to true by default for the `Component` `drawInBatch` method + - `$StringRenderOutput` now takes in the `Font`, an optional background color, and a boolean representing if inverse depth should be use when drawing the text + - `$StringRenderOutput#finish` is now package private +- `net.minecraft.client.gui.components` + - `AbstractSelectionList` + - `replaceEntries` is now public + - `getRowTop`, `getRowBottom` is now public + - `PlayerFaceRenderer#draw(GuiGraphics, ResourceLocation, int, int, int, int)` takes in a `PlayerSkin` instead of a `ResourceLocation` +- `net.minecraft.client.gui.components.toasts` + - `Toast` + - `Toast$Visibility render(GuiGraphics, ToastComponent, long)` -> `void render(GuiGraphics, Font, long)` + - `slotCount` - `occupiedSlotCount` + - `ToastComponent` -> `ToastManager` +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` + - `render` now takes in a single integer representing the color instead of four floats and is private + - `renderChar` is the public replacement, taking in the `$GlyphInstance`, the `Matrix4f`, `VertexConsumer`, and color integer + - `$Effect` is a record, now taking in a single integer representing the color instead of four floats +- `net.minecraft.client.gui.screens` + - `LoadingOverlay#MOJANG_STUDIOS_LOGO_LOCATION` is now public + - `Screen` + - `renderBlurredBackground(float)` -> `renderBlurredBackground()` + - `wrapScreenError` -> `fillCrashDetails`, not one to one as it only adds the relevant crash information and not actually throw the error +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen#renderSlotHighlight` -> `renderSlotHighlightBack`, `renderSlotHighlightFront`, now private + - `BookEditScreen` now takes in the `WritableBookContent` + - `AbstractSignEditScreen` + - `sign` is now protected + - `renderSignBackground` no longer takes in the `BlockState` + - `EffectRenderingInventoryScreen` -> `Screen#hasActiveEffects`, `EffectsInInventory`. Not one-to-one as `EffectsInInventory` now acts as a helper class to a screen to render its effects at the specified location. +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent` + - `getHeight()` -> `getHeight(Font)` + - `renderImage` now takes in the `int` width and height of the rendering tooltip +- `net.minecraft.client.gui.screens.recipebook` + - `GhostSlots#render` no longer takes in an x and y offset. + - `RecipeBookComponent` no longer takes in an x and y offset. +- `net.minecraft.client.gui.screens.reporting.ReportReasonSelectionScreen` now takes in a `ReportType` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldScreen` + - `$DataPackReloadCookie` -> `DataPackReloadCookie` + - `openFresh` now has an overload that takes in the `CreateWorldCallback` + - `WorldCreationContext` now takes in the `InitialWorldCreationOptions` + - `WorldOpenFlows#createFreshLevel` takes in a `Function` instead of `Function` +- `net.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon` now takes in a `float` instead of an `int` to represent the alpha value +- `net.minecraft.client.multiplayer` + - `ClientLevel` now takes in an `int` representing the sea level + - `getSkyColor` now returns a single `int` instead of a `Vec3` + - `getCloudColor` now returns a single `int` instead of a `Vec3` + - `setGameTime`, `setDayTime` -> `setTimeFromServer` + - `TagCollector` -> `RegistryDataCollector$TagCollector`, now package-private +- `net.minecraft.client.player` + - `AbstractClientPlayer#getFieldOfViewModifier` now takes in a boolean representing whether the camera is in first person and a float representing the partial tick + - `Input` -> `ClientInput` and `net.minecraft.world.entity.player.Input` + - `KeyboardInput` now extends `ClientInput` + - `LocalPlayer#input` is now `ClientInput` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#getSunriseColor` -> `getSunriseOrSunsetColor` + - `GameRenderer` + - `processBlurEffect` no longer takes in the partial tick `float` + - `getFov` returns a `float` instead of a `double` + - `getProjectionMatrix` now takes in a `float` instead of a `double` + - `ItemModelShaper` + - `shapes` is now private + - `getItemModel(Item)` is removed + - `getItemModel(ResourceLocation)` - Gets the baked model associated with the provided `ResourceLocation`. + - `register` is removed + - `getModelManager` is removed + - `invalidateCache` - Clears the model map. + - `LevelRenderer` + - `renderSnowAndRain` -> `WeatherEffectRenderer` + - `tickRain` -> `tickParticles` + - `renderLevel` now takes in a `GraphicsResourceAllocator` + - `renderClouds` -> `CloudRenderer` + - `addParticle` is now public + - `globalLevelEvent` -> `LevelEventHandler` + - `entityTarget` -> `entityOutlineTarget` + - `$TransparencyShaderException` no longer takes in the throwable cause + - `SectionOcclusionGraph` + - `onSectionCompiled` -> `schedulePropagationFrom` + - `update` now takes in a `LongOpenHashSet` that holds the currently loaded section nodes + - `$GraphState` is now package-private + - `addSectionsInFrustum` now takes in a list to add the render sections to + - `ShapeRenderer#renderShape` now takes in a single integer for the color instead of four floats + - `ViewArea` + - `repositionCamera` now takes in the `SectionPos` instead of two `double`s + - `getRenderSectionAt` -> `getRenderSection` +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#renderPatterns` now takes in a `boolean` determining the glint render type to use + - `*Renderer` classes that constructed `LayerDefinition`s have now been moved to their associated `*Model` class + - `SignRenderer$SignModel` -> `SignModel` +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` now takes in a `TracingExecutor` rather than just a `Executor` + - `$CompiledSection#hasNoRenderableLayers` -> `hasRenderableLayers` + - `$RenderSection` now takes in a compiled `long` of the section node + - `setOrigin` -> `setSectionNode` + - `getRelativeOrigin` -> `getNeighborSectionNode` + - `cancelTasks` now returns nothing + - `pointOfView` - A reference to the location of where the translucent render type is rendered from. + - `resortTransparency` no longer takes in the `RenderType` and returns nothing + - `hasTranslucentGeometry` - Returns whether the compiled blocks have a translucent render type. + - `transparencyResortingScheduled` - Returns whether the last task was scheduled but not completed. + - `isAxisAlignedWith` -> `$TranslucencyPointOfView#isAxisAligned` + - `$CompileTask` is now public + - No longer `Comparable` + - The constructor no longer takes in the distance at creation + - `isHighPriority` -> `isRecompile` + - `$TranslucencyPointOfView` - Returns the coordinate representing the view point of the tranlucent render type in this section. +- `net.minecraft.client.renderer.culling.Frustum#cubeInFrustum` now returns an `int` representing the index of the first plane that culled the box +- `net.minecraft.client.renderer.DebugRenderer#render` now takes in the `Frustum` +- `net.minecraft.client.renderer.texture.atlas.sources.PalettedPermutations#loadPaletteEntryFromImage` is now private +- `net.minecraft.client.tutorial` + - `Tutorial` + - `addTimedToast`, `#removeTimedToast`, `$TimedToast` -> `TutorialToast` parameter + - `onInput` takes in a `ClientInput` instead of an `Input` + - `TutorialStepInstance` + - `onInput` takes in a `ClientInput` instead of an `Input` +- `net.minecraft.core` + - `Direction` + - `getNearest` -> `getApproximateNearest` + - `getNormal` -> `getUnitVec3i` + - `HolderGetter$Provider#get` no longer takes in the registry key, instead reading it from the `ResourceKey` + - `HolderLookup$Provider` now implements `HolderGetter$Provider` + - `asGetterLookup` is removed as the interface is a `HolderGetter$Provider` + - `listRegistries` -> `listRegistryKeys` + - `Registry` now implements `HolderLookup$RegistryLookup` + - `getTags` only returns a stream of named holder sets + - `asTagAddingLookup` -> `prepareTagReload` + - `bindTags` -> `WritabelRegistry#bindTag` + - `get` -> `getValue` + - `getOrThrow` -> `getValueOrThrow` + - `getHolder` -> `get` + - `getHolderOrThrow` -> `getOrThrow` + - `holders` -> `listElements` + - `getTag` -> `get` + - `holderOwner`, `asLookup` is removed as `Registry` is an instance of them + - `RegistryAccess` + - `registry` -> `lookup` + - `registryOrThrow` -> `lookupOrThrow` + - `RegistrySynchronization#NETWORKABLE_REGISTRIES` -> `isNetworkable` +- `net.minecraft.core.cauldron.CauldronInteraction` + - `FILL_WATER` -> `fillWaterInteraction`, now private + - `FILL_LAVA` -> `fillLavaInteraction`, now private + - `FILL_POWDER_SNOW` -> `fillPowderSnowInteraction`, now private + - `SHULKER_BOX` -> `shulkerBoxInteraction`, now private + - `BANNER` -> `bannerInteraction`, now private + - `DYED_ITEM` -> `dyedItemIteration`, now private +- `net.minecraft.core.dispenser.BoatDispenseItemBehavior` now takes in the `EntityType` to spawn rather that the variant and chest boat boolean +- `net.minecraft.core.particles.DustColorTransitionOptions`, `DustParticleOptions` now takes in integers representing an RGB value instead of `Vector3f`s. +- `net.minecraft.data.loot` + - `BlockLootSubProvider` + - `HAS_SHEARS` -> `hasShears` + - `createShearsOnlyDrop` is now an instance method + - `EntityLootSubProvider` + - `killedByFrog`, `killedByFrogVariant` now take in the getter for the `EntityType` registry + - `createSheepTable` -> `createSheepDispatchPool`, not one-to-one as the table was replaced with a pool builder given a map of dye colors to loot tables +- `net.minecraft.gametest.framework` + - `GameTestHelper#assertEntityPresent`, `assertEntityNotPresent` takes in a bounding box instead of two vectors + - `GameTestInfo#getOrCalculateNorthwestCorner` is now public +- `net.minecraft.network.chat.Component#score` now takes in a `SelectorPattern` +- `net.minecraft.network.chat.contents.ScoreContents`, `SelectorContents` is now a record +- `net.minecraft.network.protocol.login.ClientboundGameProfilePacket` -> `ClientboundLoginFinishedPacket` +- `net.minecraft.network.protocol.game` + - `ClientboundMoveEntityPacket#getyRot`, `getxRot` now returns a `float` of the degrees + - `ClientboundPlayerPositionPacket` is now a record, taking in a `PositionMoverotation` representing the change + - `relativeArguments` -> `relatives` + - `yRot`, `xRot` -> `ClientboundPalyerRotationPacket` + - `ClientboundSetTimePacket` is now a record + - `ClientboundRotateHeadPacket#getYHeadRot` now returns a `float` of the degrees + - `ClientboundTeleportEntityPacket` is now a record, where the necessary parameters are passed into the packet instead of the entity + - `ServerboundPlayerInputPacket` is now a record, taking in an `Input` +- `net.minecraft.resources.RegistryDataLoader$Loader#loadFromNetwork` now takes in a `$NetworkedRegistryData`, which contains the packed registry entries +- `net.minecraft.server` + - `MinecraftServer` no longer implements `AutoCloseable` + - `tickChildren` is now protected + - `wrapRunnable` is now public + - `ReloadableServerRegistries#reload` now takes in a list of pending tags and returns a `$LoadResult` instead of a layered registry access + - `ReloadableServerResources` + - `loadResources` now takes in a list of pending tags and the server `Executor` + - `updateRegistryTags` -> `updateStaticRegistryTags` + - `ServerFunctionLibrary#getTag`, `ServerFunctionManager#getTag` returns a list of command functions +- `net.minecraft.server.level` + - `ChunkHolder` + - `blockChanged`, `sectionLightChanged` now returns `boolean` if the information has changed + - `addSaveDependency` is now protected, a method within `GenerationChunkHolder` + - `ChunkTaskPriorityQueue` no longer takes in a generic + - The constructor no longer takes in the maximum number of tasks to do + - `submit` now takes in a `Runnable` rather than an `Optional` + - `pop` returns a `$TasksForChunk` instead of a raw `Stream` + - `ChunkTaskPriorityQueueSorter` -> `ChunkTaskDispatcher` + - `ServerPlayer` + - `teleportTo` takes in a `boolean` that determines whether the camera should be set + - `INTERACTION_DISTANCE_VERIFICATION_BUFFER` -> `BLOCK_INTERACTION_DISTANCE_VERIFICATION_BUFFER` + - Also splits into `ENTITY_INTERACTION_DISTANCE_VERIFICATION_BUFFER` set to 3.0 + - `findRespawnPositionAndUseSpawnBlock` now deals with `TeleportTransition` + - `TextFilterClient` -> `ServerTextFilter` + - `ThreadedLevelLightEngine` now takes in a `ConsecutiveExecutor` and `ChunkTaskDispatcher` instead of a `ProcessorMailbox` and a `ProcessorHandle`, respectively +- `net.minecraft.server.packs.resources.ProfiledReloadInstance$State` is now a record +- `net.minecraft.sounds.SoundEvent` is now a record +- `net.minecraft.tags` + - `TagEntry$Lookup#element` now takes in a `boolean` representing if the element is required + - `TagLoader` now takes in an `$ElementLookup`, which functions the same as its previous function parameter + - `build` now returns a value of lists + - `loadAndBuild` -> `loadTagsFromNetwork`, `loadTagsForExistingRegistries`, `loadTagsForRegistry`, `buildUpdatedLookups` + - `TagNetworkSerialization$NetworkPayload` + - `size` -> `isEmpty` + - `applyToRegistry` -> `resolve` +- `net.minecraft.util` + - `FastColor` -> `ARGB` + - `scaleRGB` overload with an alpha integer and three floats. + - `Mth#color` -> `ARGB#color` +- `net.minecraft.util.profiling.metrics.MetricCategory#MAIL_BOXES` -> `CONSECUTIVE_EXECUTORS` +- `net.minecraft.util.thread` + - `BlockableEventLoop#waitForTasks` is now protected + - `ProcessorMailbox` no longer implements `AutoCloseable` +- `net.minecraft.util.worldupdate.WorldUpgrader` implements `AutoCloseable` +- `net.minecraft.world.LockCode` now takes in an `ItemPredicate` instead of a `String` representing the item name + - `addToTag`, `fromTag` now takes in a `HolderLookup$Provider` +- `net.minecraft.world.effect` + - `MobEffect#applyEffectTick`, `applyInstantenousEffect`, `onMobRemoved`, `onMobHurt` now takes in the `ServerLevel` + - `MobEffectInstance#onMobRemoved`, `onMobHurt` now takes in the `ServerLevel` +- `net.minecraft.world.entity` + - `AgeableMob$AgeableMobGroupData` now has a public constructor + - `AnimationState#getAccumulatedTime` -> `getTimeInMillis` + - `Entity` no longer implements `CommandSource` + - `setOnGroundWithMovement` now takes in an additional `boolean` representing whether there is any horizontal collision. + - `getInputVector` is now protected + - `isAlliedTo(Entity)` -> `considersEntityAsAlly` + - `teleportTo` now takes in an additional `boolean` that determines whether the camera should be set + - `checkInsideBlocks()` -> `recordMovementThroughBlocks`, not one-to-one as it takes in the movement vectors + - `checkInsideBlocks(Set)` -> `collectBlockCollidedWith`, now private + - `kill` now takes in the `ServerLevel` + - `hurt` has been marked as deprecated, to be replaced by `hurtServer` and `hurtClient` + - `hurtOrSimulate` acts as a helper to determine which to call, also marked as deprecated + - `spawnAtLocation` now takes in a `ServerLevel` + - `isInvulnerableTo` -> `isInvulnerableToBase`, now protected and final + - `isInvulnerableTo` is moved to `LivingEntity#isInvulnerableTo` + - `teleportSetPosition` now public and takes in a `PositionMoveRotation` and `Relative` set instead of the `DimensionTransition` + - `createCommandSourceStack` -> `createCommandSourceStackForNameResolution`, not one to one as it takes in the `ServerLevel` + - `mayInteract` now takes in the `ServerLevel` instead of just the `Level` + - `setOldRot` is now public + - `changeDimension` -> `teleport`, returns `ServerPlayer` given `TeleportTransition` + - `canChangeDimensions` -> `canTeleport` + - `EntitySpawnReason#SPAWN_EGG` -> `SPAWN_ITEM_USE`, not one-to-one as this indicates the entity can be spawned from any item + - `EntityType` + - `create`, `loadEntityRecursive`, `loadEntitiesRecursive`, `loadStaticEntity` now takes in an `EntitySpawnReason` + - `*StackConfig` now takes in a `Level` instead of a `ServerLevel` + - `EquipmentTable` now has a constructor that takes in a single float representing the slot drop chance for all equipment slots + - `MobSpawnType` -> `EntitySpawnReason` + - `Leashable#tickLeash` now takes in the `ServerLevel` + - `LivingEntity` + - `getScale` is now final + - `onAttributeUpdated` is now protected + - `activeLocationDependentEnchantments` now takes in an `EquipmentSlot` + - `handleRelativeFrictionAndCalculateMovement` is now private + - `updateFallFlying` is now protected + - `onEffectRemoved` -> `onEffectsRemoved` + - `spawnItemParticles` is now public + - `getLootTable` -> `Entity#getLootTable`, wrapped in optional + - `getBaseExperienceReward` now takes in the `ServerLevel` + - `triggerOnDeathMobEffects` now takes in the `ServerLevel` + - `canAttack` is removed + - `dropEquipment` now takes in the `ServerLevel` + - `dropExperience` now takes in the `ServerLevel` + - `dropFromLootTable` now takes in the `ServerLevel` + - `actuallyHurt`, `doHurtTarget` now takes in the `ServerLevel` + - `hasLineOfSight` overload with clip contexts and a eye y supplier + - `makePoofParticles` is now public + - `Mob` + - `pickUpItem`, `wantsToPickUp` now takes in the `ServerLevel` + - `equipItemIfPossible` now takes in the `ServerLevel` + - `customServerAiStep` now takes in the `ServerLevel` + - `dropPreservedEquipment` now takes in the `ServerLevel` + - `NeutralMob` + - `isAngryAt`, `isAngryAtAllPlayers` now takes in the `ServerLevel` + - `playerDied` now takes in the `ServerLevel` + - `PortalProcessor#getPortalDestination` now returns a `TeleportTransition` + - `PositionMoveRotation` + - `of(ClientboundPlayerPositionPacket)` -> `ofEntityUsingLerpTarget(Entity)` + - `of(DimensionTransition)` -> `of(TeleportTransition)` + - `Shearable#shear` now takes in the `ServerLevel` and `ItemStack` that is shearing the entity + - `RelativeMovement` -> `Relative`, expanded to contain delta movement + - `WalkAnimationState#update` now takes in an additional `float` representing the position scale when moving. +- `net.minecraft.world.entity.ai.behavior` + - `StartAttacking` now takes in a `$TargetFinder` and additionally a `$StartAttackingCondition` + - Both are functional interfaces that replace the previous functions/predicates, though with an extra `ServerLevel` parameter + - `StopAttackingIfTargetInvalid` now takes in a `$TargetErasedCallback` and/or a `$StopAttackCondition` + - Both are functional interfaces that replace the previous consumers/predicates, though with an extra `ServerLevel` parameter + - `MeleeAttack#create` can now take in a predicate to test the mob for + - `Swim` now takes in a generic representing the mob +- `net.minecraft.world.entity.ai.control.LookControl#rotateTowards` -> `Control#rotateTowards` +- `net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal` now takes in a `$Selector` + - It is a functional interface that replaces the previous predicate, though with an extra `ServerLevel` parameter +- `net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities` now takes in a `ServerLevel` +- `net.minecraft.world.entity.ai.sensing` + - `NearestLivingEntitySensor` + - `radiusXZ`, `radiusY` -> `Attributes#FOLLOW_RANGE` + - `isMatchingEntity` now takes in a `ServerLevel` + - `Sensor` + - `TARGETING_RANGE` is now private + - `isEntityTargetable`, `isEntityAttackable`, `isEntityAttackableIgnoringLineOfSight` now take in a `ServerLevel` + - `wasEntityAttackableLastNTicks`, `rememberPositives` now delas with `BiPredicate`s instead of `Predicate`s +- `net.minecraft.world.entity.ai.targeting.TargetingConditions` + - `selector` now takes in a `$Selector` + - It is a functional interface that replaces the previous predicate, though with an extra `ServerLevel` parameter + - `test` now takes in a `ServerLevel` +- `net.minecraft.world.entity.ai.village.poi.PoiRecord#codec`, `PoiSection#codec` -> `$Packed#CODEC` +- `net.minecraft.world.entity.animal` + - `Fox$Type` -> `$Variant` + - `MushroomCow$MushroomType` -> `$Variant` + - `$Variant` no longer takes in the loot table + - `Salmon` now has a variant for its size + - `Wolf` + - `getBodyRollAngle` -> `#getShakeAnim`, not one-to-one as the angle is calculated within the render state + - `hasArmor` is removed +- `net.minecraft.world.entity.animal.horse.AbstractHorse#followMommy` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.enderdragon.EnderDragon#onCrystalDestroyed` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.enderdragon.phases.DragonPhaseInstance#doServerTick` now takes in a `ServerLevel` +- `net.minecraft.world.entity.boss.wither.WitherBoss#getHead*Rot` -> `getHead*Rots`, returns all rotations rather than just the provided index +- `net.minecraft.world.entity.decoration` + - `ArmorStand` default rotations are now public + - `isShowArms` -> `showArms` + - `isNoBasePlate` -> `showBasePlate` + - `PaintingVariant` now takes in a title and author `Component` +- `net.minecraft.world.entity.item.ItemEntity#getSpin` is now static +- `net.minecraft.world.entity.monster.Monster#isPreventingPlayerRest` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.breeze.Breeze#getSnoutYPosition` -> `getFiringYPosition` +- `net.minecraft.world.entity.monster.hoglin.HoglinBase#hurtAndThrowTarget` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.piglin.PiglinAi#isWearingGold` -> `#isWearingSafeArmor` +- `net.minecraft.world.entity.npc.InventoryCarrier#pickUpItem` now takes in a `ServerLevel` +- `net.minecraft.world.entity.player` + - `Player#disableShield` now takes in the stack to apply the cooldown to + - `Inventory` + - `findSlotMatchingUnusedItem` -> `findSlotMatchingCraftingIngredient` + - `swapPaint` -> `setSelectedHotbarSlot` + - `StackedContents` -> `StackedItemContents` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow#inGround` -> `IN_GROUND`, now an `EntityDataAccessor` + - Protected accessible via `isInGround` and `setInGround` + - `ThrowableItemProjectile` can now take in an `ItemStack` of the item thrown +- `net.minecraft.world.entity.raid.Raid#getLeaderBannerInstance` -> `getOminousBannerInstance` +- `net.minecraft.world.entity.vehicle` + - `Boat$Type` now takes in the supplied boat item and the translation key for the item, but no longer take in the planks they are made from + - `ContainerEntity` + - `*LootTable*` -> `ContainerLootTable` + - `chestVehicleDestroyed` now takes in a `ServerLevel` + - `VehicleEntity` + - `destroy` now takes in a `seerverLevel` + - `getDropItem` is now protected +- `net.minecraft.world.item` + - `BoatItem` now takes in an `EntityType` instead of the variant and chest boolean + - `ItemStack#hurtEnemy`, `postHurtEnemy` now take in a `LivingEntity` instead of a `Player` + - `SmithingTemplateItem` now takes in the `Item.Properties` instead of hardcoding it, also true for static initializers + - `UseAnim` -> `ItemUseAnimation` +- `net.minecraft.world.item.crafting.ShulkerBoxColoring` -> `TransmuteRecipe`, expanded to copy any data stored on the item to the result item +- `net.minecraft.world.item.enchantment.EnchantmentHelper` + - `onProjectileSpawned` now takes in a `Projectile` instead of an `AbstractArrow` +- `net.minecraft.world.item.enchantment.effects.DamageItem` -> `ChangeItemDamage` +- `net.minecraft.world.level` + - `GameRules` takes in a `FeatureFlagSet` during any kind of construction + - `$IntegerValue#create` takes in a `FeatureFlagSet` + - `$Type` takes in a `FeatureFlagSet` + - `Level` + - `setSpawnSettings` no longer takes in a `boolean` to determine whether to spawn friendlies + - `getGameRules` -> `ServerLevel#getGameRules` + - `LevelAccessor` now implements `ScheduledTickAccess`, an interface that now contains the tick scheduling methods that were originally on `LevelAccessor` + - `neighborShapeChanged` switches the order of the `BlockState` and neighbor `BlockPos` parameters + - `LevelHeightAccessor` + - `getMinBuildHeight` -> `getMinY` + - `getMaxBuildHeight` -> `getMaxY`, this value is one less than the previous version + - `getMinSection` -> `getMinSectionY` + - `getMaxSection` -> `getMaxSectionY`, this value is one less than the previous version + - `NaturalSpawner#spawnForChunk` has been split into two methods: `getFilteredSpawningCategories`, and `spawnForChunk` +- `net.minecraft.world.level.biome#Biome#getPrecipitationAt`, `coldEnoughToSnow`, `warmEnoughToRain`, `shouldMeltFrozenOceanIcebergSlightly` now takes in an `int` representing the the base height of the biome +- `net.minecraft.world.level.block` + - `Block` + - `shouldRenderFace` takes in the relative state for the face being checked, no longer passing in the `BlockGetter` or `BlockPos`s. + - `updateEntityAfterFallOn` -> `updateEntityMovementAfterFallOn` + - `$BlockStatePairKey` -> `FlowingFluid$BlockStatePairKey`, now package private + - `getDescriptionId` -> `BlockBehaviour#getDescriptionId`, also a protected field `descriptionId` + - `ChestBlock` constructor switched its parameter order + - `Portal#getPortalDestination` now returns `TeleportTransition` +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity#serverTick` now takes in a `ServerLevel` instead of a `Level` + - `BrushableBlockEntity` + - `brush` now takes in the level and stack performing the brushing behavior + - `unpackLootTable` is now private + - `checkReset` now takes in the server level +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `getOcclusionShape`, `getLightBlock`, `propagatesSkylightDown` only takes in the `BlockState`, not the `BlockGetter` or `BlockPos` + - `getLootTable` now returns an `Optional`, also a protected field `drops` + - `$BlockStateBase#getOcclusionShape`, `getLightBlock`, `getFaceOcclusionShape`, `propagatesSkylightDown`, `isSolidRender` no longer takes in the `BlockGetter` or `BlockPos` + - `$BlockStateBase#getOffset` no longer takes in the `BlockGetter` + - `$OffsetFunction#evaluate` no longer takes in the `BlockGetter` + - `$Properties#dropsLike` -> `overrideLootTable` + - `StateHolder#findNextInCollection` now takes in a `List` instead of a `Collection` +- `net.minecraft.world.level.chunk` + - `ChunkAccess` + - `addPackedPostProcess` now takes in a `ShortList` instead of a single `short` + - `getTicksForSerialization` now takes in a `long` of the game time + - `unsaved` is now private + - `setUnsaved` -> `markUnsaved`, `tryMarkSaved` + - `$TicksToSave` -> `$PackedTicks` + - `ChunkSource#setSpawnSettings` no longer takes in a `boolean` to determine whether to spawn friendlies + - `LevelChunk#postProcessGeneration` now takes in a `ServerLevel` + - `Palette#copy` now takes in a `PaletteResize` +- `net.minecraft.world.level.chunk.status.WorldGenContext` now takes in an `Executor` or the main thread rather than a processor handle mail box + - The construtor also takes in a `LevelChunk$UnsavedListener` for when a chunk is marked as dirty +- `net.minecraft.world.level.chunk.storage` + - `ChunkSerializer` -> `SerializableChunkData` + - `ChunkStorage#write` now takes in a supplied `CompoundTag` instead of the instance itself + - `SectionStorage` now takes in a second generic representing the packed form of the storage data + - The constructor now takes in the packed codec, a function to convert the storage to a packed format, and a function to convert the packed and dirty runnable back into the storage. +- `net.minecraft.world.level.levelgen` + - `Aquifer$FluidStatus` is now a record + - `WorldDimensions#withOverworld` now takes in a `HolderLookup` instead of the `Registry` itself + - `BlendingData` now has a packed and unpacked state for serializing the interal data as a simple object +- `net.minecraft.world.level.levelgen.material.MaterialRuleList` now takes in an array instead of a list +- `net.minecraft.world.level.levelgen.placement.PlacementContext#getMinBuildHeight` -> `getMinY` +- `net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement#getShuffledJigsawBlocks` now returns a `StructureTemplate$JigsawBlockInfo` +- `net.minecraft.world.level.lighting` + - `LevelLightEngine#lightOnInSection` -> `lightOnInColumn` + - `LightEngine` + - `hasDifferentLightProperties`, `getOcclusionShape` no longer takes in the `BlockGetter` or `BlockPos` + - `getOpacity` no longer takes in the `BlockPos` + - `shapeOccludes` no longer takes in the two `longs` representing the packed positions +- `net.minecraft.world.level.material` + - `FlowingFluid` + - `spread` now takes in the `BlockState` at the current position + - `getSlopeDistance` previous parameters have been merged into a `$SpreadContext` object + - `spread`, `getNewLiquid`, `canConvertToSource`, `getSpread` now takes in a `ServerLevel` + - `Fluid` + - `tick` now takes in the `BlockState` at the current position + - `tick` and `randomTick` now take in the `ServerLevel` + - `FluidState` + - `tick` now takes in the `BlockState` at the current position + - `tick` and `randomTick` now take in the `ServerLevel` + - `MapColor#calculateRGBColor` -> `calculateARGBColor` +- `net.minecraft.world.level.portal` + - `DimensionTransition` -> `TeleportTransition` + - `pos` -> `position` + - `speed` -> `deltaMovement` + - The constructor can now take in a set of `Relatives` to indicate in what motions should the positions be moved relative to another + - `PortalShape#createPortalBlocks` now takes in a `LevelAccessor` +- `net.minecraft.world.level.saveddata.SavedData#save(File, HolderLookup$Provider)` now returns `CompoundTag`, not writing the data to file in the method +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` now implements `AutoCloseable` + - The constructor takes in a `Path` instead of a `File` + - `save` -> `scheduleSave` and `saveAndJoin` + - `LevelData#getGameRules` -> `ServerLevelData#getGameRules` +- `net.minecraft.world.phys.BlockHitResult` now takes in a boolean representing if the world border was hit + - Adds in two helpers `hitBorder`, `isWorldBorderHit` +- `net.minecraft.world.ticks` + - `ProtoChunkTicks#load` now takes in a list of saved ticks + - `SavedTick#loadTickList` now returns a list of saved ticks, rather than consuming them + - `SerializableTickContainer#save` -> `pack` + +#### List of Removals + +- `com.mojang.blaze3d.Blaze3D` + - `process` + - `render` +- `com.mojang.blaze3d.pipeline.RenderPipeline` + - Replaced by `com.mojang.blaze3d.framegraph.*` and `com.mojang.blaze3d.resources.*` +- `com.mojang.blaze3d.platform.NativeImage` + - `setPixelLuminance` + - `getRedOrLuminance`, `getGreenOrLuminance`, `getBlueOrLuminance` + - `blendPixel` + - `asByteArray` +- `com.mojang.blaze3d.systems.RenderSystem` + - `glGenBuffers` + - `glGenVertexArrays` + - `_setShaderTexture` + - `applyModelViewMatrix` +- `net.minecraft.Util#wrapThreadWithTaskName(String, Supplier)` +- `net.minecraft.advancements.critereon.EntitySubPredicates#BOAT` +- `net.minecraft.client.Options#setKey` +- `net.minecraft.client.gui.screens.inventory.EnchantmentScreen#time` +- `net.minecraft.client.multiplayer` + - `ClientCommonPacketListenerImpl#strictErrorHandling` + - `ClientLevel#isLightUpdateQueueEmpty` + - `CommonListenerCookie#strictErrorHandling` +- `net.minecraft.client.particle.ParticleRenderType#PARTICLE_SHEET_LIT` +- `net.minecraft.client.renderer` + - `GameRenderer#resetProjectionMatrix` + - `LevelRenderer` + - `playJukeboxSong` + - `clear` + - `PostChain` + - `getTempTarget`, `addTempTarget` + - `PostPass` + - `setOrthoMatrix` + - `getFilterMode` +- `net.minecraft.client.renderer.block.model.BlockModel#fromString` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture#blur`, `mipmap` + - `TextureManager#bindForSetup` +- `net.minecraft.commands.arguments.coordinates.WorldCoordinates#current` +- `net.minecraft.core` + - `Direction#fromDelta` + - `Registry#getOrCreateTag`, `getTagNames`, `resetTags` +- `net.minecraft.server.MinecraftServer` + - `isSpawningAnimals` + - `areNpcsEnabled` +- `net.minecraft.server.level` + - `GenerationChunkHolder#getGenerationRefCount` + - `ServerPlayer` + - `setPlayerInput` + - `teleportTo(ServerLevel, double, double, double, float, float, boolean)` +- `net.minecraft.tags` + - `TagManager` + - `TagManagerSerialization$TagOutput` +- `net.minecraft.world.entity` + - `AnimationState#updateTime` + - `Entity` + - `walkDist0`, `walkDist` + - `wasOnFire` + - `tryCheckInsideBlocks` + - `EntitySelector$MobCanWearArmorEntitySelector` +- `net.minecraft.world.entity.ai.sensing` + - `BreezeAttackEntitySensor#BREEZE_SENSOR_RADIUS` + - `TemptingSensor#TEMPTATION_RANGE` +- `net.minecraft.world.entity.animal` + - `Cat#getTextureId` + - `Squid#setMovementVector` + - `Wolf#isWet` +- `net.minecraft.world.entity.boss.dragon.EnderDragon` + - `getLatencyPos` + - `getHeadPartYOffset` +- `net.minecraft.world.entity.monster.Zombie#supportsBreakDoorGoal` +- `net.minecraft.world.entity.npc.Villager#setChasing`, `isChasing` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow#shotFromCrossbow` + - `ThrowableProjectile(EntityType, LivingEntity, Level)` +- `net.minecraft.world.item` + - `BannerPatternItem#getDisplayName` + - `ItemStack#LIST_STREAM_CODEC` +- `net.minecraft.world.level.BlockGetter#getMaxLightLevel` +- `net.minecraft.world.level.block.entity.JigsawBlockEntity$JointType#byName` +- `net.minecraft.world.level.block.state.BlockBehaviour#isOcclusionShapeFullBlock` +- `net.minecraft.world.level.chunk.ChunkAccess#setBlendingData` +- `net.minecraft.world.level.storage.loot.LootDataType#deserialize` +- `net.minecraft.world.phys.AABB#getBottomCenter` +- `net.minecraft.world.phys.shapes.Shapes#getFaceShape` +- `net.minecraft.world.ticks.SavedTick#saveTick` + +### Step 2: 1.21.2/3 -> 1.21.4 + +## Minecraft 1.21.2/3 -> 1.21.4 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.2/3 to 1.21.4. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +### 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](https://misode.github.io/versions/?id=1.21.4&tab=changelog). + +### Client Items + +Minecraft has moved the lookup and definition of how an item should be rendered to its own data generated system, which will be referred to as **Client Items**, located at `assets//items/.json`. Client Items is similar to the block state model definition, but has the potential to have more information enscribed in the future. Currently, it functions as simply a linker to the models used for rendering. + +All client items contain some `ItemModel$Unbaked` using the `model` field. Each unbaked model has an associated type, which defines how the item should be set up for rendering, or rendered in one specific case. These `type`s can be found within `ItemModels`. This primer will review all but one type, as that unbaked model type is specifically for bundles when selecting an item. + +The item also contains a `properties` field which holds some metadata-related parameters. Currently, it only specifies a boolean that, when false, make the hand swap the currently held item instantly rather than animate the hand coming up. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "" // Set type here + // Add additional parameters + }, + "properties": { + // When false, disables animation when swapping this item into the hand + "hand_animation_on_swap": false + } +} +``` + +#### A Basic Model + +The basic model definition is handled by the `minecraft:model` type. This contains two fields: `model`, to define the relative location of the model JSON, and an optional list of `tints`, to define how to tint each index. + +`model` points to the model JSON, relative to `assets//models/.json`. In most instances, a client item defintion will look something like this: + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:model", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item" + } +} +``` + +##### Tint Sources + +In model JSONs, some element faces will have a `tintindex` field which references some index into the `tints` list in the `minecraft:model` unbaked model type. The list of tints are `ItemTintSource`s, which are all defined in `net.minecraft.client.color.item.*`. All defined tint sources can be found within `ItemTintSources`, like `minecraft:constant` for a constant color, or `minecraft:dye`, to use the color of the `DataComponents#DYED_COLOR` or default if not present. All tint sources must return an opaque color, though all sources typically apply this by calling `ARGB#opaque`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:model", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item", + // A list of tints to apply + "tints": [ + { + // For when tintindex: 0 + "type": "minecraft:constant", + // 0x00FF00 (or pure green) + "value": 65280 + }, + { + // For when tintindex: 1 + "type": "minecraft:dye", + // 0x0000FF (or pure blue) + // Only is called if `DataComponents#DYED_COLOR` is not set + "default": 255 + } + ] + } +} +``` + +To create your own `ItemTintSource`, you need to implement the `calculate` method register the `MapCodec` associated for the `type` field. `calculate` takes in the current `ItemStack`, level, and holding entity and returns an RGB integer with an opaque alpha, defining how the layer should be tinted. + +Then, the `MapCodec` needs to be registered to `ItemTintSources#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The item source class +public record FromDamage(int defaultColor) implements ItemTintSource { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + ExtraCodecs.RGB_COLOR_CODEC.fieldOf("default").forGetter(FromDamage::defaultColor) + ).apply(instance, FromDamage::new) + ); + + public FromDamage(int defaultColor) { + this.defaultColor = ARGB.opaque(defaultColor); + } + + @Override + public int calculate(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity) { + return stack.isDamaged() ? ARGB.opaque(stack.getBarColor()) : defaultColor; + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where ItemTintSources#ID_MAPPER is exposed +ItemTintSources.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "from_damage"), + // The map codec + FromDamage.MAP_CODEC +); +``` + +```json5 +// For some object in the 'tints' array +{ + "type": "examplemod:from_damage", + // 0x0000FF (or pure blue) + // Only is called if the item has not been damaged yet + "default": 255 +} +``` + +#### Ranged Property Model + +Ranged property models, as defined by the `minecraft:range_dispatch` unbaked model type, are the most similar to the previous item override system. Essentially, the type defines some item property that can be scaled along with a list of thresholds and associated models. The model chosen is the one with the closest threshold value that is not over the property (e.g. if the property value is `4` and we have thresholds `3` and `5`, `3` would be chosen as it is the cloest without going over). The item property is defined via a `RangeSelectItemModelProperty`, which takes in the stack, level, entity, and some seeded value to get a float, usually scaled betwen 0 and 1 depending on the implementation. All properties can be found within `net.minecraft.client.renderer.item.properties.numeric.*` and are registered in `RangeSelectItemModelProperties`, such as `minecraft:cooldown`, for the cooldown percentage, or `minecraft:count`, for the current number of items in the stack or percentage of the max stack size when normalized. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:range_dispatch", + + // The `RangeSelectItemModelProperty` to use + "property": "minecraft:count", + // A scalar to multiply to the computed property value + // If count was 0.3 and scale was 0.2, then the threshold checked would be 0.3*0.2=0.06 + "scale": 1, + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `Count` ~~ + // When true, normalizes the count using its max stack size + "normalize": true, + + // ~~ Entries with threshold information ~~ + "entries": [ + { + // When the count is a third of its current max stack size + "threshold": 0.33, + "model": { + // Can be any unbaked model type + } + }, + { + // When the count is two thirds of its current max stack size + "threshold": 0.66, + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +To create your own `RangeSelectItemModelProperty`, you need to implement the `get` method register the `MapCodec` associated for the `type` field. `get` takes in the stack, level, entity, and seeded value and returns an arbitrary float to be interpreted by the ranged dispatch model. + +Then, the `MapCodec` needs to be registered to `RangeSelectItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The ranged property class +public record AppliedEnchantments() implements RangeSelectItemModelProperty { + + public static final MapCodec MAP_CODEC = MapCodec.unit(new AppliedEnchantments()); + + @Override + public float get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { + return (float) stack.getEnchantments().size(); + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where RangeSelectItemModelProperties#ID_MAPPER is exposed +RangeSelectItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "applied_enchantments"), + // The map codec + AppliedEnchantments.MAP_CODEC +); +``` + +```json5 +// For some client item in 'model' +{ + "type": "minecraft:range_dispatch", + + // The `RangeSelectItemModelProperty` to use + "property": "examplemod:applied_enchantments", + // A scalar to multiply to the computed property value + "scale": 0.5, + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `AppliedEnchantments` ~~ + // N/A (no arguments to constructor) + + // ~~ Entries with threshold information ~~ + "entries": [ + { + // When there is one enchantment present + // Since 1 * the scale 0.5 = 0.5 + "threshold": 0.5, + "model": { + // Can be any unbaked model type + } + }, + { + // When there are two enchantments present + "threshold": 1, + "model": { + // Can be any unbaked model type + } + } + ] +} +``` + +#### Select Property Model + +Select property models, as defined by the `minecraft:select` unbaked model type, are functionally similar to ranged property models, except now it switches on some property, typically an enum. The item property is defined via a `SelectItemModelProperty`, which takes in the stack, level, entity, some seeded value, and the current display context to get one of the property values. All properties can be found within `net.minecraft.client.renderer.item.properties.select.*` and are registered in `SelectItemModelProperties`, such as `minecraft:block_state`, for the stringified value of a specified block state property, or `minecraft:display_context`, for the current `ItemDisplayContext`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:select", + + // The `SelectItemModelProperty` to use + "property": "minecraft:display_context", + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `DisplayContext` ~~ + // N/A (no arguments to constructor) + + // ~~ Switch cases based on Selectable Property ~~ + "cases": [ + { + // When the display context is `ItemDisplayContext#GUI` + "when": "gui", + "model": { + // Can be any unbaked model type + } + }, + { + // When the display context is `ItemDisplayContext#FIRST_PERSON_RIGHT_HAND` + "when": "firstperson_righthand", + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +To create your own `SelectItemModelProperty`, you need to implement the `get` method register the `SelectItemModelProperty$Type` associated for the `type` field. `get` takes in the stack, level, entity, seeded value, and display context and returns an encodable object to be interpreted by the select model. + +Then, the `MapCodec` needs to be registered to `SelectItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The select property class +public record StackRarity() implements SelectItemModelProperty { + + public static final SelectItemModelProperty.Type TYPE = SelectItemModelProperty.Type.create( + // The map codec for this property + MapCodec.unit(new StackRarity()), + // The codec for the object being selected + Rarity.CODEC + ); + + @Nullable + @Override + public Rarity get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext displayContext) { + // When null, uses the fallback model + return stack.get(DataComponents.RARITY); + } + + @Override + public SelectItemModelProperty.Type type() { + return TYPE; + } +} + +// Then, in some initialization location where SelectItemModelProperties#ID_MAPPER is exposed +SelectItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "rarity"), + // The property type + StackRarity.TYPE +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:select", + + // The `SelectItemModelProperty` to use + "property": "examplemod:rarity", + "fallback": { + // The fallback model to use if no threshold matches + // Can be any unbaked model type + "type": "minecraft:model", + "model": "examplemod:item/example_item" + }, + + // ~~ Properties defined by `StackRarity` ~~ + // N/A (no arguments to constructor) + + // ~~ Switch cases based on Selectable Property ~~ + "cases": [ + { + // When rarity is `Rarity#UNCOMMON` + "when": "uncommon", + "model": { + // Can be any unbaked model type + } + }, + { + // When rarity is `Rarity#RARE` + "when": "rare", + "model": { + // Can be any unbaked model type + } + } + ] + } +} +``` + +#### Conditional Property Model + +Conditional property models, as defined by the `minecraft:condition` unbaked model type, are functionally similar to ranged property models, except now it switches on boolean. These are usually combined with range dispatch, such as when pulling the bow. The item property is defined via a `ConditionalItemModelProperty`, which takes in the stack, level, entity, some seeded value, and the current display context to get a true of false statement. All properties can be found within `net.minecraft.client.renderer.item.properties.conditional.*` and are registered in `ConditionalItemModelProperties`, such as `minecraft:damaged`, for if the item is damaged, or `minecraft:has_component`, if it has a given data component. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:condition", + + // The `SelectItemModelProperty` to use + "property": "minecraft:damaged", + + // ~~ Properties defined by `Damaged` ~~ + // N/A (no arguments to constructor) + + // ~~ What the boolean outcome is ~~ + "on_true": { + // Can be any unbaked model type + }, + "on_false": { + // Can be any unbaked model type + } + } +} +``` + +To create your own `ConditionalItemModelProperty`, you need to implement the `get` method register the `MapCodec` associated for the `type` field. `get` takes in the stack, level, entity, seeded value, and display context and returns a boolean to be interpreted by `on_true` and `on_false`, respectively. + +Then, the `MapCodec` needs to be registered to `ConditionalItemModelProperties#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +```java +// The predicate property class +public record TimePeriod(int month, MinMaxBounds.Ints dates, boolean enabled) implements ConditionalItemModelProperty { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + Codec.intRange(1, 12).fieldOf("month").forGetter(TimePeriod::month), + MinMaxBounds.Ints.CODEC.fieldOf("dates").forGetter(TimePeriod::dates) + ).apply(instance, TimePeriod::new) + ); + + public TimePeriod(int month, MinMaxBounds.Ints dates) { + this.month = month; + this.dates = dates; + + Calendar cal = Calendar.getInstance(); + this.enabled = cal.get(Calendar.MONTH) + 1 == this.month + && this.dates.matches(cal.get(Calendar.DATE)); + } + + @Override + public boolean get(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed, ItemDisplayContext context) { + return this.enabled; + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } +} + +// Then, in some initialization location where ConditionalItemModelProperties#ID_MAPPER is exposed +ConditionalItemModelProperties.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "time_period"), + // The map codec + TimePeriod.MAP_CODEC +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:condition", + + // The `SelectItemModelProperty` to use + "property": "examplemod:time_period", + + // ~~ Properties defined by `TimePeriod` ~~ + // Month of July + "month": 7, + "dates": { + // Between July 1st - 14th + "min": 1, + "max": 14 + }, + + // ~~ What the boolean outcome is ~~ + "on_true": { + // Can be any unbaked model type + }, + "on_false": { + // Can be any unbaked model type + } + } +} +``` + +#### Composite Model + +Composite models, defined by `minecraft:composite`, are essentially a combination of other model types to render. Specifically, this sets up multiple players to overlay models on top of one another when rendering. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:composite", + + // Will render in the order they appear in the list + "models": [ + { + // Can be any unbaked model type + }, + { + // Can be any unbaked model type + } + ] + } +} +``` + +#### Special Dynamic Models + +Special dynamic models, as defined by the `minecraft:special` unbaked model type, are the new system for block entity without level renderers (e.g., chests, banners, and the like). Instead of storing a baked model, these provide a render method to call. The special model wrapper takes in a base model used for grabbing the basic model settings (not the elements) and a `SpecialModelRenderer`. All special model renderers can be found within `net.minecraft.client.renderer.special.*` and are registered in `SpecialModelRenderers`. + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:special", + + // The model to read the particle texture and display transformation from + "base": "minecraft:item/template_skull", + "model": { + // The special model renderer to use + "type": "minecraft:head", + + // ~~ Properties defined by `SkullSpecialRenderer.Unbaked` ~~ + // The type of the skull block + "kind": "wither_skeleton" + } + } +} +``` + +To create your own `SpecialModelRenderer`, you need to implement both the renderer and the `$Unbaked` model to read the data from the JSON. The `$Unbaked` model creates the `SpecialModelRenderer` via `bake` and is registered using a `MapCodec` for its `type`. The `SpecialModelRenderer` then extracts the necessary data from the stack needed to render via `extractArgument` and passes that to the `render` method. If you do not need any information from the stack, you can implement `NoDataSpecialModelRenderer` instead. + +Then, the `MapCodec` needs to be registered to `SpecialModelRenderers#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. + +If your item is a held block, it also needs to be added to the `SpecialModelRenderers#STATIC_BLOCK_MAPPING` for specific rendering scenarios via `BlockRenderDispatcher#renderSingleBLock` (e.g. in minecart, or picked up by endermen). Both the default model renderer and the special model renderer are called in this method; allowing for both the static block model and the dynamic special model to be rendered at the same time. As this map is immutable, you will either need to replace it or hook into `SpecialBlockModelRenderer` and somehow add to the stored map there. + +```java +// The special renderer +public record SignSpecialRenderer(WoodType defaultType, Model model) implements SpecialModelRenderer { + + // Render the model + @Override + public void render(@Nullable WoodType type, ItemDisplayContext displayContext, PoseStack pose, MultiBufferSource bufferSource, int light, int overlay, boolean hasFoil) { + VertexConsumer consumer = Sheets.getSignMaterial(type).buffer(bufferSource, this.model::renderType); + this.model.renderToBuffer(pose, consumer, light, overlay); + } + + // Get the wood type from the stack + @Nullable + @Override + public WoodType extractArgument(ItemStack stack) { + return (stack.getItem() instanceof BlockItem item && item.getBlock() instanceof SignBlock sign) + ? sign.type() : this.defaultType; + } + + // The model to read the json from + public static record Unbaked(WoodType defaultType) implements SpecialModelRenderer.Unbaked { + + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + WoodType.CODEC.fieldOf("default").forGetter(SignSpecialRenderer.Unbaked::defaultType) + ).apply(instance, SignSpecialRenderer.Unbaked::new) + ); + + // Create the special model renderer, or null if it fails + @Nullable + @Override + public SpecialModelRenderer bake(EntityModelSet modelSet) { + return new SignSpecialRenderer( + this.defaultType, + SignRenderer.createSignModel(modelSet, defaultType, true) + ) + } + + @Overrides + public MapCodec type() { + return MAP_CODEC; + } + } +} + +// Then, in some initialization location where SpecialModelRenderers#ID_MAPPER is exposed +SpecialModelRenderers.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "sign"), + // The map codec + SignSpecialRenderer.Unbaked.MAP_CODEC +); +// Let assume we can add directly to SpecialModelRenderers#STATIC_BLOCK_MAPPING as well +// We'll have a Block EXAMPLE_SIGN +SpecialModelRenderers.STATIC_BLOCK_MAPPING.put( + // The block with a special rendering as an item + EXAMPLE_SIGN, + // The unbaked renderer to use + new SignSpecialRenderer.Unbaked(WoodType.BAMBOO) +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "minecraft:special", + + // The model to read the particle texture and display transformation from + "base": "minecraft:item/bamboo_sign", + "model": { + // The special model renderer to use + "type": "examplemod:sign", + + // ~~ Properties defined by `SignSpecialRenderer.Unbaked` ~~ + // The default wood type if none can be found + "default": "bamboo" + } + } +} +``` + +#### Rendering an Item + +Rendering an item is now done through the `ItemModelResolver` and `ItemStackRenderState`. This is similar to how the `EntityRenderState` works: first, the `ItemModelResolver` sets up the `ItemStackRenderState`, then the state is rendered via `ItemStackRenderState#render`. + +Let's start with the `ItemStackRenderState`. For rendering, the only one we care about the following methods: `isEmpty`, `isGui3d`, `usesBlockLight`, `transform`, and `render`. `isEmpty` is used to determine whether the stack should render at all. Then `isGui3d`, `usesBlockLight`, and `transform` are used in their associated contexts to properly position the stack to render. Finally, `render` takes in the pose stack, buffer source, packed light, and overlay texture to render the item in its appropriate location. + +`ItemModelResolver` is responsible for setting the information on the `ItemStackRenderState` needed to render. This is done through `updateForLiving` for items held by living entities, `updateForNonLiving` for items held by other kinds of entities, and `updateforTopItem`, for all other scenarios. `updateForItem`, which the previous two methods delegate to, take in the render state, the stack, the display context, if the stack is in the left hand, the level, the entity, and some seeded value. This will effectively clear the previous state via `ItemStackRenderState#clear` and then set up the new state via a delegate to `ItemModel#update`. The `ItemModelResolver` can always be obtained via `Minecraft#getItemModelResolver`, if you are not within a renderer context (e.g., block entity, entity). + +```java +// In its most simple form, assuming you are not doing any transformations (which you should as necessary) +public class ExampleRenderer { + private final ItemStackRenderState state = new ItemStackRenderState(); + + public void render(ItemStack stack, Level level, PoseStack pose, MultiBufferSource bufferSource) { + // First update the render state + Minecraft.getInstance().getItemModelResolver().updateForTopItem( + // The render state + this.state, + // The stack to update the state with + stack, + // The display context to render within + ItemDisplayContext.NONE, + // Whether it is in the left hand of the entity (use false when unknown) + false, + // The current level (can be null) + level, + // The holding entity (can be null) + null, + // An arbitrary seed value + 0 + ); + + // Perform any desired transformations here + + // Then render the state + this.state.render( + // The pose stack with the required transformations + pose, + // The buffer sources + bufferSource, + // The packed light value + LightTexture.FULL_BRIGHT, + // The overlay texture value + OverlayTexture.NO_OVERLAY + ); + } +} +``` + +#### Custom Item Model Defintions + +To make a custom item model definition, we need to look at a few more methods in `ItemStackRenderState` which, although you won't typically use, is useful to understand: `ensureCapacity` and `newLayer`. Both of these are responsible for ensuring there are enough `ItemStackRenderState$LayerRenderState`s if you happen to be overlaying multiple models at once. Effectively, every time you are planning to render something in an unbaked model, `newLayer` should be called. If you plan on rendering multiple things on top of one another, then `ensureCapacity` should be set with the number of layers that you plan to render before calling `newLayer`. + +An item model definition is made up of the `ItemModel`, which functionally defines a 'baked model' and its `ItemModel$Unbaked`, used for serialization. + +The unbaked variant has two methods: `bake`, which is used to create the `ItemModel`, and `type`, which references the `MapCodec` to be registered to `ItemModels#ID_MAPPER`, though this field is private by default, so some access changes or reflection needs to be applied. `bake` takes in the `$BakingContext`, which contains the `ModelBaker` to get `BakedModel`s, the `EntityModelSet` for entity models, and the missing `ItemModel`. + +The baked variant only has one method `update`, which is responsible for setting up everything necessary on the `ItemStackRenderState`. The model does no rendering itself. + +```java +public record RenderTypeModelWrapper(BakedModel model, RenderType type) implements ItemModel { + + // Update the render state + @Override + public void update(ItemStackRenderState state, ItemStack stack, ItemModelResolver resolver, ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { + ItemStackRenderState.LayerRenderState layerState = state.newLayer(); + if (stack.hasFoil()) { + layerState.setFoilType(ItemStackRenderState.FoilType.STANDARD); + } + layerState.setupBlockModel(this.model, this.type); + } + + public static record Unbaked(ResourceLocation model, RenderType type) implements ItemModel.Unbaked { + // Create a render type map for the codec + private static final BiMap RENDER_TYPES = Util.make(HashBiMap.create(), map -> { + map.put("translucent_item", Sheets.translucentItemSheet()); + map.put("cutout_block", Sheets.cutoutBlockSheet()); + }); + private static final Codec RENDER_TYPE_CODEC = ExtraCodecs.idResolverCodec(Codec.STRING, RENDER_TYPES::get, RENDER_TYPES.inverse()::get); + + // The map codec to register + public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> + instance.group( + ResourceLocation.CODEC.fieldOf("model").forGetter(RenderTypeModelWrapper.Unbaked::model), + RENDER_TYPE_CODEC.fieldOf("render_type").forGetter(RenderTypeModelWrapper.Unbaked::type) + ) + .apply(instance, RenderTypeModelWrapper.Unbaked::new) + ); + + @Override + public void resolveDependencies(ResolvableModel.Resolver resolver) { + // Resolve model dependencies, so pass in all known resource locations + resolver.resolve(this.model); + } + + @Override + public ItemModel bake(ItemModel.BakingContext context) { + // Get the baked model and return + BakedModel baked = context.bake(this.model); + return new RenderTypeModelWrapper(baked, this.type); + } + + @Override + public MapCodec type() { + return MAP_CODEC; + } + } +} + +// Then, in some initialization location where ItemModels#ID_MAPPER is exposed +ItemModels.ID_MAPPER.put( + // The registry name + ResourceLocation.fromNamespaceAndPath("examplemod", "render_type"), + // The map codec + RenderTypeModelWrapper.Unbaked.MAP_CODEC +); +``` + +```json5 +// For some item 'examplemod:example_item' +// JSON at 'assets/examplemod/items/example_item.json' +{ + "model": { + "type": "examplemod:render_type", + // Points to 'assets/examplemod/models/item/example_item.json' + "model": "examplemod:item/example_item", + // Set the render type to use when rendering + "render_type": "cutout_block" + } +} +``` + +- `net.minecraft.client` + - `ClientBootstrap` - Registers the maps backing the client; currently used for item model definitions. + - `Minecraft` + - `getEquipmentModels` is removed, only directly accessible in the `EntityRendererProvider$Context#getEquipmentAssets` + - `getItemModelResolver` - Returns the updater for resolving the current model to be rendered in the `ItemStackRenderState$LayerRenderState`. + - `KeyMapping#get` - Gets a key mapping based on its translation key. +- `net.minecraft.client.color.item` + - `Constant` - A constant to tint the item texture. + - `CustomModelDataSource` - Gets the color to tint based on an index in the `DataComponent#CUSTOM_MODEL_DATA` data component. If no index is found or is out of bounds, then the default color is used. + - `Dye` - Gets the color to tint using the `DataComponent#DYED_COLOR` data component. + - `Firework` - Gets the color to tint using the `DataComponent#FIRE_EXPLOSION` data component. + - `GrassColorSource` - Gets the color to tint based on the provided temperature and downfall values. + - `ItemColor` -> `ItemTintSource`, not one-to-one as indexing is setup by providing multiple `ItemTintSource`s in the model list. + - `ItemColors` class is removed, now data generated as `ItemTintSource`s + - `ItemTintSources` - A registry of sources for tinting an item texture in a model. + - `MapColor` - Gets the color to tint using the `DataComponent#MAP_COLOR` data component. + - `Potion` - Gets the color to tint using the `DataComponent#POTION_CONTENTS` data component. + - `TeamColor` - Gets the color based on the holding entity's team color. +- `net.minecraft.client.data.Main` - The entrypoint for client data generation. +- `net.minecraft.client.particle.BreakingItemParticle` now takes in an `ItemStackRenderState` instead of an `ItemStack` + - `$ItemParticleProvider` - An abstract particle provide that provides a simple method to calculate the `ItemStackRenderState`. +- `net.minecraft.client.renderer` + - `BlockEntityWithoutLevelRenderer` class is removed, replaced by the `NoDataSpecialModelRenderer` datagen system + - `ItemInHandRenderer` now takes in an `ItemModelResolver` + - `ItemModelShaper` is removed, as the methods are available within the `ModelManager` + - `Sheets` + - `getBedMaterial` - Gets the bed material from the dye color. + - `colorToResourceMaterial` - Gets the resource location of the dye color. + - `createBedMaterial` - Creates the bed material from the dye color or resource location. + - `getShulkerBoxMaterial` - Gets the shulker box material from the dye color. + - `colorToShulkerMaterial` - Gets the resource location of the dye color for the shulker box. + - `createShulkerMaterial` - Creates the shulker box material from the dye color or resource location. + - `chestMaterial` - Creates a new material for a chest with the given resource location. + - `SpecialBlockModelRenderer` - A map of blocks to special renderers for item variants. +- `net.minecraft.client.renderer.block.BlockRenderDispatcher` now takes in a supplied `SpecialBlockModelRenderer` instead of a `BlockEntityWithoutLevelRenderer` +- `net.minecraft.client.renderer.block.model` + - `BakedOverrides` class is removed, replaced by the `RangeSelectItemModelProperty` datagen system + - `BlockModel` now takes in a `TextureSlots$Data` instead of just a material map, and no longer takes in a list of `ItemOverride`s + - `MISSING_MATERIAL` is removed, replaced by `minecraft:missingno` + - `textureMap` -> `textureSlots`, now private, not one-to-one + - `parent` is now private, not one-to-one + - `parentLocation` is now private + - `hasAmbientOcclusion` -> `getAmbientOcclusion` + - `isResolved` is removed + - `getOverrides` is removed + - `getParent` - Returns the unbaked parent model. + - `getTextureSlots` - Returns the texture data for the model. + - `getElements` is now package-private + - `$GuiLight` -> `UnbakedModel$GuiLight` + - `FaceBakery` + - `bakeQuad` is now static + - `calculateFacing` is now private + - `ItemModelGenerator` now implements `UnbakedModel` + - `ItemOverride` class is removed, replaced by the `RangeSelectItemModelProperty` datagen system + - `ItemTransforms` is now a record + - `hasTransform` is removed + - `TextureSlots` - A class which handles the texture mapping within a model. The data is read from `$Data` and stored as `$SlotContents` until it is resolved during the baking process into `Material`s. + - `UnbakedBlockStateModel` now extends `ResolvableModel` instead of `UnbakedModel` + - `bake` - Bakes the block state into its selectable models. + - `Variant` is now a record +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the banner. + - `BedRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the bed. + - `BlockEntityRenderDispatcher(Font, EntityModelSet, Supplier, Supplier, Supplier)` -> `BlockEntityRenderDispatcher(Font, Supplier, BlockRenderDispatcher, ItemModelResolver, ItemRenderer, EntityRenderDispatcher)` + - `renderItem` is removed, implemented in their specific classes + - `BlockEntityRendererProvider` now takes in an `ItemModelResolver` + - `getItemModelResolver` - Gets the resolver which returns the item models. + - `ChestRenderer#xmasTextures` - Returns whether christmas textures should render on a chest. + - `DecoratedPotRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `renderInHand` - Renders the item model of the pot. + - `ShulkerBoxRenderer` now has an overload constructor which takes in the `EntityModelSet` + - `render` - Renders the shulker box. + - `$ShulkerBoxModel#animate` no longer takes in the `ShulkerBoxBlockEntity` + - `SkullblockRenderer#createSkullRenderers` -> `createModel`, not one-to-one +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher` now takes in an `IteModelResolver`, a supplied `EntityModelSet` instead of the instance, and an `EquipmentAssetManager` instead of a `EquipmentModelSet` + - `EntityRendererProvider$Context` now takes in an `ItemModelResolver` instead of an `ItemRenderer`, and an `EquipmentAssetManager` instead of a `EquipmentModelSet` + - `getItemRenderer` -> `getItemModelResolver`, not one-to-one + - `getEquipmentModels` -> `getEquipmentAssets` + - `FishingHookRenderer` - Returns the holding arm of the fishing hook. + - `HumanoidMobRenderer` + - `getArmPose` - Returns the arm pose of the entity. + - `extractHumanoidRenderState` now takes in an `ItemModelResolver` + - `ItemEntityRenderer` + - `getSeedForItemStack` is removed + - `renderMultipleFromCount` now takes in the `ItemClusterRenderState`, and removes the `ItemRenderer`, `ItemStack`, `BakedModel`, and 3d boolean + - `ItemRenderer` no longer implements `ResourceManagerReloadListener` + - The constructor now only takes in the `ItemModelResolver` + - `render` -> `renderItem`, not one-to-one + - `renderBundleItem` is removed + - `getModel`, `resolveItemModel` is removed + - `LivingEntityRenderer#itemRenderer` -> `itemModelResolver`, not one-to-one + - `OminousItemSpawnerRenderer` now uses the `ItemClusterRenderState` + - `SkeletonRenderer#getArmPose` -> `AbstractSkeletonRenderer#getArmPose` + - `SnowGolemRenderer` now uses the `SnowGolemRenderState` +- `net.minecraft.client.renderer.entity.layers` + - `CrossArmsItemLayer` now uses the `HoldingEntityRenderState` + - `CustomHeadLayer` no longer takes in the `ItemRenderer` + - `DolphinCarryingItemLayer` no longer takes in the `ItemRenderer` + - `EquipmentLayerRenderer$TrimSpriteKey` now takes in a `ResourceKey` + - `textureId` - Gets the texture id for the trim. + - `FoxHeldItemLayer` no longer takes in the `ItemRenderer` + - `ItemInHandLayer` now uses the `ArmedEntityRenderState` + - The constructor no longer takes in the `ItemRenderer` + - `renderArmWithItem` no longer takes in the `BakedModel`, `ItemStack`, or `ItemDisplayContext` and instead the `ItemStackRenderState` + - `LivingEntityEmissiveLayer` now takes in a boolean which determines whether the layer is always visible + - `PandaHoldsItemLayer` no longer takes in the `ItemRenderer` + - `PlayerItemInHandLayer` no longer takes in the `ItemRenderer` + - `renderArmWithItem` no longer takes in the `BakedModel`, `ItemStack`, or `ItemDisplayContext` and instead the `ItemStackRenderState` + - `SnowGolemHeadLayer` now uses the `SnowGolemRenderState` + - `WitchItemLayer` no longer takes in the `ItemRenderer` +- `net.minecraft.client.renderer.entity.player.PlayerRenderer#getArmPose` is now private +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` - A render state for an entity that holds items in their right and left hands. + - `HoldingEntityRenderState` - A render state for an entity that holds a single item. + - `ItemClusterRenderState` - A render state for an item that should be rendered multiple times. + - `ItemDisplayEntityRenderState#itemRenderState`, `itemModel` -> `item`, not one-to-one + - `ItemEntityRenderState#itemModel`, `item` -> `ItemClusterRenderState#item`, not one-to-one + - `ItemFrameRenderState#itemStack`, `itemModel` -> `item`, not one-to-one + - `LivingEntityRenderState` + - `headItemModel`, `headItem` -> `headItem`, not one-to-one + - Arm and Hand methods moved to `ArmedEntityRenderState` + - `OminousItemSpawnerRenderState` -> `ItemClusterRenderState` + - `PlayerRenderState` + - `mainHandState`, `offHandState` -> `ArmedEntityRenderState` methods + - `heldOnHead` - Represents the item stack on the head of the player. + - `SkeletonRenderState#isHoldingBow` - Represents if the skeleton is holding a bow. + - `SnowGolemRenderState` - The render state for the snow golem. + - `ThrownItemRenderState#item`, `itemModel` -> `item`, not one-to-one + - `WitchRenderState#isHoldingPotion` - Whether the witch is holding a potion or not. +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` - The basic model definition that contains the model and its associated tints. + - `BundleSelectedItemSpecialRenderer`- A special renderer for a stack selected by a bundle. + - `ClampedItemPropertyFunction`, `ItemPropertyFunction` -> `.properties.numeric.*` classes depending on the situation and property + - `ClientItem` - The base item that represents the model definition in `assets//items`. + - `CompositeModel` - Overlays multiple models together. + - `ConditionalItemModel` - A model that shows a different model based on a boolean. + - `EmptyModel` - A model that renders nothing. + - `ItemModel` - The base item model that updates the stack render state as necessary. + - `ItemModelResolver` - The resolver that updates the stack render state. + - `ItemModels` - Contains all potential item models for a `ClientItem`. + - `ItemProperties` class is removed + - `ItemStackRenderState` - The render state representing the stack to render. + - `MissingItemModel` - A model that represents the missing model. + - `RangeSelectItemModel` - A model that contains some range of values that applies the associated model that meets the threshold. + - `SelectItemModel` - An item model that switches based on the provided property. + - `SpecialModelWrapper` - An item model for models that are rendered dynamically, such as chests. +- `net.minecraft.client.renderer.item.properties.conditional` + - `Broken` - If the item only has one durability left. + - `BundleHasSelectedItem` - If the bundle is holding the selected item. + - `ConditionalItemModelProperties` - Contains all potential conditional property types. + - `ConditionalItemModelProperty` - Represents a property that returns some boolean. + - `CustomModelDataProperty` - If the current index is set to true within `DataComponents#CUSTOM_MODEL_DATA`. + - `Damaged` - If the item is damaged. + - `ExtendedView` - If the display context is a gui and the shift key is down. + - `FishingRodCast` - If the fishing rod is being used. + - `HasComponent` - Whether it has the associated data component. + - `IsCarried` - If the item is being carried in the current menu. + - `IsKeybindDown` - If the key mapping is being pressed. + - `IsSelected` - If the item is selected in the hotbar. + - `IsUsingItem` - If the item is being used. + - `IsViewEntity` - Whether the holding entity is the current camera entity. +- `net.minecraft.client.renderer.item.properties.numeric` + - `BundleFullness` - A threshold based on the bundle contents. + - `CompassAngle` - A threshold on the currrent angle state. + - `CompassAngleState` - A threshold based on the current compass angle towards its target. + - `Cooldown` - A threshold based on the current cooldown percentage. + - `Count` - A threshold based on the stack count. + - `CrossbowPull` - A threshold based on the crossbow being pulled. + - `CustomModelDataProperty` - If the current index has set theshold value within `DataComponents#CUSTOM_MODEL_DATA`. + - `Damage` - A threshold based on the durability percentage remaining. + - `NeedleDirectionHelper` - An abstract class which help point the position needle in the correct direction. + - `RangeSelectItemModelProperties` - Contains all potential ranged property types. + - `RangeSelectItemModelProperty` - Represents a property that returns some threshold of a float. + - `Time` - A threshold based on the current time of day. + - `UseCycle` - A threshold based on the remaining time left normalized to some period modulo in the stack being used. + - `UseDuration` - A threshold based on the remaining time left in the stack being used. +- `net.minecraft.client.renderer.item.properties.select` + - `Charge` - A case based on the charge type of a crowssbow. + - `ContextDimension` - A case based on the dimension the item is currently within. + - `ContextEntityType` - A case based on the holding entity's type. + - `CustomModelDataProperty` - If the current index is set to the string within `DataComponents#CUSTOM_MODEL_DATA`. + - `DisplayContext` - A case based on the display context. + - `ItemBlockState` - A case based on getting a property value from an item holding the block state properties. + - `LocalTime` - A case based on a simple date format pattern. + - `MainHand` - A case based on the arm holding the item. + - `SelectItemModelProperties` - Contains all potential select-cased property types. + - `SelectItemModelProperty` - Represents a property that returns some cased selection. + - `TrimMaterialProperty` - A case based on the trim material on the item. +- `net.minecraft.client.renderer.special` + - `BannerSpecialRenderer` - An item renderer for a banner. + - `BedSpecialRenderer` - An item renderer for a bed. + - `ChestSpecialRenderer` - An item renderer for a chest. + - `ConduitSpecialRenderer` - An item renderer for a conduit. + - `DecoratedPotSpecialRenderer` - An item renderer for a decorated pot. + - `HangingSignSpecialRenderer` - An item renderer for a hanging sign. + - `NoDataSpecialModelRenderer` - An item renderer that does not need to read any data from the stack. + - `ShieldSpecialRenderer` - An item renderer for a shield. + - `ShulkerBoxSpecialRenderer` - An item renderer for a shulker box. + - `SkullSpecialRenderer` - An item renderer for a skull. + - `SpecialModelRenderer` - Represents a model that reads data from the stack and renders the object without needing the render state. + - `SpecialModelRenderers` - Contains all potential special renderers. + - `StandingSignSpecialRenderer` - An item renderer for a standing sign. + - `TridentSpecialRenderer` - An item renderer for a trident. +- `net.minecraft.client.resources.model` + - `BakedModel` + - `isCustomRenderer` is removed, replaced by the special renderer system + - `overrides` is removed, replaced by the properties renderer system + - `BlockStateModelLoader` no longer takes in the missing model + - `definitionLocationToBlockMapper` is now private + - `loadBlockStateDefinitionStack` is now private + - `loadBlockStates` - Gets the loaded models for the block state. + - `$LoadedBlockModelDefinition` is now package-private + - `$LoadedModel` now takes in an `UnbakedBlockStateModel` instead of a `UnbakedModel` + - `$LoadedModels` + - `forResolving` - Returns all models hat need to be resolved. + - `plainModels` - Returns a map from the model location to the unbaked model. + - `BuiltInModel` class is removed + - `ClientItemInfoLoader` - Loads all models for all item stacks. + - `EquipmentModelSet` -> `EquipmentAssetManager` + - `ItemModel` -> `net.minecraft.client.renderer.item.ItemModel` + - `MissingBlockModel#MISSING` is now private + - `ModelBaker` + - `sprites` - Returns the getter to get sprites. + - `rootName` - Gets the name of the model for debugging. + - `ModelBakery(Map, Map, UnbakedModel)` -> `ModelBakery(EntityModelSet, Map, Map, Map, UnbakedModel)` + - `bakeModels` now returns a `$BakingResult` + - `getBakedTopLevelModels` is removed + - `$BakingResult` - Holds all models that have been lodaded. + - `$TextureGetter` + - `get` now takes in the `ModelDebugName` instead of the `ModelResourceLocation` + - `reportingMissingReference` - Handles how a texture is reported when not set. + - `bind` - Creates a spriate getter bound to the current model. + - `ModelDebugName` - Returns the name of the model for debugging. + - `ModelDiscovery` + - `registerStandardModels` is removed + - `registerSpecialModels` - Adds the internal models loaded by the system. + - `addRoot` - Adds a new model that can be resolved. + - `getUnreferencedModels` - Returns the difference between the models loaded vs the models used. + - `getTopModels` is removed + - `ModelGroupCollector$GroupKey#create` now takes in an `UnbakedBlockStateModel` instead of a `UnbakedModel` + - `ModelManager` + - `specialBlockModelRenderer` - Returns the renderer for special block models. + - `entityModels` - Returns the model set for the entities. + - `getItemProeprties` - Returns the properties for the client item based on its resource location. + - `ModelResourceLocation#inventory` is removed + - `ResolvableModel` - The base model, usually unbaked, that have references to resolve. + - `SimpleBakedModel` fields are now all private + - `bakeElements` - Bakes a model given the block elements. + - `$Builder` no longer has an overload that takes in the `BlockModel` + - `SpecialModels` class is removed + - `SpriteGetter` - A getter for atlas sprites for the associated materials. + - `UnbakedModel` is now a `ResolvableModel` + - `bake(ModelBaker, Function, ModelState)` -> `bake(TextureSlots, ModelBaker, ModelState, boolean, boolean, ItemTransforms)` + - `getAmbientOcclusion`, `getTopAmbientOcclusion` - Returns whether ambient occlusion should be enabled on the item. + - `getGuiLight`, `getTopGuiLight` - Returns the lighting side within a gui. + - `getTransforms`, `getTopTransform`, `getTopTransforms` - Returns the transformations to apply based on the display context. + - `getTextureSlots`, `getTopTextureSlots` - Returns the texture data for the model. + - `getParent` - Returns the parent of this model. + - `bakeWithTopModelValues` - Bakes the model. +- `net.minecraft.data.models.*` -> `net.minecraft.client.data.models.*` +- `net.minecraft.world.item` + - `BundleItem` no longer takes in any `ResourceLocation`s + - `openFrontModel`, `openBackModel` is removed + - `CrossbowItem$ChargeType` - The item being charged by the crossbow. + - `DyeColor#getMixedColor` - Returns the dye most closely representing the mixed color. + - `Item$Properties#overrideModel` is removed + - `SpawnEggItem` no longer takes in its tint colors + - `getColor` is removed +- `net.minecraft.world.item.alchemy.PotionContents` + - `getColor(*)` is removed + - `getColorOr` - Gets a custom color fro the potion or the default if not present. +- `net.minecraft.world.item.component.CustomModelData` now takes in a list of floats, flags, strings, and colors to use in the custom model properties based on the provided index +- `net.minecraft.world.item.equipment` + - `ArmorMaterial` now takes in a `ResourceKey` instead of just the model id + - `EquipmentAsset` - A marker to represent the equipment client info key + - `EquipmentAssets` - All vanilla equipment assets. + - `EquipmentModel` -> `net.minecraft.client.resources.model.EquipmentClientInfo` + - `EquipmentModels` -> `net.minecraft.client.data.models.EquipmentAssetProvider`, not one-to-one + - `Equippable` now takes in a `ResourceKey` instead of just the model id + - `$Builder#setModel` -> `setAsset` +- `net.minecraft.world.item.equipment.trim` + - `ArmorTrim#getTexture` is removed + - `TrimMaterial` no longer takes in an item model index, and the key over the override armor materials points to `ResourceKey` +- `net.minecraft.world.level.FoliageColor` + - `getEvergreenColor` -> `FOLIAGE_EVERGREEN` + - `getBirchColor` -> `FOLIAGE_BIRCH` + - `getDefaultColor` -> `FOLIAGE_DEFAULT` + - `getMangroveColor` -> `FOLIAGE_MANGROVE` +- `net.minecraft.world.level.block.RenderShape#ENTITYBLOCK_ANIMATED` is removed +- `net.minecraft.world.level.block.entity` + - `BannerBlockEntity#fromItem` is removed + - `BedBlockEntitty#setColor` is removed + - `BlockEntity#saveToItem` is removed + - `DecoratedPotBlockEntity#setFromItem`, `getPotAsItem` is removed +- `net.minecraft.world.level.storage.loot.functions.SetCustomModelDataFunction` now takes in a list of floats, flags, strings, and colors to use in the custom model properties based on the provided index + +### Mob Replacing Current Items + +One of the last hardcoded instances relating to tools and armor being subtypes of `DiggerItem` and `ArmorItem`, respectively, have been reworked: `Mob#canReplaceCurrentItem`. Now, it reads the `EquipmentSlot` of the stack from the `DataComponents#EQUIPPABLE` data component. Then, using that, different logic occurs depending on the situation. + +For armor slots, it cannot be changed if the armor is enchanted with a `EnchantmentEffectComponents#PREVENT_ARMOR_CHANGE` effect component. Otherwise, it will attempt to compare the armor attributes first, then armor toughness if equal. + +For weapons (via hand slots), it will first check if the mob has a preferred weapon type tag. If so, it will switch the item to the weapon in the tag, provided one item is in the tag and the other is not. Otherwise, it will attempt to compare attack damage attributes. + +If all attributes are equal, then they will both default to the following logic. First, it will try to pick the item with the most enchantments. Then, it will attempt to pick the item with the most durability remaining (the raw value, not the percentage). Finally, it will check whether one of the items hsa a custom name via the `DataComponents#CUSTOM_NAME`. + +> As a small caveat, `BambooSaplingBlock` and `BambooStalkBLock` still hardcode a check for check if the mainhand item is a `SwordItem`, though this could probably be replaced with a change to `ToolMaterial#applySwordProperties` in the future. + +### Particles, rendered through Render Types + +Particles are now rendered using a `RenderType`, rather than setting a buffer builder themselves. The only special cases are `ParticleRenderType#CUSTOM`, which allows the modder to implement their own rendering via `Particle#renderCustom`; and `ParticleRenderType#NO_RENDER`, which renders nothing. + +To create a new `ParticleRenderType`, it can be created by passing in its name for logging and the `RenderType` to use. Then, the type is returned in `Particle#getRenderType`. + +```java +public static final ParticleRenderType TERRAIN_SHEET_OPAQUE = new ParticleRenderType( + "TERRAIN_SHEET_OPAQUE", // Typically something recognizable, like the name of the field + RenderType.opaqueParticle(TextureAtlas.LOCATION_BLOCKS) // The Render Type to use +); +``` + +- `net.minecraft.client.particle` + - `CherryParticle` -> `FallingLeavesParticle`, not one-to-one as the new class has greater configuration for its generalization + - `ItemPickupParticle` no longer takes in the `RenderBuffers` + - `Particle#renderCustom` - Renders particles with the `ParticleRenderType#CUSTOM` render type. + - `ParticleEngine#render(LightTexture, Camera, float)` -> `render(Camera, float, MutliBufferSource$BufferSource)` + - `ParticleRenderType` is now a record which takes in the name and the `RenderType` it uses. + +### 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. + +#### `SimpleJsonResourceReloadListener` + +`SimpleJsonResourceReloadListener`s now take in a converter to map some key to a resource location. An abstract has been provided for registry keys. This is done through a `FileToIdConverter`, which essentially holds a prefix and extension to apply to some `ResourceLocation`. + +```java +// We will assume this is a server reload listener (meaning in the 'data' folder) +public class MyLoader extends SimpleJsonResourceReloadListener { + + public MyLoader() { + super( + // The codec to encode/decode the object + ExampleObject.CODEC, + // The file converter + // Will place files in data//example/object/.json + FileToIdConverter.json( + // The prefix + "example/object" + ) + ); + } + + // Below is the same +} +``` + +- `net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener` now takes in a resource key for a registry, or a file to id converter instead of just a string + - `scanDirectory` now takes in a resource key for a registry, or a file to id converter instead of just a string + +#### MetadataSectionSerializer, replaced by Codecs + +`MetadataSectionSerializer` has been removed in favor of using `Codec`s to serialize the metadata sections. As such all `MetadataSectionSerializer`s have been replaced by its `MetadataSectionType` instead, which holds the name of the section and the codec for the metadata section. + +- `net.minecraft.client.renderer.texture` + - `HttpTexture` -> `SkinTextureDownloader`, not one-to-one as the new class is just a utility that returns the content to store + - `MissingTextureAtlasSprite` + - `getTexture` -> `generateMissingImage`, not one-to-one + - `getMissingImage(int, int)` is now public + - `SpriteLoader#loadAndStitch` now takes in a collection of `MetadataSectionType`s rather than `MetadataSectionSerializer`s +- `net.minecraft.client.resources.SkinManager` no longer takes in the `TextureManager` + - `getOrLoad` now returns an `Optional` future instead of just the `PlayerSkin` +- `net.minecraft.client.resources.metadata.animation` + - `AnimationFrame` is now a record + - `AnimationMetadataSection` is now a record + - `AnimationMetadataSectionSerializer` class is removed + - `VillagerMetaDataSection` -> `VillagerMetadataSection` + - `VillagerMetadataSectionSerializer` class is removed +- `net.minecraft.client.resources.metadata.texture` + - `TextureMetadataSection` is now a record + - `TextureMetadataSectionSerializer` class is removed +- `net.minecraft.server.packs.PackResources#getMetadataSection` now takes in a `MetadataSectionType` instead of a `MetadataSectionSerializer` +- `net.minecraft.server.packs.metadata` + - `MetadataSectionSerializer` is removed in favor of section codecs + - `MetadataSectionType` is a now a record instead of a `MetadataSectionSerializer` extension +- `net.minecraft.server.packs.resources.ResourceMetadata` + - `getSection` now takes in a `MetadataSectionType` instead of a `MetadataSectionSerializer` + - `copySections` now takes in a collection of `MetadataSectionType`s instead of a `MetadataSectionSerializer`s + +#### Music, now with Volume Controls + +The background music is now handled through a `MusicInfo` class, which also stores the volume along with the associated `Music`. + +- `net.minecraft.client.Minecraft#getSituationalMusic` now returns a `MusicInfo` instead of a `Music` +- `net.minecraft.client.sounds` + - `MusicInfo` - A record that holds the currently playing `Music` and the volume its at. + - `MusicManager#startPlaying` now takes in a `MusicInfo` instead of a `Music` + - `SoundEngine#setVolume`, `SoundManager#setVolume` - Sets the volume of the associated sound instance. +- `net.minecraft.world.level.biome` + - `Biome` + - `getBackgroundMusic` now returns a optional `SimpleWeightedRandomList` of music. + - `getBackgroundMusicVolume` - Gets the volume of the background music. + - `BiomeSpecialEffects$Builder#silenceAllBackgroundMusic`, `backgroundMusic(SimpleWeightedRandomList)` - Handles setting the background music for the biome. + +#### Tag Changes + +- `minecraft:block` + - `tall_flowers` -> `bee_attractive` +- `minecraft:item` + - `tall_flowers`, `flowers` is removed + - `trim_templates` is removed + - `skeleton_preferred_weapons` + - `drowned_preferred_weapons` + - `piglin_preferred_weapons` + - `pillager_preferred_weapons` + - `wither_skeleton_disliked_weapons` + +#### List of Additions + +- `com.mojang.blaze3d.platform.Window#isMinimized` - Returns whether the application window is minimized. +- `com.mojang.blaze3d.vertex.VertexBuffer` + - `uploadStatic` - Immediately uploads the provided vertex data via the `Consumer` using the `Tesselator` with a `STATIC_WRITE` `VertexBuffer`. + - `drawWithRenderType` - Draws the current buffer to the screen with the given `RenderType`. +- `com.mojang.math.MatrixUtil#isIdentity` - Checks whether the current `Matrix4f` is an identity matrix. +- `net.minecraft` + - `SuppressForbidden` - An annotation that holds some reason, usually related to needing the sysout stream. + - `Util#maxAllowedExecutorThreads` - Returns the number of available processors clamped between one and the maximum number of threads. +- `net.minecraft.client.gui.components.events.GuiEventListener#getBorderForArrowNavigation` - Returns the `ScreenRectangle` bound to the current direction. +- `net.minecraft.client.gui.navigation.ScreenRectangle#transformAxisAligned` - Creates a new `ScreenRectangle` by transforming the position using the provided `Matrix4f`. +- `net.minecraft.client.gui.narration.NarratableEntry#getNarratables` - Returns the list of narratable objects within the current object. +- `net.minecraft.client.gui.screens.recipebook.RecipeCollection#EMPTY` - An empty collection of recipes. +- `net.minecraft.client.gui.screens.worldselection` + - `ExperimentsScreen$ScrollArea` - Represents a narratable scroll area of the currently available experiments. + - `SwitchGrid#layout` - Returns the layout of the grid to visit. +- `net.minecraft.client.model` + - `BannerFlagModel`, `BannerModel` - Models for the banner and hanging banner. + - `VillagerLikeModel#translateToArms` - Translates the pose stack such that the current relative position is at the entity's arms. +- `net.minecraft.client.model.geom.EntityModelSet#vanilla` - Creates a new model set with all vanilla models. +- `net.minecraft.client.multiplayer.PlayerInfo#setShowHat`, `showHat` - Handles showing the hat layer of the player in the tab overlay. +- `net.minecraft.client.renderer.blockentity` + - `AbstractSignRenderer` - How a sign should render as a block entity. + - `HangingSignRenderer` + - `createSignModel` - Creates a sign model given the wood and the attachment location. + - `renderInHand` - Renders the model in the entity's hand. + - `$AttachmentType` - An enum which represents where the model is attached to, given its properies. + - `$ModelKey` - A key for the model that combines the `WoodType` with its `$AttachmentType`. + - `SignRenderer` + - `renderInHand` - Renders the model in the entity's hand. +- `net.minecraft.client.renderer.entity.EntityRenderer#getShadowStrength` - Returns the raw opacity of the display's shadow. +- `net.minecraft.client.renderer.entity.layers.CrossedArmsItemLayer#applyTranslation` - Applies the translation to render the item in the model's arms. +- `net.minecraft.client.renderer.texture` + - `ReloadableTexture` - A texture that can be reloaded from its associated contents. + - `TextureContents` - Holds the image and metadata associated with a given texture. + - `TextureManager` + - `registerAndLoad` - Registers a reloadable texture with the given name. + - `registerForNextReload` - Registers a texture by its resource location to be loaded on next reload. +- `net.minecraft.commands.SharedSuggestionProvider#MATCH_SPLITTER` - Defines a matcher that matches a period, underscore, or forward slash. +- `net.minecraft.core.BlockPos$TraversalNodeStatus` - A marker indicating whether the `BlockPos` should be used, skipped, or stopped from any further traversal. +- `net.minecraft.core.component.PatchedDataComponentMap` + - `toImmutableMap` - Returns either the immutable patch or a copy of the current map. + - `hasNonDefault` - Returns whether there is a custom value for the data component instead of just the default. +- `net.minecraft.data.PackOutput$PathProvider#json` - Gets the JSON path from a resource key. +- `net.minecraft.data.loot.BlockLootSubProvider#createMultifaceBlockDrops` - Drops a block depending on the block face mined. +- `net.minecraft.data.worldgen.placement.PlacementUtils#HEIGHTMAP_NO_LEAVES` - Creates a y placement using the `Heightmap$Types#MOTION_BLOCKING_NO_LEAVES` heightmap. +- `net.minecraft.network.chat.Style#getShadowColor`, `withShadowColor` - Methods for handling the shadow color of a component. +- `net.minecraft.network.protocol.game.ServerboundPlayerLoadedPacket` - A packet for when the client player loads into a client world. +- `net.minecraft.resources.FileToIdConverter#registry` - Gets the file converter from a registry key. +- `net.minecraft.util.ExtraCodecs` + - `idResolverCodec` - Creates a codec that maps some key to some value. + - `compactListCodec` - Creates a codec that can either be an element of a list of elements. + - `floatRange` - Creates a codec that must be between two float values. + - `$LateBoundIdMapper` - A mapper that functionally acts like a registry with an associated codec. +- `net.minecraft.util.profiling.jfr.JvmProfiler#onStructureGenerate` - Returns the profiled duration on when a structure attempts to generate in the world. +- `net.minecraft.util.profiling.jfr.event.StructureGenerationEvent` - A profiler event when a structure is being generated. +- `net.minecraft.util.profiling.jfr.stats.StructureGenStat` - A result of a profiled structure generation. +- `net.minecraft.world.entity` + - `LivingEntity` + - `resolvePlayerResponsibleForDamage` - Gets the player responsible for hurting the current entity. + - `canBeNameTagged` - When true, the entity's can be set with a name tag. + - `Mob#getPreferredWeaponType` - Gets the tag that represents the weapons the entity wants to pick up. +- `net.minecraft.world.entity.ai.attributes.AttributeMap#resetBaseValue` - Resets the attribute instance to its default value. +- `net.minecraft.world.entity.monster.creaking` + - `Creaking` + - `activate`, `deactivate` - Handles the activateion of the brain logic for the creaking. + - `setTransient`, `isHeartBound`, `setHomePos`, `getHomePos` - Handles the home position. + - `blameSourceForDamage` - Finds the player responsible for the damage. + - `tearDown` - Handles when the creaking is destroyed. + - `creakingDeathEffects` - Handles the death of a creaking. + - `playerIsStuckInYou` - Checks whether there are at least four players stuck in a creaking. + - `setTearingDown`, `isTearingDown` - Handles the tearing down state. + - `hasGlowingEyes`, `checkEyeBlink` - Handles the eye state. +- `net.minecraft.world.entity.player.Player` + - `hasClientLoaded`, `setClientLoaded` - Whether the client player has been loaded. + - `tickClientLoadTimeout` - Ticks the timer on how long to wait before kicking out the client player if not loaded. +- `net.minecraft.world.item` + - `Item#shouldPrintOpWarning` - Whether a warning should be printed to the player based on stored block entity data and adminstrator permissions. + - `ItemStack` + - `getCustomName` - Returns the custom name of the item, or `null` if no component exists. + - `immutableComponents` - Returns either the immutable patch or a copy of the stack component map. + - `hasNonDefault` - Returns whether there is a custom value for the data component instead of just the default. +- `net.minecraft.world.item.component.CustomData` + - `parseEntityId` - Reads the entity id off of the component. + - `parseEntityType` - Reads the entity type from the id and maps it to its registry object. +- `net.minecraft.world.item.crafting.Ingredient#isEmpty` - Returns whether the ingredient has no values. +- `net.minecraft.world.item.trading.Merchant#stillValid` - Checks whether the merchant can still be accessed by the player. +- `net.minecraft.world.level` + - `Level#dragonParts` - Returns the list of entities that are the parts of the ender dragon. + - `ServerExplosion#getDamageSource` - Returns the damage source of the explosion. +- `net.minecraft.world.level.block` + - `EyeblossomBlock$Type` + - `block` - Gets the block for the current type. + - `state` - Gets the block state for the current type. + - `transform` - Returns the opposiate state of this type. + - `FlowerBlock#getBeeInteractionEffect` - Returns the effect that bees obtain when interacting with the flower. + - `FlowerPotBlock#opposite` - Returns the opposite state of the block, only for potted eyeblossoms. + - `MultifaceBlock#canAttachTo` - Returns whether this block can attach to another block. + - `MultifaceSpreadeableBlock` - A multiface block that can naturally spread. +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner#overrideEntityToSpawn` - Changes the entity to spawn in the trial. + - `TrialSpawnerConfig#withSpawning` - Sets the entity to spawn within the trial. + +#### List of Changes + +- `com.mojang.blaze3d.platform.NativeImage#upload` no longer takes in three booleans that set the filter mode or texture wrap clamping for `TEXTURE_2D` + - This has been moved to `AbstractTexture#setClamp` and `#setFilter` +- `net.minecraft.client.gui` + - `Gui#clear` -> `clearTitles` + - `GuiGraphics#drawWordWrap` has a new overload that takes in whether a drop shadow should be applied to the text + - The default version enables drop shadows instead of disabling it +- `net.minecraft.client.gui.components` + - `AbstractContainerWidget` now implements `AbstractScrollArea` + - `AbstractScrollWidget` -> `AbstractScrollArea` or `AbstractTextAreaWidget` depending on use-case, not one-to-one + - `AbstractSelectionList` + - `setRenderHeader` is now bundled into a new constructor with an extra integer + - `getMaxScroll` -> `AbstractScrollArea#maxScrollAmount` + - `getScrollAmount` -> `AbstractScrollArea#scrollAmount` + - `scrollbarVisible` -> `AbstractScrollArea#scrollbarVisible` + - `setClampedScrollAmount`, `setScrollAmount` -> `AbstractScrollArea#setScrollAmount` + - `clampScrollAmount` -> `refreshScrollAmount` + - `updateScrollingState` -> `AbstractScrollArea#updateScrolling` + - `getScrollbarPosition`, `getDefaultScrollbarPosition` -> `scrollBarY`, not one-to-one + - `AbstractWidget#clicked` -> `isMouseOver`, already exists +- `net.minecraft.client.gui.components.toasts.TutorialToast` now requires a `Font` as the first argument in its constructor +- `net.minecraft.client.gui.font.glyphs.BakedGlyph$Effect` and `$GlyphInstance` now take in the color and offset of the text shadow +- `net.minecraft.client.gui.screens` + - `LoadingOverlay#registerTextures` now takes in a `TextureManager` instead of the `Minecraft` instance + - `TitleScreen#preloadResources` -> `registerTextures`, not one-to-one +- `net.minecraft.client.gui.screens.debug.GameModeSwitcherScreen$GameModeSlot` is now a static inner class +- `net.minecraft.client.gui.screens.reporting.ChatSelectionScreen$Entry`, `$PaddingEntry` are now static inner classes +- `net.minecraft.client.gui.screens.worldselection.SwitchGrid$Builder#build` no longer takes in a `Consumer` +- `net.minecraft.client.model` + - `DonkeyModel#createBodyLayer`, `createBabyLayer` now take in a scaling factor + - `VillagerHeadModel` -> `VillagerLikeModel` +- `net.minecraft.client.model.geom.EntityModelSet` is no longer a `ResourceManagerReloadListener` +- `net.minecraft.client.multiplayer.MultiPlayerGameMode#handlePickItem` -> `handlePickItemFromBlock` or `handlePickItemFromEntity`, providing both the actual object data to sync and a `boolean` about whether to include the data of the object being picked +- `net.minecraft.client.particle.CherryParticle` -> `FallingLeavesParticle`, not one-to-one as the new class has greater configuration for its generalization +- `net.minecraft.client.player.ClientInput#tick` no longer takes in any parameters +- `net.minecraft.client.renderer` + - `CubeMap#preload` -> `registerTextures`, not one-to-one + - `LevelRenderer` + - `renderLevel` no longer takes in the `LightTexture` + - `onChunkLoaded` -> `onChunkReadyToRender` + - `PostChainConfig$Pass#program` -> `programId` + - `program` now returns the `ShaderProgram` with the given `programId` + - `ScreenEffectRenderer#renderScreenEffect` now takes in a `MultiBufferSource` + - `SectionOcclusionGraph#onChunkLoaded` -> `onChunkReadyToRender` + - `Sheets#createSignMaterial`, `createHangingSignMaterial` now has an overload that takes in a `ResourceLocation` + - `SkyRenderer` + - `renderSunMoonAndStars`, `renderSunriseAndSunset` now takes in a `MultiBufferSource$BufferSource` instead of a `Tesselator` + - `renderEndSky` no longer takes in the `PoseStack` + - `WeatherEffectRenderer#render` now takes in a `MultiBufferSource$BufferSource` instead of a `LightTexture` +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#createBodyLayer` -> `BannerModel#createBodyLayer`, not one-to-one + - `HangingSignRenderer` + - `createHangingSignLayer` now takes in a `HangingSignRenderer$AttachmentType` + - `$HangingSignModel` is now replaced with a `Model$Simple`, though its fields can be obtained from the root + - `SkullBlockRenderer#getRenderType` now has an overload that takes in a `ResourceLocation` to override representing the player's texture +- `net.minecraft.client.renderer.entity.AbstractHorseRenderer`, `DonkeyRenderer` no longer takes in a float scale +- `net.minecraft.client.renderer.entity.layers.CrossedArmsItemLayer` now requires the generic `M` to be a `VillagerLikeModel` +- `net.minecraft.client.renderer.entity.state.CreakingRenderState#isActive` -> `eyesGlowing` + - The original parameter still exists on the `Creaking`, but is not necessary for rendering +- `net.minecraft.core.BlockPos#breadthFirstTraversal` now takes in a function that returns a `$TraversalNodeStatus` instead of a simple predicate to allow certain positions to be skipped +- `net.minecraft.core.particles.TargetColorParticleOption` -> `TrailParticleOption`, not one-to-one +- `net.minecraft.data.DataProvider#savelAll` now has overloads for maps with a key function to get the associated path +- `net.minecraft.network` + - `NoOpFrameEncoder` replaced by `LocalFrameEncoder`, not one-to-one + - `NoOpFrameDecoder` replaced by `LocalFrameDecoder`, not one-to-one + - `MonitorFrameDecoder` replaced by `MonitoredLocalFrameDecoder`, not one-to-one +- `net.minecraft.network.protocol.game` + - `ClientboundLevelParticlesPacket` now takes in a boolean that determines whether the particle should always render + - `ClientboundMoveVehiclePacket` is now a record + - `ClientboundPlayerInfoUpdatePacket$Entry` now takes in a boolean representing whether the hat should be shown + - `ClientboundSetHeldSlotPacket` is now a record + - `ServerboundMoveVehiclePacket` is now a record + - `ServerboundPickItemPacket` -> `ServerboundPickItemFromBlockPacket`, `ServerboundPickItemFromEntityPacket`; not one-to-one +- `net.minecraft.server.level + - `ServerLevel#sendParticles` now has an overload that takes in the override limiter distance and whether the particle should always be shown + - Other overloads that take in the override limiter now also take in the boolean for if the particle should always be shown + - `ServerPlayer#doCheckFallDamage` -> `Entity#doCheckFallDamage`, now final +- `net.minecraft.util` + - `ARGB#from8BitChannel` is now private, with individual float components obtained from `alphaFloat`, `redFloat`, `greenFloat`, and `blueFloat` + - `SpawnUtil#trySpawnMob` now takes in a boolean that, when false, allows the entity to spawn regardless of collision status with the surrounding area +- `net.minecraft.util.profiling.jfr.callback.ProfiledDuration#finish` now takes in a boolean that indicates whether the profiled event was successful +- `net.minecraft.util.profiling.jfr.parse.JfrStatsResults` now takes in a list of structure generation statistics +- `net.minecraft.world.effect.PoisonMobEffect`, `WitherMobEffect` is now public +- `net.minecraft.world.entity` + - `Entity` + - `setOnGroundWithMovement` has an overload that sets the horizontal collision to whatever the entity's current state is. + - `awardKillScore` no longer takes in an integer + - `makeBoundingBox()` is now final + - `makeBoundingBox(Vec3)` is now + - `onlyOpCanSetNbt` -> `EntityType#onlyOpCanSetNbt` + - `Leashable` + - `readLeashData` is now private, replaced by a method that returns nothing + - `dropLeash(boolean, boolean)` -> `dropLeash()`, `removeLeash`, `onLeashRemoved`; not one-to-one, as they all internally call the private `dropLeash` + - `LivingEntity` + - `isLookingAtMe` no longer takes in a `Predicate`, and array of `DoubleSupplier`s is now an array of `double`s + - `hasLineOfSight` takes in a double instead of a `DoubleSupplier` +- `net.minecraft.world.entity.ai.behavior.AcquirePoi#create` now has overloads which take in a `BiPredicate` for filtering POI locations +- `net.minecraft.world.entity.animal.Bee#attractsBees` is now public +- `net.minecraft.world.entity.monster.Shulker#getProgressAabb`, `getProgressDeltaAabb` now take in a movement `Vec3` +- `net.minecraft.world.entity.player` + - `Inventory` + - `setPickedItem` -> `addAndPickItem` + - `findSlotMatchingCraftingIngredient` now takes in an `ItemStack` to compare against + - `Player#getPermissionLevel` is now public + - `StackedContents$IngredientInfo` is now an interface that acts like a predicate for accepting some item +- `net.minecraft.world.entity.projectile.FishingHook` no longer takes in the `ItemStack` +- `net.minecraft.world.inventory.Slot#getNoItemIcon` now returns a single `ResourceLocation` rather than a pair of them +- `net.minecraft.world.item` + - `Item$TooltipContext#of` now takes in the `Player` viewing the item + - `MobBucketItem` now requires a `Mob` entity type + -` SpawnEggItem#spawnsEntity`, `getType` now takes in a `HolderLookup$Provider` +- `net.minecraft.world.item.crafting` + - `Ingredient` now implements `StackedContents$IngredientInfo>` + - `items` now returns a stream instead of a list + - `PlacementInfo#slotInfo` -> `slotsToIngredientIndex`, not one-to-one +- `net.minecraft.world.level.Level#addParticle` now takes in a boolean representing if the particle should always be shown +- `net.minecraft.world.level.block` + - `Block#getCloneItemStack` -> `state.BlockBehaviour#getCloneItemStack`, now protected + - `CherryLeavesBlock` -> `ParticleLeavesBlock` + - `CreakingHeartBlock#canSummonCreaking` -> `isNaturalNight` + - `MultifaceBlock` is no longer abstract and implements `SimpleWaterloggedBlock` + - `getSpreader` -> `MultifaceSpreadeableBlock#getSpreader` + - `SculkVeinBlock` is now an instance of `MultifaceSpreadeableBlock` + - `SnowyDirtBlock#isSnowySetting` is now protected +- `net.minecraft.world.level.block.entity` + - `AbstractFurnaceBlockEntity` + - `litTime` -> `litTimeRemaining` + - `litDuration` -> `litTotalTime` + - `cookingProgress` -> `cookingTimer` + - `BeehiveBlockEntity#addOccupant` now takes in a `Bee` rather than an `Entity` + - `CreakingHeartBlockEntity#setCreakingInfo` - Sets the creaking the block entity is attached to. +- `net.minecraft.world.level.block.state.BlockBehaviour#getCloneItemStack`, `$BlockStateBase#getCloneItemStack` now takes in a boolean representing if there is infinite materials and whether the current block data should be saved. +- `net.minecraft.world.level.chunk.ChunkGenerator#createStructures` now takes in the `Level` resource key, only used for profiling +- `net.minecraft.world.level.levelgen.feature.configurations` + - `MultifaceGrowthConfiguration` now takes in a `MultifaceSpreadableBlock` instead of a `MultifaceBlock` + - `SimpleBlockConfiguration` now takes in a boolean on whether to schedule a tick update +- `net.minecraft.world.level.levelgen.structure.Structure#generate` now takes in the `Structure` holder and a `Level` resource key, only used for profiling + +#### List of Removals + +- `com.mojang.blaze3d.systems.RenderSystem#overlayBlendFunc` +- `net.minecraft.client.gui.components.AbstractSelectionList` + - `clickedHeader` + - `isValidMouseClick` +- `net.minecraft.client.gui.screens.recipebook.RecipeCollection#hasSingleResultItem` +- `net.minecraft.client.model` + - `DrownedModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `FelineModel#CAT_TRANSFORMER` + - `HumanoidModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `PlayerModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `SkeletonModel#getArmPose`, now part of the `ArmedEntityRenderState` + - `VillagerModel#BABY_TRANSFORMER` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `load` + - `reset` + - `getDefaultBlur` + - `PreloadedTexture` + - `TextureManager` + - `getTexture(ResourceLocation, AbstractTexture)` + - `register(String, DynamicTexture)` + - `preload` +- `net.minecraft.server.level.TicketType#POST_TELEPORT` +- `net.minecraft.world.entity.LivingEntity#deathScore` +- `net.minecraft.world.entity.ai.navigation.FlyingPathNavigation`, `GroundPathNavigation` + - `canPassDoors`, `setCanPassDoors` + - `canOpenDoors` +- `net.minecraft.world.entity.monster.creaking.CreakingTransient` +- `net.minecraft.world.entity.player.StackedItemContents#convertIngredientContents` +- `net.minecraft.world.item` + - `CompassItem#getSpawnPosition` + - `ItemStack#clearComponents` +- `net.minecraft.world.item.crafting.PlacementInfo` + - `ingredientToContents` + - `unpackedIngredients` + - `$SlotInfo` +- `net.minecraft.world.level.block.CreakingHeartBlock$CreakingHeartState` +- `net.minecraft.world.level.block.entity.BlockEntity#onlyOpCanSetNbt` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData#setEntityId` + +### Step 3: 1.21.4 -> 1.21.5 + +## Minecraft 1.21.4 -> 1.21.5 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.4 to 1.21.5. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @TelepathicGrunt for the information within the 'Very Technical Changes' section +- @RogueLogix for their review and comments on the 'Render Pipeline Rework' section +- @Tslat for catching an error about `equipOnInteract` + +### 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](https://misode.github.io/versions/?id=1.21.5&tab=changelog). + +### Handling the Removal of Block Entities Properly + +Previously, `BlockEntity` would handle all of their removal logic within `BlockBehaviour#onRemove`, including both dropping any stored items and removing the block entity itself. However, depending on how the method is used, it can cause some strange behaviors due to the mutable state of the block entity. For this reason, the logic that makes up the removal process has been split between two methods: `BlockEntity#preRemoveSideEffects` and `BlockBehaviour#affectNeighborsAfterRemoval`. + +`BlockEntity#preRemoveSideEffects` is now responsible for removing anything from the block entity before it is removed from the level. By default, if the `BlockEntity` is a `Container` instance, it will drop the contents of the container into the level. Other logic can be handled within here, but it should generally avoid removing the `BlockEntity` itself, unless the position of the block entity tends to change dynamically, like for a piston. + +From there, the `LevelChunk` logic will call `removeBlockEntity` before calling `BlockBehaviour#affectNeighborsAfterRemoval`. This should only send the updates to other blocks indicating that this block has been removed from the level. For `BlockEntity` holders, this can be done easily by calling `Containers#updateNeighboursAfterDestroy`. Otherwise may want to call `Level#updateNeighborsAt` themselves, depending on the situation. + +- `net.minecraft.world.Containers` + - `updateNeighboursAfterDestroy` - Updates the neighbor state aftering destroying the block at the specified position. + - `dropContentsOnDestroy` is removed, handled within `BlockEntity#preRemoveSideEffects` for `Container` instances +- `net.minecraft.world.level.block.entity.BlockEntity#preRemoveSideEffects` - Handles logic on the block entity that should happen before being removed from the level. +- `net.minecraft.world.level.block.state.BlockBehaviour#onRemove`, `$BlockStateBase#onRemove` -> `affectNeighborsAfterRemoval`, should only handle logic to update the surrounding neighbors rather than dropping container data + +### Voxel Shape Helpers + +`VoxelShape`s have received numerous helpers for more common transformations of its base state. There are the `Block` methods for creating a centered (if desired) box and the `Shapes` methods for rotating a `VoxelShape` to its appropriate axis or direction. There is also a `Shapes#rotateAttachFace` method for rotating some `VoxelShape` that is attached to a face of a different block. The results are either stored in a `Map` of some key to a `VoxelShape`, or when using `Block#getShapeForEachState`, a `Function`. + +Most of the `Block` subclasses that had previous public or protected `VoxelShape`s are now private, renamed to a field typically called `SHAPE` or `SHAPES`. Stored `VoxelShape`s may also be in a `Function` instead of directly storing the map itself. + +- `com.mojang.math.OctahedralGroup` + - `permute` - Returns the axis that the given axis is permuted to within the specified group. + - `fromAngles` - Creates a group with the provided X and Y rotations. +- `net.minecraft.core.Direction$Axis#choose` now has an overload that takes in three booleans +- `net.minecraft.world.level.block.Block` + - `boxes` - Creates one more than the specified number of boxes, using the index as part of the function to create the `VoxelShape`s. + - `cube` - Creates a centered cube of the specified size. + - `column` - Creates a horizontally centered column of the specified size. + - `boxZ` - Creates a vertically centered (around the X axis) cube/column of the specified size. + - `getShapeForEachState` now returns a `Function` which wraps the `ImmutableMap`, there is also a method that only considers the specified properties instead of all possible states. +- `net.minecraft.world.phys.shapes` + - `DiscreteVoxelShape#rotate` - Rotates a voxel shape according to the permutation of the `OctahedralGroup`. + - `Shapes` + - `blockOccudes` -> `blockOccludes` + - `rotate` - Rotates a given voxel shape according to the permutation of the `OctahedralGroup` around the provided vector, or block center if not specified. + - `equal` - Checks if two voxel shapes are equivalent. + - `rotateHorizontalAxis` - Creates a map of axes to `VoxelShape`s of a block being rotated around the y axis. + - `rotateAllAxis` - Creates a map of axes to `VoxelShape`s of a block being rotated around any axis. + - `rotateHorizontal` - Creates a map of directions to `VoxelShape`s of a block being rotated around the y axis. + - `rotateAll` - Creates a map of directions to `VoxelShape`s of a block being rotated around the any axis. + - `rotateAttachFace` - Creates a map of faces to a map of directions to `VoxelShape`s of a block being rotated around the y axis when attaching to the faces of other blocks. + - `VoxelShape#move` now has an overload to take in a `Vec3i` + +### Weapons, Tools, and Armor: Removing the Redundancies + +There have been a lot of updates to weapons, tools, and armor that removes the reliance on the hardcoded base classes of `SwordItem`, `DiggerItem`, and `ArmorItem`, respectively. These have been replaced with their associated data components `WEAPON` for damage, `TOOL` for mining, `ARMOR` for protection, and `BLOCKS_ATTACKS` for shields. Additionally, the missing attributes are usually specified by setting the `ATTRIBUTE_MODIFIERS`, `MAX_DAMAGE`, `MAX_STACK_SIZE`, `DAMAGE`, `REPAIRABLE`, and `ENCHANTABLE`. Given that pretty much all of the non-specific logic has moved to a data component, these classes have now been completely removed. Use one of the available item property methods or call `Item$Properties#component` directly to set up each item as a weapon, tool, armor, or some combination of the three. + +Constructing a `BlockAttacks` component for a shield-like item: + +```java +var blocker = new BlocksAttacks( + // The number of seconds to wait when the item is being used + // before the blocking effect is applied. + 1.2f, + // A scalar to change how many ticks the blocker is disabled + // for. If negative, the blocker cannot normally be disabled. + 0.5f, + // A list of reductions for what type and how much of a damage type + // is blocked by this blocker. + List.of( + new DamageReduction( + // The horizontal blocking angle of the shield required to apply + // the reduction + 90f, + // A set of damage types this reduction should apply for. + // When empty, it applies for all damage types. + Optional.empty(), + // The base damage to reduce the attack by. + 1f, + // A scalar representing the fraction of the damage blocked. + 0.5f + ) + ), + // A function that determines how much durability to remove to the blocker. + new ItemDamageFunction( + // A threshold that specifies the minimum amount of damage required + // to remove durability from the blocker. + 4f, + // The base durability to remove from the blocker. + 1f, + // A scalar representing the fraction of the damage to convert into + // removed durability. + 0.5f + ), + // A tag key containing the items that can bypass the blocker and deal + // damage directly to the wielding entity. If empty, no item can bypass + // the blocker. + Optional.of(DamageTypeTags.BYPASSES_SHIELD), + // The sound to play when the blocker successfully mitigates some damage. + Optional.of(SoundEvents.SHIELD_BLOCK), + // The sound to play when the blocker is disabled by a weapon. + Optional.of(SoundEvents.SHIELD_BREAK) +); +``` + +Constructing a `Weapon` component for a sword-like item: + +```java +var weapon = new Weapon( + // The amount of durability to remove from the item. + 3, + // The number of seconds a `BlocksAttack`s component item should + // be disabled for when hit with this weapon. + 5f +); +``` + +- `net.minecraft.core.component.DataComponents` + - `UNBREAKABLE` is now a `Unit` instance + - `HIDE_ADDITIONAL_TOOLTIP`, `HIDE_TOOLTIP` have been bundled in `TOOLTIP_DISPLAY`, taking in a `TooltipDisplay` + - `BLOCKS_ATTACKS` - A component that determines whether a held item can block an attack from some damage source + - `INSTRUMENT` now takes in an `InstrumentComponent` + - `PROVIDES_TRIM_MATERIAL`, `PROVIDES_BANNER_PATTERNS` handles a provider for their associated types. + - `BEES` now takes in a `Bees` component + - `BREAK_SOUND` - The sound to play when the item breaks. +- `net.minecraft.data.recipes` + - `RecipeProvider#trimSmithing` now takes in the key for the `TrimPattern` + - `SmithingTrimRecipeBuilder` now takes in a holder for the `TrimPattern` +- `net.minecraft.world.entity.LivingEntity` + - `blockUsingShield` -> `blockUsingItem` + - `blockedByShield` -> `blockedByItem` + - `hurtCurrentlyUsedShield` is removed + - `canDisableBlocking` -> `getSecondsToDisableBlocking`, not one-to-one + - `applyItemBlocking` - Applies the damage reduction done when blocking an attack with an item. + - `isDamageSourceBlocked` is removed +- `net.minecraft.world.entity.player.Player#disableShield` -> `net.minecraft.world.item.component.BlocksAttacks#disable` +- `net.minecraft.world.item` + - `AnimalArmorItem` class is removed + - `ArmorItem` class is removed + - `AxeItem` now extends `Item` + - `BannerPatternItem` class is removed + - `DiggerItem` class is removed + - `FireworkStarItem` class is removed + - `HoeItem` now extends `Item` + - `InstrumentItem` no longer takes in the tag key + - `Item` + - `getBreakingSound` is removed + - `$Properties` + - `tool` - Sets the item as a tool. + - `pickaxe` - Sets the item as a pickaxe. + - `sword` - Sets the item as a sword. + - `axe` - Sets the item as an axe. + - `hoe` - Sets the item as a hoe. + - `shovel` - Sets the item as a shovel. + - `trimMaterial` - Sets the item as providing a trim material. + - `ItemStack#getBreakingSound` is removed + - `PickaxeItem` class is removed + - `ShovelItem` now extends `Item` + - `SwordItem` class is removed + - `ToolMaterial#applyToolProperties` now takes in a boolean of whether the weapon can disable a blocker (e.g., shield) +- `net.minecraft.world.item.component` + - `Bees` - A component that holds the occupants of a beehive. + - `BlocksAttacks` - A component for blocking an attack with a held item. + - `InstrumentComponent` - A component that holds the sound an instrument plays. + - `ProvidesTrimMaterial` - A component that provides a trim material to use on some armor. + - `Tool` now takes in a boolean representing if the tool can destroy blocks in creative + - `Unbreakable` class is removed + - `Weapon` - A data component that holds how much damage the item can do and for how long it disables blockers (e.g., shield). +- `net.minecraft.world.item.equipment` + - `AllowedEntitiesProvider` - A functional interface for getting the entities that are allowed to handle the associated logic. + - `ArmorMaterial` + - `humanoidProperties` -> `Item$Properties#humanoidArmor` + - `animalProperties` -> `Item$Properties#wolfArmor`, `horseArmor` + - `createAttributes` is now public + - `Equippable` + - `equipOnInteract` - When true, the item can be equipped to another entity when interacting with them. + - `saddle` - Creates an equippable for a saddle. + - `equipOnTarget` - Equips the item onto the target entity. + + +#### Extrapolating the Saddles: Equipment Changes + +A new `EquipmentSlot` has been added for saddles, which brings with it new changes for genercizing slot logic. + +First, rendering an equipment slot for an entity can now be handled as an additional `RenderLayer` called `SimpleEquipmentLayer`. This takes in the entity renderer, the `EquipmentLayerRenderer`, the layer type to render, a function to get the `ItemStack` from the entity state, and the adult and baby models. The renderer will attempt to look up the client info from the associated equippable data component and use that to render the laters as necessary. + +Next, instead of having individual lists for each equipment slot on the entity, there is now a general `EntityEquipment` object that holds a delegate to a map of slots to `ItemStack`s. This simplifies the storage logic greatly. + +Finally, equippables can now specify whether an item should be equipped to a mob on interact (usually right-click) by setting `equipOnInteract`. + +- `net.minecraft.client.model` + - `CamelModel` + - `head` is now public + - `createBodyMesh` - Creates the mesh definition for a camel. + - `CamelSaddleModel` - A model for a camel with a saddle. + - `DonkeyModel#createSaddleLayer` - Creates the layer definition for a donkey with a saddle. + - `EquineSaddleModel` - A model for an equine animal with a saddle. + - `PolarBearModel#createBodyLayer` now takes in a boolean for if the entity is a baby +- `net.minecraft.client.renderer.entity.layers.HorseArmorLayer`, `SaddleLayer` -> `SimpleEquipmentLayer` +- `net.minecraft.client.renderer.entity.state` + - `CamelRenderState#isSaddled` -> `saddle`, not one-to-one + - `EquineRenderState#isSaddled` -> `saddle`, not one-to-one + - `PigRenderState#isSaddled` -> `saddle`, not one-to-one + - `SaddleableRenderState` class is removed + - `StriderRenderState#isSaddled` -> `saddle`, not one-to-one + - `CamelRenderState#isSaddled` -> `saddle`, not one-to-one +- `net.minecraft.client.resources.model.EquipmentClientInfo$LayerType` now has: + - `PIG_SADDLE` + - `STRIDER_SADDLE` + - `CAMEL_SADDLE` + - `HORSE_SADDLE` + - `DONKEY_SADDLE` + - `MULE_SADDLE` + - `ZOMBIE_HORSE_SADDLE` + - `SKELETON_HORSE_SADDLE` + - `trimAssetPrefix` - Returns the prefix applied to the texture containing the armor trims for the associated type. +- `net.minecraft.world.entity` + - `EntityEquipment` - A map of slots to item stacks representing the equipment of the entity. + - `EquipmentSlot` + - `SADDLE`, `$Type#SADDLE` + - `canIncreaseExperience` - Whether the slot can increase the amount of experience earned when killing a mob. + - `EquipmentSlotGroup` is now an iterable + - `SADDLE` + - `slots` - Returns the slots within the group. + - `LivingEntity` + - `getEquipSound` - Gets the sound to play when equipping an item into a slot. + - `getArmorSlots`, `getHandSlots`, `getArmorAndBodyArmorSlots`, `getAllSlots` are removed + - `equipment` - The equipment worn by the entity. + - `createEquipment` - Sets the default equipment worn by the entity. + - `drop` - Drops the specified stack. + - `getItemBySlot`, `setItemBySlot` are no longer abstract. + - `verfiyEquippedItem` is removed + - `Mob` + - `isSaddled` - Checks if an item is in the saddle slot. + - `createEquipmentSlotContainer` - Creates a single item container for the equipment slot. + - `OwnableEntity#getRootOwner` - Gets the highest level owner of the entity. + - `Saddleable` interface is removed +- `net.minecraft.world.entity.animal.horse.AbstractHorse` + - `syncSaddletoClients` is removed + - `getBodyArmorAccess` is removed +- `net.minecraft.world.entity.player` + - `Inventory` + - `armor`, `offhand` -> `EQUIPMENT_SLOT_MAPPING`, not one-to-one + - `selected` is now private + - `setSelectedHotbarSlot` -> `setSelectedSlot` + - Getter also exists `getSelectedSlot` + - `getSelected` -> `getSelectedItem` + - Setter also exists `setSelectedItem` + - `getNonEquipmentItems` - Returns the list of non-equipment items in the inventory. + - `getDestroySpeed` is removed + - `getArmor` is removed + - `PlayerEquipment` - Equipment that is worn by the player. +- `net.minecraft.world.item` + - `Item#inventoryTick(ItemStack, Level, Entity, int, boolean)` -> `inventoryTick(ItemStack, ServerLevel, Entity, EquipmentSlot)` + - `SaddleItem` class is removed + +### Weighted List Rework + +The weighted random lists have been redesigned into a basic class that hold weighted entries, and a helper class that can obtain weights from the objects themselves. + +First there is `WeightedList`. It is effectively the replacement for `SimpleWeightedRandomList`, working the exact same way by storing `Weighted` (replacement for `WeightedEntry`) entries in the list itself. Internally, the list is either stored as a flat array of object entries, or the compact weighted list if the total weight is greater than 64. Then, to get a random element, either `getRandom` or `getRandomOrThrow` can be called to obtain an entry. Both of these methods will either return some form of an empty object or exception if there are no elements in the list. + +Then there are the static helpers within `WeightedRandom`. These take in raw lists and some `ToIntFunction` that gets the weight from the list's object. Some methods also take in an integer either representing the largest index to choose from or the entry associated with the weighted index. + +- `net.minecraft.client.resources.model.WeightedBakedModel` now takes in a `WeightedList` instead of a `SimpleWeightedRandomList` +- `net.minecraft.util.random` + - `SimpleWeightedRandomList`, `WeightedRandomList` -> `WeightedList`, now final and not one-to-one + - `contains` - Checks if the list contains this element. + - `Weight` class is removed + - `WeightedEntry` -> `Weighted` + - All `WeightedRandom` static methods now take in a `ToIntFunction` to get the weight of some entry within the provided list +- `net.minecraft.util.valueproviders.WeightedListInt` now takes in a `WeightedList` +- `net.minecraft.world.level.SpawnData#LIST_CODEC` is now a `WeightedList` of `SpawnData` +- `net.minecraft.world.level.biome` + - `Biome#getBackgroundMusic` is now a `WeightedList` of `Music` + - `BiomeSpecialEffects#getBackgroundMusic`, `$Builder#backgroundMusic` is now a `WeightedList` of `Music` + - `MobSpawnSettings#EMPTY_MOB_LIST`, `getMobs` is now a `WeightedList` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig#spawnPotentialsDefinition`, `lootTablesToEject` now takes in a `WeightedList` +- `net.minecraft.world.level.chunk.ChunkGenerator#getMobsAt` now returns a `WeightedList` +- `net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider` now works with `WeightedList`s +- `net.minecraft.world.level.levelgen.heightproviders.WeightedListHeight` now works with `WeightedList`s +- `net.minecraft.world.level.levelgen.structure.StructureSpawnOverride` now takes in a `WeightedList` +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `PoolAliasBinding#random`, `randomGroup` now takes in a `WeightedList` + - `Random` now takes in a `WeightedList` + - `RandomGroup` now takes in a `WeightedList` +- `net.minecraft.world.level.levelgen.structure.structures.NetherFortressStructure#FORTRESS_ENEMIES` is now a `WeightedList` + +### Tickets + +Tickets have been reimplemented into a half type registry-like, half hardcoded system. The underlying logic of keeping a chunk loaded or simulated for a certain period of time still exists; however, the logic associated with each ticket is hardcoded into their appropriate locations, such as the forced or player loading tickets. + +Tickets begin with their registered `TicketType`, which contains information about how many ticks should the ticket should last for (or `0` when permanent), whether the ticket should be saved to disk, and what the ticket is used for. A ticket has two potential uses: one for loading the chunk and keeping it loaded, and one for simulating the chunk based on the expected movement of the ticket creator. Most ticks specify that they are for both loading and simulation. + +There are two special types that have additional behavior associated with them. `TicketType#FORCED` has some logic for immediately loading the chunk and keeping it loaded. `TicketType#UNKNOWN` cannot be automatically timed out, meaning they are never removed unless explicitly specified. + +```java +// You need to register the ticket type to `BuiltInRegistries#TICKET_TYPE` +public static final TicketType EXAMPLE = new TicketType( + // The amount of ticks before the ticket is removed + // Set to 0 if it should not be removed + 0L, + // Whether the ticket should be saved to disk + true, + // What the ticket will be used for + TicketType.TicketUse.LOADING_AND_SIMULATION +); +``` + +Then there is the `Ticket` class, which are actually stored and handled within the `TicketStorage`. The `Ticket` class takes in the type of the ticket and uses it to automatically populate how long until it expires. It also takes in the ticket level, which is a generally a value of 31 (for entity ticking and block ticking), 32 (for block ticking), or 33 (only can access static or modify, not naturally update) minus the radius of chunks that can be loaded. A ticket is then added to the process by calling `TicketStorage#addTicketWithRadius` or its delegate `ServerChunkCache#addTicketWithRadius`. There is also `addTicket` if you wish to specify the ticket manually rather than having it computed based on its radius. + +- `net.minecraft.server.level` + - `ChunkMap` now takes in a `TicketStorage` + - `$TrackedEntity#broadcastIgnorePlayers` - Broadcasts the packet to all player but those within the UUID list. + - `DistanceManager` + - `chunksToUpdateFutures` is now protected and takes in a `TicketStorage` + - `purgeStaleTickets` -> `net.minecraft.world.level.TicketStorage#purgeStaleTickets` + - `getTicketDebugString` -> `net.minecraft.world.level.TicketStorage#getTicketDebugString` + - `getChunkLevel` - Returns the current chunk level or the simulated level when the provided boolean is true. + - `getTickingChunks` is removed + - `removeTicketsOnClosing` is removed + - `$ChunkTicketTracker` -> `LoadingChunkTracker`, or `SimulationChunkTracker` + - `ServerChunkCache` + - `addRegionTicket` -> `addTicketWithRadius`, or `addTicket` + - `removeRegionTicket` -> `removeTicketWithRadius` + - `removeTicketsOnClosing` -> `deactivateTicketsOnClosing` + - `Ticket` is no longer final or implements `Comparable` + - The constructor no longer takes in a key + - `CODEC` + - `setCreatedTick`, `timedOut` -> `resetTicksLeft`, `decreaseTicksLeft`, `isTimedOut`; not one-to-one + - `TicketType` is now a record and no longer has a generic + - `getComparator` is removed + - `doesLoad`, `doesSimulate` - Checks whether the ticket use is for their particular instance. + - `$TicketUse` - What a ticket can be used for. + - `TickingTracker` -> `SimulationChunkTracker` +- `net.minecraft.world.level.ForcedChunksSavedData` -> `TicketStorage` +- `net.minecraft.world.level.chunk.ChunkSource` + - `updateChunkForced` now returns a boolean indicating if the chunk has been forcefully loaded + - `getForceLoadedChunks` - Returns all chunks that have been forcefully loaded. + +### The Game Test Overhaul + +Game tests have been completely overhauled into a registry based system, completely revamped from the previous automatic annotation-driven system. However, most implementations required to use the system must be implemented yourself rather than provided by vanilla. As such, this explanation will go over the entire system, including which parts need substantial work to use it similarly to the annotation-driven system of the previous version. + +#### The Environment + +All game tests happen within some environment. Most of the time, a test can occur independent of the area, but sometimes, the environment needs to be curated in some fashion, such as checking whether an entity or block does something at a given time or whether. To facilitate the setup and teardown of the environment for a given test instance, a `TestEnvironmentDefinition` is created. + +A `TestEnvironmentDefinition` works similarly to the `BeforeBatch` and `AfterBatch` annotations. The environment contains two methods `setup` and `teardown` that manage the `ServerLevel` for the test. The environments are structured in a type-based registry system, meaning that every environment registers a `MapCodec` to built-in registry `minecraft:test_environment_definition_type` that is then consumed via the `TestEnvironmentDefinition` in a datapack registry `minecraft:test_environment`. + +Vanilla, by default, provides the `minecraft:default` test environment which does not do anything. However, additional test environments can be created using the available test definition types. + +##### Game Rules + +This environment type sets the game rules to use for the test. During teardown, the game rules are set back to their default value. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:game_rules", + + // A list of game rules with boolean values to set + "bool_rules": [ + { + // The name of the rule + "rule": "doFireTick", + "value": false + } + // ... + ], + + // A list of game rules with integer values to set + "int_rules": [ + { + "rule": "playersSleepingPercentage", + "value": 50 + } + // ... + ] +} +``` + +##### Time of Day + +This environment type sets the time to some non-negative integer, similar to how the `/time set ` command is used. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:time_of_day", + + // Sets the time of day in the world + // Common values: + // - Day -> 1000 + // - Noon -> 6000 + // - Night -> 13000 + // - Midnight -> 18000 + "time": 13000 +} +``` + +##### Weather + +This environment type sets the weather, similar to how the `/weather` command is used. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:weather", + + // Can be one of three values: + // - clear (No weather) + // - rain (Rain) + // - thunder (Rain and thunder) + "weather": "thunder" +} +``` + +##### Function + +This environment type provides two `ResourceLocation`s to mcfunctions to setup and teardown the level, respectively. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:function", + + // The setup mcfunction to use + // If not specified, nothing will be ran + // Points to 'data/examplemod/function/example/setup.mcfunction' + "setup": "examplemod:example/setup", + + // The teardown mcfunction to use + // If not specified, nothing will be ran + // Points to 'data/examplemod/function/example/teardown.mcfunction' + "teardown": "examplemod:example/teardown" +} +``` + +##### Composite + +If multiple combinations are required, then the composite environment type (aptly named `all_of`) can be used to string multiple of the above environment types together. + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "minecraft:all_of", + + // A list of test environments to use + // Can either specified the registry name or the environment itself + "definitions": [ + // Points to 'data/minecraft/test_environment/default.json' + "minecraft:default", + { + // A raw environment definition + "type": "..." + } + // ... + ] +} +``` + +#### Custom Types + +If none of the types above work, then a custom definition can be created by implementing `TestEnvironmentDefinition` and creating an associated `MapCodec`: + +```java +public record ExampleEnvironmentType(int value1, boolean value2) implements TestEnvironmentDefinition { + + // Construct the map codec to register + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(ExampleEnvironmentType::value1), + Codec.BOOL.fieldOf("value2").forGetter(ExampleEnvironmentType::value2) + ).apply(instance, ExampleEnvironmentType::new) + ); + + @Override + public void setup(ServerLevel level) { + // Setup whatever is necessary here + } + + @Override + public void teardown(ServerLevel level) { + // Undo whatever was changed within the setup method + // This should either return to default or the previous value + } + + @Override + public MapCodec codec() { + return CODEC; + } +} +``` + +Then register the `MapCodec` using whatever registry method is required by your mod loader: + +```java +Registry.register( + BuiltInRegistries.TEST_ENVIRONMENT_DEFINITION_TYPE, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_environment_type"), + ExampleEnvironmentType.CODEC +); +``` + +Finally, you can use it in your environment definition: + +```json5 +// examplemod:example_environment +// In 'data/examplemod/test_environment/example_environment.json' +{ + "type": "examplemod:example_environment_type", + + "value1": 0, + "value2": true +} +``` + +#### Test Functions + +The initial concept of game tests were structured around running functions from `GameTestHelper` determining whether the test succeeds or fails. Test functions are the registry-driven representation of those. Essentially, every test function is a method that takes in a `GameTestHelper`. + +At the moment, vanilla only provides `minecraft:always_pass`, which just calls `GameTestHelper#succeed`. Test functions are also not generated, meaning it simply runs the value with whatever is provided. As such, a test function should generally represent a single old game test: + +```java +Registry.register( + BuiltInRegistries.TEST_FUNCTION, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_function"), + (GameTestHelper helper) -> { + // Run whatever game test commands you want + helper.assertBlockPresent(...); + + // Make sure you have some way to succeed + helper.succeedIf(() -> ...); + } +); +``` + +#### Test Data + +Now that we have environments and test functions, we can get into defining our game test. This is done through `TestData`, which is the equivalent of the `GameTest` annotation. The only things changed are that structures are now referenced by their `ResourceLocation` via `structure`, `GameTest#timeoutTicks` is now renamed to `TestData#maxTicks`, and instead of specifying `GameTest#rotationSteps`, you simply provide the `Rotation` via `TestData#rotation`. Everything else remains the same, just represented in a different format. + +#### The Game Test Instance + +With the `TestData` in hand, we can now link everything together through the `GameTestInstance`. This instance is what actually represents a single test. Once again, vanilla only provides the default `minecraft:always_pass`, so we will need to construct the instance ourselves. + +##### The Original Instance + +The previous game tests are implemented using `minecraft:function`, which links a test function to the test data. + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "minecraft:function", + + // Points to a 'Consumer' in the test function registry + "function": "examplemod:example_function", + + // The 'TestData' information + + // The environment to run the test in + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // The structure used for the game test + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + // The number of ticks that the game test will run until it automatically fails + "max_ticks": 400, + // The number of ticks that are used to setup everying required for the game test + // This is not counted towards the maximum number of ticks the test can take + // If not specified, defaults to 0 + "setup_ticks": 50, + // Whether the test is required to succeed to mark the batch run as successful + // If not specified, defaults to true + "required": true, + // Specifies how the structure and all subsequent helper methods should be rotated for the test + // If not specified, nothing is rotated + "rotation": "clockwise_90", + // When true, the test can only be ran through the `/test` command + // If not specified, defaults to false + "manual_only": true, + // Specifies the maximum number of times that the test can be reran + // If not specified, defaults to 1 + "max_attempts": 3, + // Specifies the minimum number of successes that must occur for a test to be marked as successful + // This must be less than or equal to the maximum number of attempts allowed + // If not specified, defaults to 1 + "required_successes": 1, + // Returns whether the structure boundary should keep the top empty + // This is currently only used in block-based test instances + // If not specified, defaults to false + "sky_access": false +} +``` + +##### Block-Based Instances + +Vanilla also provides a block-based test instance via `minecraft:block_based`. This is handled through via structures with test blocks receiving signals via `Level#hasNeighborSignal`. To start, a structure must have one test block which is set to its start mode. This block is then triggered, sending a fifteen signal pulse for one tick. Structures may then have as many test blocks with either a log, accept, or fail mode set. Log test blocks also send a fifteen signal pulse when activated. Accept and fail test blocks either succeed or fail the game test if any of them are activated (success takes precedent over failure). + +As this test relies on test blocks in the structure, no additional information is required other than the test data: + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "minecraft:block_based", + + // The 'TestData' information + + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + "max_ticks": 400, + "setup_ticks": 50, + "required": true, + "rotation": "clockwise_90", + "manual_only": true, + "max_attempts": 3, + "required_successes": 1, + "sky_access": false +} +``` + +##### Custom Tests + +If you need to implement your own test-based logic, whether using a more dynamic feature ~~or because you can't be bothered to migrated all of your data logic to the new systems~~, you can create your own custom test instance by extending `GameTestInstance` and creating an associated `MapCodec`: + +```java +public class ExampleTestInstance extends GameTestInstance { + + // Construct the map codec to register + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(test -> test.value1), + Codec.BOOL.fieldOf("value2").forGetter(test -> test.value2), + TestData.CODEC.forGetter(ExampleTestInstance::info) + ).apply(instance, ExampleTestInstance::new) + ); + + public ExampleTestInstance(int value1, boolean value2, TestData> info) { + super(info); + } + + @Override + public void run(GameTestHelper helper) { + // Run whatever game test commands you want + helper.assertBlockPresent(...); + + // Make sure you have some way to succeed + helper.succeedIf(() -> ...); + } + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + protected MutableComponent typeDescription() { + // Provides a description about what this test is supposed to be + // Should use a translatable component + return Component.literal("Example Test Instance"); + } +} +``` + +Then register the `MapCodec` using whatever registry method is required by your mod loader: + +```java +Registry.register( + BuiltInRegistries.TEST_INSTANCE_TYPE, + ResourceLocation.fromNamespaceAndPath("examplemod", "example_test_instance"), + ExampleTestInstance.CODEC +); +``` + +Finally, you can use it in your test instance: + +```json +// examplemod:example_test +// In 'data/examplemod/test_instance/example_test.json' +{ + "type": "examplemod:example_test_instance", + + "value1": 0, + "value2": true, + + // The 'TestData' information + + // Points to 'data/examplemod/test_environment/example_environment.json' + "environment": "examplemod:example_environment", + // Points to 'data/examplemod/structure/example_structure.nbt' + "structure": "examplemod:example_structure", + "max_ticks": 400, + "setup_ticks": 50, + "required": true, + "rotation": "clockwise_90", + "manual_only": true, + "max_attempts": 3, + "required_successes": 1, + "sky_access": false +} +``` + +- `net.minecraft.client.renderer.blockentity` + - `BeaconRenderer` now has a generic that takes in a subtype of `BlockEntity` and `BeaconBeamOwner` + - `StructureBlockRenderer` -> `BlockEntityWithBoundingBoxRenderer`, not one-to-one +- `net.minecraft.core.registries.Registries#TEST_FUNCTION`, `TEST_ENVIRONMENT_DEFINITION_TYPE`, `TEST_INSTANCE_TYPE` +- `net.minecraft.gametest.Main` - The entrypoint for the game test server. +- `net.minecraft.gametest.framework` + - `AfterBatch`, `BeforeBatch` annotations are removed + - `BlockBasedTestInstance` - A test instance for testing the test block. + - `BuiltinTestFunctions` - Contains all registered test functions. + - `FailedTestTracker` - An object for holding all game tests that failed. + - `FunctionGameTestInstance` - A test instance for running a test function. + - `GameTest` annotation is removed + - `GameTestAssertException` now extends `GameTestException` + - `GameTestException` - An exception thrown during the execution of a game test. + - `GameTestBatch` now takes in an index and environment definition instead of a name and batch setups + - `GameTestBatchFactory` + - `fromTestFunction` -> `divideIntoBatches`, not one-to-one + - `toGameTestInfo` is removed + - `toGameTestBatch` now takes in an environment definition and an index + - `$TestDecorator` - Creates a list of test infos from a test instance and level. + - `GameTestEnvironments` - Contains all environments used for batching game test instances. + - `GameTestGenerator` annotation is removed + - `GameTestHelper` + - `tickBlock` - Ticks the block at the specific position. + - `assertionException` - Returns a new exception to throw on error. + - `getBlockEntity` now takes in a `Class` to cast the block entity to + - `assertBlockTag` - Checks whether the block at the position is within the provided tag. + - `assertBlock` now takes in a block -> component function for the error message. + - `assertBlockProperty` now takes in a `Component` instead of a string + - `assertBlockState` now takes in either nothing, a blockstate -> component function, or a supplied component + - `assertRedstoneSignal` now takes in a supplied component + - `assertContainerSingle` - Asserts that a container contains exactly one of the item specified. + - `assertEntityPosition`, `assertEntityProperty` now takes in a component + - `fail` now takes in a `Component` for the error message + - `assertTrue`, `assertValueEqual`, `assertFalse` now takes in a component + - `GameTestInfo` now takes in a holder-wrapped `GameTestInstance` instead of a `TestFunction` + - `setStructureBlockPos` -> `setTestBlockPos` + - `placeStructure` now returns nothing + - `getTestName` - `id`, not one-to-one + - `getStructureBlockPos` -> `getTestBlockPos` + - `getStructureBlockEntity` -> `getTestInstanceBlockEntity` + - `getStructureName` -> `getStructure` + - `getTestFunction` -> `getTest`, `getTestHolder`, not one-to-one + - `getOrCalculateNorthwestCorner`, `setNorthwestCorner` are removed + - `fail` now takes in a `Component` or `GameTestException` instead of a `Throwable` + - `getError` now returns a `GameTestException` instead of a `Throwable` + - `GameTestInstance` - Defines a test to run. + - `GameTestInstances` - Contains all registered tests. + - `GameTestMainUtil` - A utility for running the game test server. + - `GameTestRegistry` class is removed + - `GameTestSequence` + - `tickAndContinue`, `tickAndFailIfNotComplete` now take in an integer for the tick instead of a long + - `thenFail` now takes in a supplied `GameTestException` instead of a `Throwable` + - `GameTestServer#create` now takes in an optional string and boolean instead of the collection of test functions and the starting position + - `GeneratedTest` - A object holding the test to run for the given environment and the function to apply + - `GameTestTicker$State` - An enum containing what state the game test ticker is currently executing. + - `GameTestTimeoutException` now extends `GameTestException` + - `ReportGameListener#spawnBeacon` is removed + - `StructureBlockPosFinder` -> `TestPosFinder` + - `StructureUtils` + - `testStructuresDir` is now a path + - `getStructureBounds`, `getStructureBoundingBox`, `getStructureOrigin`, `addCommandBlockAndButtonToStartTest` are removed + - `createNewEmptyStructureBlock` -> `createNewEmptyTest`, not one-to-one + - `getStartCorner`, `prepareTestStructure`, `encaseStructure`, `removeBarriers` are removed + - `findStructureBlockContainingPos` -> `findTestContainingPos` + - `findNearestStructureBlock` -> `findNearestTest` + - `findStructureByTestFunction`, `createStructureBlock` are removed + - `findStructureBlocks` -> `findTestBlocks` + - `lookedAtStructureBlockPos` -> `lookedAtTestPos` + - `TestClassNameArgument` is removed + - `TestEnvironmentDefinition` - Defines the environment that the test is run on by setting the data on the level appropriately. + - `TestFinder` no longer contains a generic for the context + - `$Builder#allTests`, `allTestsInClass`, `locateByName` are removed + - `$Builder#byArgument` -> `byResourceSelection` + - `TestFunction` -> `TestData`, not one-to-one + - `TestFunctionArgument` -> `net.minecraft.commands.arguments.ResourceSelectorArgument` + - `TestFunctionFinder` -> `TestInstanceFinder` + - `TestFunctionLoader` - Holds the list of test functions to load and run. + - `UnknownGameTestException` - An exception that is thrown when the error of the game test is unknown. +- `net.minecraft.network.protocol.game` + - `ClientboundTestInstanceBlockState` - A packet sent to the client containing the status of a test along with its size. + - `ServerboundSetTestBlockPacket` - A packet sent to the server to set the information within the test block to run. + - `ServerboundTestInstanceBlockActionPacket` - A packet sent to the server to set up the test instance within the test block. +- `net.minecraft.world.entity.player.Player` + - `openTestBlock` - Opens a test block. + - `openTestInstanceBlock` - Opens a test block for a game test instance. +- `net.minecraft.world.level.block` + - `TestBlock` - A block used for running game tests. + - `TestInstanceBlock` - A block used for managing a single game test. +- `net.minecraft.world.level.block.entity` + - `BeaconBeamOwner` - An interface that represents a block entity with a beacon beam. + - `BeaconBlockEntity` now implements `BeaconBeamOwner` + - `BeaconBeamSection` -> `BeaconBeamOwner$Section` + - `BoundingBoxRenderable` - An interface that represents a block entity that can render an arbitrarily-sized bounding box. + - `StructureBlockEntity` now implements `BoundingBoxRenderable` + - `TestBlockEntity` - A block entity used for running game tests. + - `TestInstanceBlockEntity` - A block entity used for managing a single game test. +- `net.minecraft.world.level.block.state.properties.TestBlockMode` - A property for representing the current state of the game tests associated with a test block. + +### Data Component Getters + +The data component system can now be represented on arbitrary objects through the use of the `DataComponentGetter`. As the name implies, the getter is responsible for getting the component from the associated type key. Both block entities and entities use the `DataComponentGetter` to allow querying the internal data, such as variant information or custom names. They both also have methods for collecting the data components from another holder (via `applyImplicitComponents` or `applyImplicitComponent`). Block entities also contain a method for collection to another holder via `collectImplicitComponents`. + +#### Items + +`ItemSubPredicate`s have been completely replaced with `DataComponentPredicate`s. Each sub predicate has its appropriate analog within the system. + +- `net.minecraft.advancements.critereon.*` -> `net.minecraft.core.component.predicates.*` + - `ItemAttributeModifiersPredicate` -> `AttributeModifiersPredicate` + - `ItemBundlePredicate` -> `BundlePredicate` + - `ItemContainerPredicate` -> `ContainerPredicate` + - `ItemCustomDataPredicate` -> `CustomDataPredicate` + - `ItemDamagePredicate` -> `DamagePredicate` + - `ItemEnchantmentsPredicate` -> `EnchantmentsPredicate` + - `ItemFireworkExplosionPredicate` -> `FireworkExplosionPredicate` + - `ItemFireworksPredicate` -> `FireworksPredicate` + - `ItemJukeboxPlayablePredicate` -> `JukeboxPlayablePredicate` + - `ItemPotionsPredicate` -> `PotionsPredicate` + - `ItemSubPredicate` -> `DataComponentPredicate`, not one-to-one + - `SINGLE_STREAM_CODEC` + - `ItemSubPredicates` -> `DataComponentPredicates`, not one-to-one + - `ItemTrimPredicate` -> `TrimPredicate` + - `ItemWritableBookPredicate` -> `WritableBookPredicate` + - `ItemWrittenBookPredicate` -> `WrittenBookPredicate` +- `net.minecraft.advancements.critereon` + - `BlockPredicate` now takes in a `DataComponentMatchers` for matching any delegated component data + - `DataComponentMatchers` - A predicate that operates on a `DataComponentGetter`, matching any exact and partial component data on the provider. + - `EntityPredicate` now takes in a `DataComponentMatchers` instead of a `Optional` + - `ItemPredicate` now takes in a `DataComponentMatchers` for matching any delegated component data + - `NbtPredicate#matches` now takes in a `DataComponentGetter` instead of an `ItemStack` + - `SingleComponentItemPredicate` now implements `DataComponentPredicate` instead of `ItemSubPredicate` + - `matches(ItemStack, T)` -> `matches(T)` +- `net.minecraft.core.component` + - `DataComponentPatch` + - `DELIMITED_STREAM_CODEC` + - `$CodecGetter` - Gets the codec for a given component type. + - `DataComponentPredicate` -> `DataComponentExactPredicate` + - `isEmpty` - Checks if the expected components list within the predicate is empty. +- `net.minecraft.core.registries.Registries#ITEM_SUB_PREDICATE_TYPE` -> `DATA_COMPONENT_PREDICATE_TYPE`, not one-to-one +- `net.minecraft.world.item.AdventureModePredicate` no longer takes in a boolean to show in tooltip +- `net.minecraft.world.item` + - `BannerItem#appendHoverTextFromBannerBlockEntityTag` is removed + - `Item#appendHoverText(ItemStack, Item.TooltipContext, List, TooltipFlag)` -> `appendHoverText(ItemStack, Item.TooltipContext, TooltipDisplay, Consumer, TooltipFlag)`, now deprecated + - `ItemStack` + - `addToTooltip` is now public + - `addDetailsToTooltip` - Appends the component details of an item to the tooltip. + - `JukeboxPlayable#showInTooltip` is removed +- `net.minecraft.world.item.component` + - `BlockItemStateProperties` now implements `TooltipProvider` + - `ChargedProjectiles` now implements `TooltipProvider` + - `CustomData#itemMatcher` is removed + - `DyedItemColor#showInTooltip` is removed + - `FireworkExplosion#addShapeNameTooltip` is removed + - `ItemAttributeModifiers#showInTooltip` is removed + - `ItemContainerContents` now implements `TooltipProvider` + - `SeededContainerLoot` now implements `TooltipProvider` + - `TooltipDisplay` - A component that handles what should be hidden within an item's tooltip. + - `TooltipProvider#addToTooltip` now takes in a `DataComponentGetter` +- `net.minecraft.world.item.enchantment.ItemEnchantments#showInTooltip` is removed +- `net.minecraft.world.item.equipment.trim.ArmorTrim#showInTooltip` is removed +- `net.minecraft.world.item.trading.ItemCost` now takes in a `DataComponentExactPredicate` instead of a `DataComponentPredicate` +- `net.minecraft.world.level.block.Block#appendHoverText` is removed +- `net.minecraft.world.level.block.entity` + - `BannerPatternLayers` now implements `TooltipProvider` + - `PotDecorations` now implements `TooltipProvider` +- `net.minecraft.world.level.saveddata.maps.MapId` now implements `TooltipProvider` + +#### Entities + +Some `EntitySubPredicate`s for entity variants have been transformed into data components stored on the held item due to a recent change on `EntityPredicate` now taking in a `DataComponentExactPredicate` for matching the slots on an entity. + +- `net.minecraft.advancements.critereon` + - `EntityPredicate` now takes in a `DataComponentExactPredicate` to match the equipment slots checked + - `EntitySubPredicate` + - `AXOLTOL` -> `DataComponents#AXOLOTL_VARIANT` + - `FOX` -> `DataComponents#FOX_VARIANT` + - `MOOSHROOM` -> `DataComponents#MOOSHROOM_VARIANT` + - `RABBIT` -> `DataComponents#RABBIT_VARIANT` + - `HORSE` -> `DataComponents#HORSE_VARIANT` + - `LLAMA` -> `DataComponents#LLAMA_VARIANT` + - `VILLAGER` -> `DataComponents#VILLAGER_VARIANT` + - `PARROT` -> `DataComponents#PARROT_VARIANT` + - `SALMON` -> `DataComponents#SALMON_SIZE` + - `TROPICAL_FISH` -> `DataComponents#TROPICAL_FISH_PATTERN`, `TROPICAL_FISH_BASE_COLOR`, `TROPICAL_FISH_PATTERN_COLOR` + - `PAINTING` -> `DataComponents#PAINTING_VARIANT` + - `CAT` -> `DataComponents#CAT_VARIANT`, `CAT_COLLAR` + - `FROG` -> `DataComponents#FROG_VARIANT` + - `WOLF` -> `DataComponents#WOLF_VARIANT`, `WOLF_COLLAR` + - `PIG` -> `DataComponents#PIG_VARIANT` + - `register` with variant subpredicates have been removed + - `catVariant`, `frogVariant`, `wolfVariant` are removed + - `$EntityHolderVariantPredicateType`, `$EntityVariantPredicateType` are removed + - `SheepPredicate` no longer takes in the `DyeColor` +- `net.minecraft.client.renderer.entity.state.TropicalFishRenderState#variant` -> `pattern` +- `net.minecraft.core.component` + - `DataComponentGetter` - A getter that obtains data components from some object. + - `DataComponentHolder`, `DataComponentMap` now extends `DataComponentGetter` + - `DataComponentExactPredicate` is now a predicate of a `DataComponentGetter` + - `expect` - A predicate that expects a certain value for a data component. + - `test(DataComponentHolder)` is removed + - `DataComponents` + - `SHEEP_COLOR` - The dye color of a sheep. + - `SHULKER_COLOR` - The dye color of a shulker (box). + - `COW_VARIANT` - The variant of a cow. + - `CHICKEN_VARIANT` - The variant of a chicken. + - `WOLF_SOUND_VARIANT` - The sounds played by a wolf. +- `net.minecraft.world.entity` + - `Entity` now implements `DataComponentGetter` + - `applyImplicitComponents` - Applies the components from the getter onto the entity. This should be overriden by the modder. + - `applyComponentsFromItemStack` - Applies the components from the stack onto the entity. + - `castComponentValue` - Casts the type of the object to the component type. + - `setComponent` - Sets the component data onto the entity. + - `applyImplicitComponent` - Applies the component data to the entity. This should be overriden by the modder. + - `applyImplicitComponentIfPresent` - Applies the component if it is present on the getter. + - `EntityType#appendCustomNameConfig` -> `appendComponentsConfig` + - `VariantHolder` interface is removed + - As such, all `setVariant` methods on relevant entities are private while the associated data can also be obtained from the `DataComponentGetter` +- `net.minecraft.world.entity.animal` + - `CatVariant#CODEC` + - `Fox$Variant#STREAM_CODEC` + - `FrogVariant#CODEC` + - `MushroomCow$Variant#STREAM_CODEC` + - `Parrot$Variant#STREAM_CODEC` + - `Rabbit$Variant#STREAM_CODEC` + - `Salmon$Variant#STREAM_CODEC` + - `TropicalFish` + - `getVariant` -> `getPattern` + - `$Pattern` now implements `TooltipProvider` + - `Wolf` -> `.wolf.Wolf` + - `WolfVariant` -> `.wolf.WolfVariant`, now a record, taking in an `$AssetInfo` and a `SpawnPrioritySelectors` + - `WolfVariants` -> `.wolf.WolfVariants` +- `net.minecraft.world.entity.animal.axolotl.Axolotl$Variant#STREAM_CODEC` +- `net.minecraft.world.entity.animal.horse` + - `Llama$Variant#STREAM_CODEC` + - `Variant#STREAM_CODEC` +- `net.minecraft.world.entity.animal.wolf` + - `WolfSoundVariant` - The sounds played by a wolf. + - `WolfSoundVariants` - All vanilla wolf sound variants. +- `net.minecraft.world.entity.decoration.Painting` + - `VARIANT_MAP_CODEC` is removed + - `VARIANT_CODEC` is now private +- `net.minecraft.world.entity.npc.VillagerDataHolder#getVariant`, `setVariant` are removed +- `net.minecraft.world.entity.variant.VariantUtils`- A utility for getting the variant info of an entity. +- `net.minecraft.world.item` + - `ItemStack#copyFrom` - Copies the component from the getter. + - `MobBucketItem#VARIANT_FIELD_CODEC` -> `TropicalFish$Pattern#STREAM_CODEC` +- `net.minecraft.world.level.block.entity.BlockEntity#applyImplicitComponents` now takes in a `DataComponentGetter` + - `$DataComponentInput` -> `DataComponentGetter` +- `net.minecraft.world.level.Spawner` methods now takes in a `CustomData` instead of the `ItemStack` itself + +##### Spawn Conditions + +To allow entities to spawn variants randomly but within given conditions, a new registry called `SPAWN_CONDITION_TYPE` was added. These take in `SpawnCondition`s: a selector that acts like a predicate to take in the context to see whether the given variant can spawn there. All of the variants are thrown into a list and then ordered based on the selected priorty stored in the `SpawnProritySelectors`. Those with a higher priority will be checked first, with multiple of the same priority selected in the order they are provided. Then, all variants on the same priority level where a condition has been met is selected at random. + +```json5 +// For some object where there are spawn conditions +[ + { + // The spawn condition being checked + "condition": { + "type": "minecraft:biome", + // Will check that the biome the variant is attempting to spawn in is in the forest + "biomes": "#minecraft:is_forest" + }, + // Will check this condition first + "priority": 1 + }, + { + // States that the condition will always be true + "priority": 0 + } +] +``` + +- `net.minecraft.core.registries.Registries#SPAWN_CONDITION_TYPE` +- `net.minecraft.world.entity.variant` + - `BiomeCheck` - A spawn condition that checks whether the entity is in one of the given biomes. + - `MoonBrightnessCheck` - A spawn condition that checks the brightness of the moon. + - `PriorityProvider` - An interface which orders the condition selectors based on some priority integer. + - `SpawnCondition` - Checks whether an entity can spawn at this location. + - `SpawnConditions` - The available spawn conditions to choose from. + - `SpawnContext` - An object holding the current position, level, and biome the entity is being spawned within. + - `SpawnPrioritySelectors` - A list of spawn conditions to check against the entity. Used to select a random variant to spawn in a given location. + - `StructureCheck` - A spawn condition that checks whether the entity is within a structure. + +##### Variant Datapack Registries + +Frog, cat, cow, chicken, pig, and wolf, and wolf sound variants are datapack registry objects, meaning that most references now need to be referred to through the `RegistryAccess` or `HolderLookup$Provider` instance. + +For a frog, cat, or wolf: + +```json5 +// A file located at: +// - `data/examplemod/frog_variant/example_frog.json` +// - `data/examplemod/cat_variant/example_cat.json` +// - `data/examplemod/wolf_variant/example_wolf.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/cat/example_cat.png` + "asset_id": "examplemod:entity/cat/example_cat", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +For a pig, cow, or chicken: +```json5 +// A file located at: +// - `data/examplemod/pig_variant/example_pig.json` +// - `data/examplemod/cow_variant/example_cow.json` +// - `data/examplemod/chicken_variant/example_chicken.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/pig/example_pig.png` + "asset_id": "examplemod:entity/pig/example_pig", + // Defines the `PigVariant$ModelType` that's used to select what entity model to render the pig variant with + "model": "cold", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +For a wolf sound variant: +```json5 +// A file located at: +// - `data/examplemod/wolf_sound_variant/example_wolf_sound.json`` +{ + // The registry name of the sound event to play randomly on idle + "ambient_sound": "minecraft:entity.wolf.ambient", + // The registry name of the sound event to play when killed + "death_sound": "minecraft:entity.wolf.death", + // The registry name of the sound event to play randomly when angry on idle + "growl_sound": "minecraft:entity.wolf.growl", + // The registry name of the sound event to play when hurt + "hurt_sound": "minecraft:entity.wolf.hurt", + // The registry name of the sound event to play randomly + // 1/3 of the time on idle when health is max + "pant_sound": "minecraft:entity.wolf.pant", + // The registry name of the sound event to play randomly + // 1/3 of the time on idle when health is below max + "whine_sound": "minecraft:entity.wolf.whine" +} +``` + +##### Client Assets + +Raw `ResourceLocation`s within client-facing files for identifiers or textures are being replaced with objects defining an idenfitier along with a potential texture path. There are three main objects to be aware of: `ClientAsset`, `ModelAndTexture`, and `MaterialAssetGroup`. + +`ClientAsset` is an id/texture pair used to point to a texture location. By default, the texture path is contructed from the id, with the path prefixed with `textures` and suffixed with the PNG extension. + +`ModelAndTexture` is a object/client asset pair used when a renderer should select between multiple models. Usually, the renderer creates a map of the object type to the model, and the object provided to the `ModelAndTexture` is used as a lookup into the map. + +`MaterialAssetGroup` is a handler for rendering an equipment asset with some trim material. It takes in the base texture used to overlay onto the armor along with any overrides for a given equipment asset. + +- `net.minecraft.advancements.DisplayInfo` now takes in a `ClientAsset` instead of only a `ResourceLocation` for the background texture +- `net.minecraft.client.model` + - `AdultAndBabyModelPair` - Holds two `Model` instances that represents the adult and baby of some entity. + - `ChickenModel#createBaseChickenModel` - Creates the default chicken model. + - `ColdChickenModel` - A variant model for a chicken in cold temperatures. + - `ColdCowModel` - A variant model for a cow in cold temperatures. + - `ColdPigModel` - A variant model for a big in cold temperatures. + - `CowModel#createBaseCowModel` - Creates the base model for a cow. + - `PigModel#createBasePigModel` - Creates the default pig model. + - `WarmCowModel` - A variant model for a cow in warm temperatures. +- `net.minecraft.client.renderer.entity` + - `ChickenRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` + - `CowRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` + - `PigRenderer` now extends `MobRenderer` instead of `AgeableMobRenderer` +- `net.minecraft.client.renderer.entity.layers.SheepWoolUndercoatLayer` - A layer that renders the wool undercoat of a sheep. +- `net.minecraft.client.renderer.entity.state` + - `CowRenderState` - A render state for a cow entity. + - `SheepRenderState` + - `getWoolColor` - Returns the integer color of the sheep wool. + - `isJebSheep` - Returns whether the sheep's name contains the `jeb_` prefix. +- `net.minecraft.core.ClientAsset` - An object that holds an identifier and a path to some texture. +- `net.minecraft.data.loot.EntityLootSubProvider#killedByFrogVariant` now takes in a `HolderGetter` for the `FrogVariant` +- `net.minecraft.data.tags.CatVariantTagsProvider` class is removed +- `net.minecraft.tags.CatVariantTags` class is removed +- `net.minecraft.world.entity.animal` + - `AbstractCow` - An abstract animal that represents a cow. + - `Chicken#setVariant`, `getVariant` - Handles the variant information of the chicken. + - `ChickenVariant` - A class which defines the common-sideable rendering information and biome spawns of a given chicken. + - `ChickenVariants` - Holds the keys for all vanilla chicken variants. + - `Cow` now extends `AbstractCow`. + - `CowVariant` - A class which defines the common-sideable rendering information and biome spawns of a given cow. + - `CowVariants` - Holds the keys for all vanilla cow variants. + - `CatVariant(ResourceLocation)` -> `CatVariant(ClientAsset, SpawnPrioritySelectors)` + - `CatVariants` - Holds the keys for all vanilla cat variants. + - `FrogVariant` -> `.frog.FrogVariant` + - `FrogVariant(ResourceLocation)` -> `FrogVariant(ClientAsset, SpawnPrioritySelectors)` + - `MushroomCow` now extends `AbstractCow` + - `PigVariant` - A class which defines the common-sideable rendering information and biome spawns of a given pig. + - `TemperatureVariants` - An interface which holds the `ResourceLocation`s that indicate an entity within a different temperature. +- `net.minecraft.world.entity.variant.ModelAndTexture` - Defines a model with its associated texture. +- `net.minecraft.world.item.equipment.trim` + - `MaterialAssetGroup` - An asset defines some base and the permutations based on the equipment worn. + - `TrimMaterial` now takes in a `MaterialAssetGroup` instead of the raw base and overrides + +### Tags and Parsing + +Tags have received a rewrite, removing any direct references to types while also sealing and finalizing related classes. Getting a value from the tag now returns an `Optional`-wrapped entry, unless you call one of the `get*Or`, where you specify the default value. Objects, on the other hand, do not take in a default, instead returning an empty variant of the desired tag. + +```java +// For some `CompoundTag` tag + +// Read a value +Optional value1 = tag.getInt("value1"); +int value1Raw = tag.getIntOr("value1", 0); + +// Reading another object +Optional childTag = tag.getCompound("childTag"); +CompoundTag childTagRaw = tag.getCopmoundOrEmpty("childTag"); +``` + +#### Writing with Codecs + +`CompoundTag`s now have methods to write and read using a `Codec` or `MapCodec`. For a `Codec`, it will store the serialized data inside the key specified. For a `MapCodec`, it will merge the fields onto the top level tag. + +```java +// For some Codec CODEC and MapCodec MAP_CODEC +// We will also have ExampleObject example +CompoundTag tag = new CompoundTag(); + +// For a codec +tag.store("example_key", CODEC, example); +Optional fromCodec = tag.read("example_key", CODEC); + +// For a map codec +tag.store(MAP_CODEC, example); +Optional fromMapCodec = tag.read(MAP_CODEC); +``` + +#### Command Parsers + +The packrat parser has been updated with new rules and systems, allowing commands to have parser-based arguments. This comes from the `CommandArgumentParser`, which parses some grammar to return the desired object. The parser is then consumed by the `ParserBasedArgument`, where it attempts to parse a string and build any suggestions based on what you're currently typing. These are both handled through the `Grammar` class, which implements `CommandArgumentParser`, constructed using a combination of atoms, dictionaries, rules, and terms. + +- `net.minecraft.commands.ParserUtils#parseJson` +- `net.minecraft.commands.arguments` + - `ComponentArgument` now extends `ParserBasedArgument` + - `NbtTagArgument` now extends `ParserBasedArgument` + - `StyleArgument` now extends `ParserBasedArgument` +- `net.minecraft.commands.arguments.item.ItemPredicateArgument` now extends `ParserBasedArgument` +- `net.minecraft.nbt` + - `ByteArrayTag`, now final, no longer takes in a list object + - `ByteTag` is now a record + - `CollectionTag` is now a sealed interface, no longer extending `AbstractList` or has a generic + - `set`, `add` is removed + - `remove` now returns a `Tag` + - `get` - Returns the tag at the specified index. + - `getElementType` is removed + - `size` - Returns the size of the collection. + - `isEmpty` - Returns whether the collection has no elements. + - `stream` - Streams the elements of the collection. + - `CompoundTag` is now final + - `store` - Writes a codec or map codec to the tag. + - `read` - Reads the codec or map codec-encoded value from the tag. + - `getFloatOrDefault`, `getIntOrDefault`, `getLongOrDefault` - Gets the value with the associated key, or the default if not present or an exception is thrown. + - `storeNullable` - When not null, uses the codec to write the value to the tag. + - `putUUID`, `getUUID`, `hasUUID` is removed + - `getAllKeys` -> `keySet` + - `values`, `forEach` - Implements the standard map operations. + - `putByteArray`, `putIntArray` with list objects are removed + - `getTagType` is removed + - `contains` is removed + - `get*`, `get*Or` - Returns an optional wrapped object for the key, or the default value specified is using the `Or` methods. + - `DoubleTag` is now a record + - `EndTag` is now a record + - `FloatTag` is now a record + - `IntArrayTag`, now final, no longer takes in a list object + - `IntTag` is now a record + - `ListTag`, now final, extends `AbstractList` + - `addAndUnwrap` - Adds the tag to the list where, if a compound with one element, adds the inner tag instead. + - `get*`, `get*Or` - Returns an optional wrapped object for the key, or the default value specified is using the `Or` methods. + - `compoundStream` - Returns a flat map of all `CompoundTag`s within the list. + - `LongArrayTag`, now final, no longer takes in a list object + - `LongTag` is now a record + - `NbtIo#readUnnamedTag` is now public, visible for testing + - `NbtOps` now has a private constructor + - `NbtUtils` + - `getDataVersion` now has an overload that takes in a `Dynamic` + - `createUUID`, `loadUUID` is removed + - `readBlockPos`, `writeBlockPos` is removed + - `NumericTag` is now a sealed interface that implements `PrimitiveTag` + - `getAsLong` -> `longValue` + - `getAsInt` -> `intValue` + - `getAsShort` -> `shortValue` + - `getAsByte` -> `byteValue` + - `getAsDouble` -> `doubleValue` + - `getAsFloat` -> `floatValue` + - `getAsNumber` -> `box` + - `as*` - Returns an optional wrapped of the numeric value. + - `PrimitiveTag` - A sealed interface that represents the tag data as being a primitive object. + - `ShortTag` is now a record + - `SnbtGrammar` - A parser creater for stringified NBTs. + - `SnbtOperations` - A helper that contains the built in operations for parsing some value. + - `StringTag` is now a record + - `StringTagVisitor` + - `visit` -> `build`, not one-to-one + - `handleEscape` -> `handleKeyEscape`, now private + - `Tag` is now a sealed interface + - `as*` -> Attempts to cast the tag as one of its subtypes, returning an empty optional on failure. + - `getAsString` -> `asString`, not one-to-one + - `TagParser` now holds a generic referncing the type of the intermediate object to parse to + - The constructor now takes in a grammar, or `create` constructs the grammar from a `DynamicOps` + - `AS_CODEC` -> `FLATTENED_CODEC` + - `parseTag` -> `parseCompoundFully` or `parseCompoundAsArgument` + - Additional methods such as `parseFully`, `parseAsArgument` parse to some intermediary object + - These are all instance methods + - `readKey`, `readTypedValue` is removed + - `TagType#isValue` is removed +- `net.minecraft.util.parsing.packrat` + - `CachedParseState` - A parse state that caches the parsed positions and controls when reading. + - `Control#hasCut` - Returns whether the control flow for the grammar has a cut for the reading object. + - `DelayedException` - An interface that creates an exception to throw. + - `Dictionary` + - `put` now returns a `NamedRule` + - `put(Atom, Term, Rule.RuleAction)` -> `putComplex` + - `get` -> `getOtThrow`, not one-to-one + - `forward` - Gets or writes the term to the dictionary. + - `namedWithAlias` - Creates a new reference to the named atom or its alias. + - `ErrorCollector$Nop` - A error collector that does nothing. + - `NamedRule` - A rule that has an associated name. + - `ParseState` is now an interface + - Caching logic has moved to `CachedParseState` + - `scope` - Returns the current scope being analyzed within the parsing object. + - `parse` now takes in a `NamedRule` instead of an `Atom` + - `acquireControl`, `releaseControl` - Handles obtaining the `Control` used during parsing. + - `silent` - Returns a `ParseState` that does not collect any errors. + - `Rule` + - `parse`, `$RuleAction#run` now returns a nullable value rather than an optional + - `SimpleRuleAction` now implements `$RuleAction` + - `Scope#pushFrame`, `popFrame`, `splitFrame`, `clearFrameValues`, `mergeFrame` - Handles the management of parsing terms into sections called frames. + - `Term` + - `named` -> `Dictionary#named`, not one-to-one + - `repeated`, `repeatedWithTrailingSeparator`, `repeatedWithoutTrailingSeparator` - Handles terms similar to varargs that are repeated and sticks them into a list. + - `positiveLookahead`, `negativeLookahead` - Handles a term that matches information based on what is following. + - `fail` - Mark a term as having failed during parsing. +- `net.minecraft.util.parsing.packrat.commands` + - `CommandArgumentParser` - Parses a string into an argument for use with a command. + - `Grammar` now takes in a `NamedRule` for the top rather than an `Atom` + - `GreedyPatternParseRule` - A rule that attempts to match the provided pattern greedily, assuming that if a region matches, that the matched group can be obtained. + - `GreedyPredicateParseRule` - A rule that attempts to match the accepted characters greedily, making sure that the string reaches a minimum size. + - `NumberRunParseRule` - A rule that attempts to parse a number from the string. + - `ParserBasedArgument` - A command argument that uses a parser to extract the value. + - `ResourceLookupRule` now takes in a `NamedRule` for the id parser rather than an `Atom` + - `StringReaderParserState` now extends `CachedParsedState` + - The `Dictoionary` is no longer taken in + - `StringReaderTerms#characters` - Matches multiple characters in a string, usually for catching both the lowercase and uppercase variant. + - `UnquotedStringParseRule` - A rule that reads part of the sequence as an unquoted string, making sure it reaches a minimum size. + +### Saved Data, now with Types + +`SavedData` has been reworked to abstract most of its save and loading logic into a separate `SavedDataType`. This means that the `save` override and additional `load` and `factory` methods are now handled within the `SavedDataType` itself. + +To construct a `SavedDataType`, you need to pass in four paramters. First is the string identifier, used to resolve the `.dat` file holding your information. This must be a vaild path. Then there is the constructor, which takes in the `SavedData$Context` to return an instance of your data object when no information is present. Following that is the codec, which takes in the `SavedData$Context` and returns a `Codec` to read and write your saved data. Finally, there is the `DataFixTypes` used for data fixers. As this is a static enum, you will either need to inject into the enum itself, if you plan on using vanilla data fixers, or patch out the `update` call within `DimensionDataStorage#readTagFromDisk` to pass in a null value. + +```java +// Our saved data instance +public class ExampleSavedData extends SavedData { + + // The saved data type + public static final SavedDataType TYPE = new SavedDataType<>( + // Best to preface the identifier with your mod id followed by an underscore + // Slashes will throw an error as the folders are not present + // Will resolve to `saves//data/examplemod_example.dat` + "examplemod_example", + // Constructor for the new instance + ExampleSavedData::new, + // Codec factory to encode and decode the data + ctx -> RecordCodecBuilder.create(instance -> instance.group( + RecordCodecBuilder.point(ctx.levelOrThrow()), + Codec.INT.fieldOf("value1").forGetter(data -> data.value1), + Codec.BOOL.fieldOf("value2").forGetter(data -> data.value2) + ).apply(instance, ExampleSavedData::new)); + ); + + private final ServerLevel level; + private final int value1; + private final boolean value2; + + + // For the new instance + private ExampleSavedData(ServerLevel.Context ctx) { + this(ctx.levelOrThrow(), 0, false); + } + + // For the codec + // The constructors don't need to be public if not using `DimensionDataStorage#set` + private ExampleSavedData(ServerLevel level, int value1, boolean value2) { + this.level = level; + this.value1 = value1; + this.value2 = value2; + } + + // Other methods here +} + +// With access to the DimensionDataStorage storage +ExampleSavedData data = storage.computeIfAbsent(ExampleSavedData.TYPE); +``` + +- `net.minecraft.server.ServerScoreboard` + - `dataFactory` is removed + - `createData` now takes in a `$Packed` instance +- `net.minecraft.world.RandomSequences` + - `factory`, `load` is removed + - `codec` - Constructs a codec for the random sequence given the current world seed. +- `net.minecraft.world.entity.raid.Raids` no longer takes in anything + - `getType` - Returns the saved data type based on the current dimension. + - `factory` is removed + - `tick` now takes in the `ServerLevel` + - `getId` - Gets the identifier for the raid instance. + - `canJoinRaid` no longer takes in the raid instance + - `load` no longer takes in the `ServerLevel` +- `net.minecraft.world.level.levelgen.structure.structures.StructureFeatureIndexSavedData` + - `factory`, `load` is removed + - `type` - Returns the feature saved data type with its specified id. +- `net.minecraft.world.level.saveddata` + - `SavedData` + - `save` is removed + - `$Factory` record is removed + - `$Context` - Holds the current context that the saved data is being written to. + - `SavedDataType` - A record that represents the type of the saved data, including information on how to construct, save, and load the data. +- `net.minecraft.world.level.saveddata.maps` + - `MapIndex` now has a constructor to take in the last map id + - `factory`, `load` is removed + - `getFreeAuxValueForMap` -> `getNextMapId` + - `MapItemSavedData` + - `factory`, `load` is removed + - `type` - Returns the saved data type using the map id's key. +- `net.minecraft.world.level.storage.DimensionDataStorage` now takes in a `SavedData$Context` + - `computeIfAbsent`, `get` now take in only the `SavedDataType` + - `set` now takes in the `SavedDataType` along with the data instance +- `net.minecraft.world.scores.ScoreboardSaveData` + - `load` -> `loadFrom` + - `pack` - Packs the data into its saved data format. + - `$Packed` - Represents the serializable packed data. + +### Render Pipeline Rework + +Rendering an object to the screen, whether through a shader or a `RenderType`, has been fully or partially reworked, depending on what systems you were using previously. As such, a lot of things need to be reexplained, which a more in-depth look will be below. However, for the people who don't care, here's the TL;DR. + +First, shader JSONs no longer exist. This is replaced by a `RenderPipeline`, which is effectively an in-code substitute. Second, the `RenderPipeline`s forcibly make most abtrarily values into objects. For example, instead of storing the blend function mode id, you store a `BlendFunction` object. Similarly, you no longer store or setup the direct texture objects, but instead manage it through a `GpuTexture`. Finally, the `VertexBuffer` can either draw to the framebuffer by directly passing in the `RenderPipeline`, updating any necessary uniforms in the consumer, or by passing in the `RenderType`. + +Now, for those who need the details, let's jump into them. + +#### Abstracting Open GL + +As many are aware, Minecraft has been abstracting away their OpenGL calls and constants, and this release is no different. All of the calls to GL codes, except `BufferUsage`, have been moved out of object references, to be obtained typically by calling `GlConst$toGl`. However, with all of the other rendering reworks, there are numerous changes and complexities that require learning an entirely new system, assuming you're not using `RenderType`s. + +Starting from the top, all calls to the underlying render system goes through `GpuDevice`, an interface that acts like a general implementation of a render library like OpenGL or Vulkan. The device is responsible for creating buffers and textures, executing whatever commands are desired. Getting the current `GpuDevice` can be accessed through the `RenderSystem` via `getDevice` like so: + +```java +GpuDevice device = RenderSystem.getDevice(); +``` + +The `GpuDevice` can the create either buffers with the desired data or a texture containing information on what to render using `createBuffer` and `createTexture`, respectively. Just for redundancy, buffers hold the vertex data while textures hold the texture (color and depth) data. You should generally cache the buffer or texture object for later use with any additional data updated as needed. For reference, buffers are typically created by using a `BufferBuilder` with a `ByteBufferBuilder` to build the `MeshData` first, before passing that into `createBuffer`. + +With the desired buffers and textures set up, how do we actually modify render them to the screen? Well, this is handled through the `CommandEncoder`, which can also be optained from the device via `GpuDevice#createCommandEncoder`. The encoder contain the familiar read and write methods along with a few extra to clear texture to a given color or simply blit the the texture immediately to the screen (`presentTexture`). However, the most important method here is `createRenderPass`. This takes in the `GpuTexture` to draw to the screen along with a default ARGB color for the background. Additionally, it can take in a depth texture as well. This should be created using a try with resources block like so: + +```java +// We will assume you have constructed a `GpuTexture` texture for the color data +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(this.texture, OptionalInt.of(0xFFFFFFFF))) { + // Setup things here + +} +``` + +Within the `RenderPass`, you can set the `RenderPipeline` to use, which defines the associated shaders, bind any samplers from other targets or set uniforms, scissor a part of a screen to render, and set the vertex and index buffers used to define the vertices to render. Finally, everything can be drawn to the screen using one of the `draw` methods, providing the starting index and the vertex count. + +```java +// If the buffers/textures are not created or cached, create them here +// Any methods ran from `CommandEncoder` cannot be run while a render pass is open +RenderSystem.AutoStorageIndexBuffer indices = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS); +GpuBuffer vertexBuffer = RenderSystem.getQuadVertexBuffer(); +GpuBuffer indexBuffer = indices.getBuffer(6); + +// We will assume you have constructed a `GpuTexture` texture for the color data +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(this.texture, OptionalInt.of(0xFFFFFFFF))) { + + // Set pipeline information along with any samplers and uniforms + pass.setPipeline(EXAMPLE_PIPELINE); + pass.setVertexBuffer(0, vertexBuffer); + pass.setIndexBuffer(indexBuffer, indices.type()); + pass.bindSampler("Sampler0", RenderSystem.getShaderTexture(0)); + + // Then, draw everything to the screen + // In this example, the buffer just contains a single quad + // For those unaware, the vertex count is 6 as a quad is made up of 2 triangles, so 2 vertices overlap + pass.drawIndexed(0, 6); +} +``` + +However, unless you need such fine control, it is recommended to use a `RenderType` with the `MultiBufferSource` when necessary as that sets up most things for you. + +#### Object References + +Most raw references to GL codes used for determining the mode and handling the texture have been replaced with objects. As the TL;DR previously mentioned, these are stored typically as some sort of enum or object that can then be resolved to their GL counterparts. Some objects contain their reference identifier directly, like `BlendFunction`. Others are simply placeholders that are resolved in their appropriate location, like `DepthTestFunction` whose enum values are converted via `RenderPipeline#toGl`. + +However, the biggest change is the addition of the `GpuTexture`. This is responsible for managing anything to do with creating, writing, and releasing a texture written to some buffer. At initialization, the texture is created and bound, with any necessary parameters set for mipmaps and texture formats. These `GpuTexture`s are stored and referenced everywhere, from the depth and color targets for a `RenderTarget` to the texture backing a `TextureAtlas`. Then, once no longer need, the texture is released by calling `#close`. Note that although technically `#bind` can be called again, the texture is already considered deleted and should not be used. + +If, for some reason, you need to use a `GpuTexture`, it's actually quite simple to use. First, you just construct the `GpuTexture` via `GpuDevice#createTexture`. Then, if you need to change any of the addressing or texture mipmap filters, you can apply them whenever before writing. + +```java +public class MyTextureManager { + + private final GpuTexture texture; + + public MyTextureManager() { + this.texture = RenderSystem.getDevice().createTexture( + // The texture name, used for logging and debugging + "Example Texture", + // The format of the texture pixels, can be one of three values that + // Values: (texture internal format, texel data format, texel data type, pixel size) + // - RGBA8 (GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4) + // - RED8 (GL_R8, GL_RED, GL_UNSIGNED_BYTE, 1) + // - DEPTH32 (GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT, 4) + TextureFormat.RGBA8, + // Width of the texture + 16, + // Height of the texture + 16, + // The mipmap level and maximum level-of-detail (minimum of 1) + 1 + ); + + // Set the texture mode for the UV component + // Values: + // - REPEAT (GL_REPEAT) + // - CLAMP_TO_EDGE (GL_CLAMP_TO_EDGE) + this.texture.setAddressMode( + // The mode to use for the U component (GL_TEXTURE_WRAP_S) + AddressMode.CLAMP_TO_EDGE, + // The mode to use for the V component (GL_TEXTURE_WRAP_R) + AddressMode.REPEAT + ); + + // Sets the filter functions used for scaling the texture on the screen + // Values (default, for mipmaps): + // - NEAREST (GL_NEAREST, GL_NEAREST_MIPMAP_LINEAR) + // - LINEAR (GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR) + this.texture.setTextureFilter( + // The mode to use for the texture minifying function (GL_TEXTURE_MIN_FILTER) + FilterMode.LINEAR, + // The mode to use for the texture magnifying function (GL_TEXTURE_MAG_FILTER) + FilterMode.NEAREST, + // Whether mipmaps should be used for the minifying function (should have a higher mipmap level than 1 when true) + false + ); + } +} +``` + +Then, whenever you want to upload something to the texture, you call `CommandEncoder#writeToTexture` or `CommandEncoder#copyTextureToTexture`. This either takes in the `NativeImage` to write from or an `IntBuffer` with the texture data and a `NativeImage$Format` to use. + +```java +// Like other buffer/texture modification methods, this must be done outside of a render pass +// We will assume you have some `NativeImage` image to load into the texture +RenderSystem.getDevice().createCommandEncoder().writeToTexture( + // The texture (destination) being written to + this.texture, + // The image (source) being read from + image, + // The mipmap level + 0, + // The starting destination x offset + 0, + // The starting destination y offset + 0, + // The destination width (x size) + 16, + // The desintation height (y size) + 16, + // The starting source x offset + 0, + // The starting source y offset + 0 +) +``` + +Finally, once you're done with the texture, don't forget to release it via `#close` if it's not already handled for you. + +#### Render Pipelines + +Previously, a pipeline was constructed using a JSON that contained all metadata from the vertex and fragement shader to their defined values, samplers, and uniforms. However, this has all been replaced with an in-code solution that more localizes some parts of the JSON and some parts that were relegated to the `RenderType`. This is known as a `RenderPipeline`. + +A `RenderPipeline` can be constructed using its builder via `RenderPipeline#builder`. A pipeline can then be built by calling `build`. If you want the shader to be pre-compiled without any additional work, the final pipeline can be passed to `RenderPipeline#register`. However, you can also handle the compilation yourself if more graceful fail states are desired. If you have snippets that are used across multiple pipelines, then a partial pipeline can be built via `$Builder#buildSnippet` and then passed to the constructing pipelines in the `builder` method. + +> The following enums described in the examples have their GL codes provided with them as they have been abstracted away. + +```java +// This assumes that RenderPipeline#register has been made public through some form +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipelines.register( + RenderPipeline.builder() + // The name of the pipeline (required) + .withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example")) + // The location of the vertex shader, relative to 'shaders' (required) + // Points to 'assets/examplemod/shaders/example.vsh' + .withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + // The location of the fragment shader, relative to 'shaders' (required) + // Points to 'assets/examplemod/shaders/example.fsh' + .withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + // The format of the vertices within the shader (required) + .withVertexFormat( + // The vertex format + DefaultVertexFormat.POSITION_TEX_COLOR, + // The mode of the format + VertexFormat.Mode.QUADS + ) + // Adds constants that can be referenced within the shaders + // Can specify a name in addition to an int / float to represent its value + // If no value is specified, then it should be gated with a #ifdef / #endif block + .withShaderDefines("ALPHA_CUTOUT", 0.5) + // Adds the texture sampler2Ds that can be referenced within the shaders + // Typically, the shader textures stored in the `RenderSystem` is referenced via `Sampler0` - `Sampler11` + // - `Sampler0` is usually always present, but these should be set up beforehand + // Additionally, for render targets, `InSampler` is typically present, along with any defined in a postpass + .withSampler("Sampler0") + // Adds uniforms that can be referenced within the shaders + // These are just definitions which are then populated by default or by the caller depending on the scenario + // Defaults can be found in `CompiledShaderProgram#setupUniforms` + .withUniform("ModelOffset", UniformType.VEC3) + // Custom uniforms must be set manually as the vanilla batching system does not support such an operation + .withUniform("CustomUniform", UniformType.INT) + // Sets the depth test functions used rendering objects at varying distances from the camera + // Values: + // - NO_DEPTH_TEST (GL_ALWAYS) + // - EQUAL_DEPTH_TEST (GL_EQUAL) + // - LEQUAL_DEPTH_TEST (GL_LEQUAL) + // - LESS_DEPTH_TEST (GL_LESS) + // - GREATER_DEPTH_TEST (GL_GREATER) + .withDepthTestFunction(DepthTestFunction.LEQUAL_DEPTH_TEST) + // Sets how the polygons should render + // Values: + // - FILL (GL_FILL) + // - WIREFRAME (GL_LINE) + .withPolygonMode(PolygonMode.FILL) + // When true, can cull front or back-facing polygons + .withCull(false) + // Specifies the functions to use when blending two colors with alphas together + // Made up of the `GlStateManager$SourceFactor` and `GlStateManager$DestFactor` + // First two are for RGB, the last two are for alphas + // If nothing is specified, then blending is disabled + .withBlend(BlendFunction.TRANSLUCENT) + // Determines whether to mask writing colors and alpha to the draw buffer + .withColorWrite( + // Mask RGB + false, + // Mask alpha + false + ) + // Determines whether to mask writing values to the depth buffer + .withDepthWrite(false) + // Determines the logical operation to apply when applying an RGBA color to the framebuffer + .withColorLogic(LogicOp.NONE) + // Sets the scale and units used to calculate the depth values for the polygon. + // This takes the place of the polygon offset. + .withDepthBias(0f, 0f) + .build() +); +``` + +From there, the pipeline can either be used directly or through some `RenderType`: + +```java +// This will assume that RenderType#create is made public +public static final RenderType EXAMPLE_RENDER_TYPE = RenderType.create( + // The name of the render type + "examplemod:example", + // The size of the buffer + // Or 4MB + 4194304, + // Whether it effects crumbling that is applied to block entities + false, + // Whether the vertices should be sorted before upload + true, + // The pipeline to use + EXAMPLE_PIPIELINE, + // Any additional composite state settings to apply + RenderType.CompositeState.builder().createCompositeState(RenderType.OutlineProperty.NONE) +); +``` + +The pipeline can then be drawn by creating the `RenderPass` and setting the `RenderPipeline` to use your pipeline. As for the `RenderType`, the associated buffer can be obtained using `MultiBufferSource#getBuffer`. Note that custom uniforms should not be used within `RenderType`s as they cannot be set easily. + +```java +// Since we are using a custom uniform, we must handle it ourselves +// We will assume we have some `GpuTexture` texture to write to + +// Create the render pass to use +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass( + // The GPU color texture to write to + this.texture, + // The clear color in ARGB format + OptionalInt.of(0xFFFFFFFF), + // The depth texture and the clear depth value can also be constructed here + ) +) { + // Add the pipeline and our uniform + pass.setPipeline(EXAMPLE_PIPELINE); + pass.setUniform("CustomUniform", 1); + + // Set any additional sampler and the vertex/index buffers to use + + // Finally, call one of the draw functions + // Takes in the first index and the index count to draw for the vertices + pass.draw(...); +} +``` + +#### Post Effects + +Given that the pipeline JSONs have been stripped, this also effects the post effects. The `program` is replaced with directly specifying the `vertex_shader` and the `fragment_shader`. Additionally, uniforms must specify their `type`. + +```json5 +// Before 1.21.5 (for some pass in 'passes') +{ + // Same as before + "inputs": [ /*...*/ ], + "output": "swap", + + // Replaced by 'vertex_shader', 'fragement_shader' + "program": "minecraft:post/box_blur", + + "uniforms": [ + { + "name": "BlurDir", + // Required + "values": [ 1.0, 0.0 ] + }, + { + "name": "Radius", + // Required + "values": [ 0.0 ] + } + ] +} + +// 1.21.1 (for some pass in 'passes') +{ + // Same as before + "inputs": [ /*...*/ ], + "output": "swap", + + // Relative to 'shaders' + // Points to 'assets/minecraft/shaders/post/blur.vsh' + "vertex_shader": "minecraft:post/blur", + // Points to 'assets/minecraft/shaders/post/box_blur.fsh' + "fragment_shader": "minecraft:post/box_blur", + + + "uniforms": [ + { + "name": "BlurDir", + // Specifies the type to use for this uniform + // One of `Uniform$Type`: + // - int + // - ivec3 + // - float + // - vec2 + // - vec3 + // - vec4 + // - matrix4x4 + "type": "vec2", + "values": [ 1.0, 0.0 ] + }, + { + "name": "Radius", + "type": "float" + // Values are no longer required + } + ] +} +``` + +Note that if you do not define a value for a uniform, they still must be specified before processing the `PostChain` by calling `#setUniform` within the `RenderPass` consumer of `PostChain#process`. + +```java +// Assume we already got the `PostChain` post +post.process(Minecraft.getInstance().getMainRenderTarget(), GraphicsResourceAllocator.UNPOOLED, pass -> { + pass.setUniform("Radius", 0.4f); +}); +``` + +- `com.mojang.blaze3d.GpuOutOfMemoryException` - An exception thrown when a texture could not be allocated on the GPU. +- `com.mojang.blaze3d.buffers` + - `BufferType` no longer stores the GL codes, now in `GlConst#toGl` + - `BufferUsage` no longer stores the GL codes, now in `GlConst#toGl` + - `isReadable`, `isWritable` - Returns whether the buffer can be read from or written to. + - `GpuBuffer` is now abstract + - Constructor with `ByteBuffer` is removed + - `size` - Returns the size of the buffer. + - `type` - Returns the type of the buffer. + - `resize`, `write`, `read`, `bind` is removed + - `usage` - Returns the usage of the buffer. + - `close` is now abstract + - `isClosed` - Returns whether the buffer has been closed. + - `$ReadView` is now an interface that defines the buffer data and how to close the view +- `com.mojang.blaze3d.font.SheetGlyphInfo#upload` now takes in a `GpuTexture` +- `com.mojang.blaze3d.opengl` + - `DirectStateAccess` - An interface that creates and binds data to some framebuffer. + - `$Core` - An implementation of DSA that modifies the framebuffer without binding them to the context. + - `$Emulated` - An abstraction over DSA that still binds the context. + - `GlBuffer` - An implementation of the `GpuBuffer` for OpenGL. + - `GlCommandEncoder` - An implementation of the `CommandEncoder` for OpenGL. + - `GlDebugLabel` - A labeler for handling debug references to GL-specified data structures. + - `GlDevice` - An implementation of `GpuDevice` for OpenGL. + - `GlRenderPass` - An implementation of `RenderPass` for OpenGL. + - `GlRenderPipeline` - An implementation of `CompiledRenderPipeline` for OpenGL. + - `GlTexture` - An implementation of `GpuTexture` for OpenGL. + - `VertexArrayCache` - A cache for binding and uploading a vertex array to the OpenGL pipeline. +- `com.mojang.blaze3d.pipeline` + - `BlendFunction` - A class that holds the source and destination colors and alphas to apply when overlaying pixels in a target. This also holds all vanilla blend functions. + - `CompiledRenderPipeline` - An interface that holds the pipeline with all necessary information to render to the screen. + - `RenderPipeline` - A class that contains everything required to render some object to the screen. It acts similarly to a render state before being applied. + - `RenderTarget` now takes in a string representing the name of the target + - `colorTextureId` -> `colorTexture`, now a `GpuTexture` + - Same with `getColorTextureId` -> `getColorTexture` + - `depthBufferId` -> `depthTexture`, now a `GpuTexture` + - Same with `getDepthTextureId` -> `getDepthTexture` + - `filterMode` is now a `FilterMode` + - Same with `setFilterMode` for the int parameter + - `blitAndBlendToScreen` no longer takes in the viewport size parameters + - `framebufferId` is removed + - `checkStatus` is removed + - `bindWrite`, `unbindWrite`, `setClearColor` is removed + - `blitToScreen` no longer takes in any parameters + - `blitAndBlendToScreen` -> `blitAndBlendToTexture`, not one-to-one + - `clear` is removed + - `unbindRead` is removed +- `com.mojang.blaze3d.platform` + - `DepthTestFunction` - An enum representing the supported depth tests to apply when rendering a sample to the framebuffer. + - `DisplayData` is now a record + - `withSize` - Creates a new instance with the specified width/height. + - `withFullscreen` - Creates a new instance with the specified fullscreen flag. + - `FramerateLimitTracker` + - `getThrottleReason` - Returns the reason that the framerate of the game was throttled. + - `isHeavilyThrottled` - Returns whether the current throttle significantly impacts the game speed. + - `$FramerateThrottleReason` - The reason the framerate is throttled. + - `GlConst` -> `com.mojang.blaze3d.opengl.GlConst` + - `#toGl` - Maps some reference object to its associated OpenGL code. + - `GlDebug` -> `com.mojang.blaze3d.opengl.GlDebug` + - `enableDebugCallback` now takes in a set of the enabled extensions. + - `GlStateManager` -> `com.mojang.blaze3d.opengl.GlStateManager` + - `_blendFunc`, `_blendEquation` is removed + - `_glUniform2(int, IntBuffer)`, `_glUniform4(int, IntBuffer)` is removed + - `_glUniformMatrix2(int, boolean, FloatBuffer)`, `_glUniformMatrix3(int, boolean, FloatBuffer)` is removed + - `_glUniformMatrix4(int, boolean, FloatBuffer)` -> `_glUniformMatrix4(int, FloatBuffer)`, transpose is now always false + - `_glGetAttribLocation` is removed + - `_glMapBuffer` is removed + - `_glCopyTexSubImage2D` is removed + - `_glBindRenderbuffer`, `_glDeleteRenderbuffers` is removed + - `glGenRenderbuffers`, `_glRenderbufferStorage`, `_glFramebufferRenderbuffer` is removed + - `_texParameter(int, int, float)` is removed + - `_genTextures`, `_deleteTextures` is removed + - `_texSubImage2D` now has an overload that takes in an `IntBuffer` instead of a `long` for the pixel data + - `upload` is removed + - `_stencilFunc`, `_stencilMask`, `_stencilOp`, `_clearStencil` is removed + - `_getTexImage` is removed + - `_glDrawPixels`, `_readPixels` is removed + - `$CullState#mode` is removed + - `$DestFactor` -> `DestFactor`, codes are removed to be called through `GlConst#toGl` + - `$FramebufferState` enum is removed + - `$LogicOp` -> `LogicOp`, codes are removed to be called through `GlConst#toGl` + - All but `OR_REVERSE` is removed + - `NONE` - Performs no logic operation. + - `$PolygonOffsetState#line` is removed + - `$SourceFactor` -> `SourceFactor`, codes are removed to be called through `GlConst#toGl` + - `$StencilFunc`, `$StencilState` class is removed + - `$Viewport` enum is removed + - `GlUtil` class is removed + - `getVendor`, `getRenderer`, `getOpenGlVersion` (now `getVersion`) have been moved to instance abstract methods on `GpuDevice` + - `getCpuInfo` -> `GLX#_getCpuInfo` + - `GLX` + - `getOpenGLVersionString` is removed + - `_init` -> `_getCpuInfo`, not one-to-one + - `_renderCrosshair`, `com.mojang.blaze3d.systems.RenderSystem#renderCrosshair` -> `net.minecraft.client.gui.components.DebugScreenOverlay#render3dCrosshair`, not one-to-one + - `PolygonMode` - A enum that defines how the polygons will render in the buffer. + - `NativeImage` constructor is now public + - `upload` is removed + - `getPointer` - Returns the pointer to the image data. + - `setPixelABGR` is now public + - `applyToAllPixels` is removed + - `downloadTexture`, `downloadDepthBuffer` is removed + - `flipY` is removed + - `setPackPixelStoreState`, `setUnpackPixelStoreState` is removed + - `$InternalGlFormat` enum is removed + - `$Format` no longer contains the GL codes, now in `GlConst#toGl` + - `TextureUtil` + - `generateTextureId`, `releaseTextureId` is removed + - `prepareImage` is removed + - `writeAsPNG` now takes in a `GpuTexture` instead of the direct three integers + - The overload without the `IntUnaryOperator` is removed +- `com.mojang.blaze3d.resource` + - `RenderTargetDescriptor` now takes in an integer representing the color to clear to + - `ResourceDescriptor` + - `prepare` - Prepares the resource for use after allocation. + - `canUsePhysicalResource` - Typically returns whether a descriptor is already allocated with the same information. +- `com.mojang.blaze3d.shaders` + - `AbstractUniform` -> `com.mojang.blaze3d.opengl.AbstractUniform` + - `setSafe` methods are removed + - `setMat*` methods are removed + - `set(Matrix3f)` is removed + - `CompiledShader` -> `com.mojang.blaze3d.opengl.GlShaderModule` + - `$Type` -> `com.mojang.blaze3d.shaders.ShaderType` + - `Uniform` -> `com.mojang.blaze3d.opengl.Uniform` + - Constructor now takes in a `$Type` instead of the count and an integer representing the type + - `UT_*` fields are removed + - `setFromConfig(ShaderProgramConfig.Uniform)` is removed + - `getTypeFromString` is removed + - `getType` now returns a `$Type` + - `set(int, float)` is removed + - `setSafe` is now private + - `$Type` - Holds the type name as well as how many values it holds. + - `getLocation` is removed + - `getCount` -> `$Type#count` + - `getIntBuffer`, `getFloatBuffer` is removed + - `$Type` -> `com.mojang.blaze3d.shaders.UniformType` +- `com.mojang.blaze3d.systems` + - `CommandEncoder` - An interface that defines how to encode various commands to the underlying render system, such as creating a pass, clearing and writing textures, or reading from the buffer. + - `GpuDevice` - An interface that defines the device or underlying render system used to draw to the screen. This is responsible for creating the buffers and textures while compiling any pipelines. + - `RenderPass` - An interface that defines how a given pass is rendered to some buffer using the underlying render system. This allows binding any samplers and setting the required uniforms. + - `RenderSystem` + - `isOnRenderThreadOrInit`, `assertOnRenderThreadOrInit` is removed + - `recordRenderCall`, `replayQueue` is removed + - `blendFunc`, `blendFuncSeparate`, `blendEquation` is removed + - `texParameter`, `deleteTexture`, `bindTextureForSetup` is removed + - `stencilFunc`, `stencilMask`, `stencilOp` is removed + - `clearDepth` is removed + - `glBindBuffer`, `glBindVertexArray`, `glBufferData`, `glDeleteBuffers` is removed + - `glUniform1i` is removed + - `glUniform1`, `glUniform2`, `glUniform3`, `glUniform4` is removed + - `glUniformMatrix2`, `glUniformMatrix3`, `glUniformMatrix4` is removed + - `setupOverlayColor` now takes in a `GpuTexture` instead of two ints + - `beginInitialization`, `finishInitialization` is removed + - `renderThreadTesselator` is removed + - `setShader`, `clearShader`, `getShader` is removed + - `setShaderTexture` now takes in a `GpuTexture` instead of a bind address + - `getShaderTexture` now returns a `GpuTexture` or null if not present + - `pixelStore`, `readPixels` is removed + - `queueFencedTask`, `executePendingTasks` - Handles sending tasks that run on the GPU asyncronously. + - `SCISSOR_STATE` - Holds the main scissor state. + - `disableDepthTest`, `enableDepthTest` is removed + - `depthFunc`, `depthMask` is removed + - `enableBlend`, `disableBlend` is removed + - `neableCull`, `disableCull` is removed + - `polygonMode`, `enablePolygonOffset`, `disablePolygonOffset`, `polygonOffset` is removed + - `enableColorLogicOp`, `disableColorLogicOp`, `logicOp` is removed + - `bindTexture`, `viewport` is removed + - `colorMask`, `clearColor`, `clear` is removed + - `setupShaderLights(CompiledShaderProgram)` is removed + - `getShaderLights` - Returns the vectors representing the block and sky lights. + - `drawElements`, `getString` is removed + - `initRenderer` now takes in the window pointer, the default shader source, and a boolean of whether to use debug labels + - `setupDefaultState` no longer takes in any parameters + - `maxSupportTextureSize` is removed + - `glDeleteVertexArrays` is removed + - `defaultBlendFunc` is removed + - `setShaderTexture` is removed + - `getQuadVertexBuffer` - Returns a vertex buffer with a quad bound to it. + - `getDevice`, `tryGetDevice` - Returns the `GpuDevice` representing the underlying render system to use. + - `getCapsString` is removed + - `activeTexture` is removed + - `setModelOffset`, `resetModelOffset`, `getModelOffset` - Handles the offset to apply to a model when rendering for the uniform `ModelOffset`. Typically for clouds and world borders. + - `$AutoStorageIndexBuffer#bind` -> `getBuffer`, not one-to-one + - `$GpuAsyncTask` - A record that holds the callback and fence object used to sync information to the GPU. + - `ScissorState` - A class which holds the part of the screen to render. +- `com.mojang.blaze3d.textures` + - `AddressMode` - The mode set for how to render a texture to a specific location. + - `FilterMode` - The mode set for how to render a texture whenever the level-of-detail function determines how the texture should be maximized or minimized. + - `GpuTexture` - A texture that is bound and written to the GPU as required. + - `TextureFormat` - Specifies the format that the texture should be allocated with. +- `com.mojang.blaze3d.vertex` + - `PoseStack` + - `mulPose(Quaternionf)`, `rotateAround` now takes in a `Quaternionfc` instead of a `Quaternionf` + - `clear` -> `isEmpty` + - `mulPose(Matrix4f)` -> `mulPose(Matrix4fc)` + - `$Pose` + - `computeNormalMatrix` is now private + - `transformNormal` now takes in a `Vector3fc` as its first parameter + - `translate`, `scale`, `rotate`, `rotateAround`, `setIdentity`, `mulPose` are now available on the pose itself in addition to the stack + - `VertexBuffer` -> `com.mojang.blaze3d.buffers.GpuBuffer`, not one-to-one + - Some logic is also moved to `VertexFormat` + - `VertexFormat` + - `bindAttributes` is removed + - `setupBufferState`, `clearBufferState`, `getImmediateDrawVertexBuffer` -> `uploadImmediateVertexBuffer`, `uploadImmediateIndexBuffer`; not one-to-one + - `$IndexType` no longer stores the GL codes, now in `GlConst#toGl` + - `$Mode` no longer stores the GL codes, now in `GlConst#toGl` + - `VertexFormatElement` + - `setupBufferState` is removed + - `$Type` no longer stores the GL codes, now in `GlConst#toGl` + - `$Usage` no longer stores the GL function calls, now in `VertexArrayCache#setupCombinedAttributes` +- `com.mojang.math` + - `MatrixUtil` + - `isIdentity`, `isPureTranslation`, `isOrthonormal` now take in a `Matrix4fc` + - `checkProperty` - Checks if the provided property is represented within the matrix. + - `OctahedralGroup` + - `transformation` now returns a `Matrix3fc` + - `fromAnges` -> `fromXYAngles`, not one-to-one + - `Quadrant` - An enum that contains rotations in 90 degree increments. + - `SymmetricGroup3#transformation` now returns a `Matrix3fc` + - `Transformation` now takes in a `Matrix4fc` + - `getMatrix` now returns a `Matrix4fc` + - `getMatrixCopy` - Returns a deep copy of the current matrix. +- `net.minecraft.client.gui.font.FontTexture` now takes in a supplied label string +- `net.minecraft.client.main.GameConfig` now takes in a boolean representing whether to render debug labels +- `net.minecraft.client.renderer` + - `CloudRenderer#render` no longer takes in the `Matrix4f`s used for projection or posing + - `CompiledShaderProgram` -> `com.mojang.blaze3d.opengl.GlProgram` + - `link` now takes in a string for the shader name + - `setupUniforms` now take in the list of `$UniformDescription`s along with a list of names used by the samplers + - `getUniformConfig` is removed + - `bindSampler` now takes in a `GpuTexture` instead of the integer bind identifier + - `parseUniformNode` is removed + - `CoreShaders` -> `RenderPipelines`, not one-to-one + - `LightTexture#getTarget` - Returns the `GpuTexture` that contains the light texture for the current level based on the player. + - `PostChain` + - `load` no longer takes in the `ShaderManager`, now taking in a `ResourceLocation` representing the name of the chain + - `addToFrame`, `process` now takes in a `RenderPass` consumer to apply any additional settings to the pass to render + - `setUniform` is removed + - `setOnRenderPass` - Sets the uniform within the post chain on the `RenderPass` for use in the shaders. + - `PostChainConfig` + - `$Pass` now takes in the ids of the vertex and fragment shader instead of the program id + - `referencedTargets` - Returns the targets referenced in the pass to apply. + - `program` is removed + - `$Uniform` now takes in the type of the uniform along with an optional list of floats if the value does not need to be overridden + - `PostPass` no longer takes in the `CompiledShaderProgram`, now taking in the `RenderPipeline` instead of a string representing the name of the pass + - `addToFrame` now takes in a `RenderPass` consumer to apply any additional settings to the pass to render + - `getShader` is removed + - `$Input#bindTo` now takes in a `RenderPass` instead of the `CompiledShaderProgram` + - `RenderStateShard` + - `$LayerStateShard`s using polygon offsets have been removed + - `getName` - Returns the name of the shard. + - `$TransparencyStateShard` class is removed + - Now handled through `BlendFunction` + - `$ShaderStateShard` class is removed + - Directly referred to by the `VertexBuffer` + - `$CullStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$DepthTestStateShard` class is removed + - Now handled through `DepthTestFunction` + - `$WriteMaskStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$ColorLogicStateShard` class is removed + - Now handled as a setting on the `RenderPipeline` + - `$OutputStateShard` now takes in a supplied `RenderTarget` instead of the runnables for the startup and teardown states + - `RenderType` no longer takes in the `VertexFormat` or `VertexFormat$Mode` + - `SKY`, `END_SKY`, `sky`, `endSky`, `stars` is removed + - `ENTITY_OUTLINE_BLIT`, `entityOutlineBlit` is removed + - `PANORAMA`, `panorama` is removed + - `CREATE_LIGHTMAP`, `createLightmap` is removed + - `createClouds`, `flatClouds`, `clouds`, `cloudsDepthOnly` is removed + - `worldBorder` is removed + - `debugLine` - Returns the `RenderType` associated with the debug line. + - `entityOutlineBlit` - Returns the `RenderType` used for rendering an entity outline. + - `panorama` - Returns the `RenderType` used for rendering panorama mode. + - `createLightmap` - Returns the `RenderType` used for rendering the lightmap texture. + - `create` no longer takes in the `VertexFormat` or `VertexFormat$Mode`, instead the `RenderPipeline` + - `getRenderTarget`, `getRenderPipeline` - Returns the target and pipeline used for rendering. + - `format`, `mode`, `draw` are now abstract + - `$CompositeStateBuilder` methods are now protected + - `$OutlineProperty` is now protected + - `ShaderDefines$Builder#define` now has an overload that takes in an integer + - `ShaderManager` + - `SHADER_INCLUDE_PATH` is now private + - `MAX_LOG_LENGTH` is removed + - `preloadForStartup` is removed, replaced by `GpuDevice#precompilePipeline` + - `getProgram`, `getProgramForLoading` -> `getShader`, not one-to-one + - `linkProgram` now takes in a `RenderPipeline` instead of a `ShaderProgram` and `ShaderProgramConfig` + - `$CompilationCache#getOrCompileProgram`, `getOrCompileShader` -> `getShaderSource`, not one-to-one + - `$Configs` no longer takes in the map of programs + - `$ShaderCompilationKey` record is removed + - `ShaderProgram`, `ShaderProgramConfig` -> `RenderPipeline`, not one-to-one + - `SkyRenderer#renderDarkDisc` no longer takes in the `PoseStack` +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` + - `uploadSectionLayer`, `uploadSectionIndexBuffer` -> `$RenderSection#uploadSectionLayer`, `uploadSectionIndexBuffer` + - `$SectionBuffers` - A class that holds the buffers used to render the sections. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `NOT_ASSIGNED` is removed + - `texture`, `getTexture` - Holds the reference to the texture to render. + - `getId`, `releaseId` is removed + - `bind` is removed + - `DynamicTexture` now takes in the label of the texture + - `SpriteContents#uploadFirstFrame`, `$AnimatedTexture#uploadFirstFrame` now takes in a `GpuTexture` + - `SpriteTicker#tickAndUpload` now takes in the `GpuTexture` + - `TextureAtlasSprite#uploadFirstFrame`, `$Ticker#tickAndUpload` now takes in the `GpuTexture` + +### Model Rework + +The model system has been further separated into models for block states, blocks, and items. As such, the unifying `BakedModel` has been completely removed and separated into their own sections, loaded in three steps: from JSON, resolving dependencies, and then baking for use with the associated block state model or item model. For reference, everything discussed below is what's happenening within `ModelManager#reload` in parallel. + +First, let's start from the base model JSON used between blocks and items. These are loaded into an `UnbakedModel` (specifically `BlockModel`) which contains the familiar properties such as gui light and texture slots. However, one change is the splitting of the elements from their render settings. These elements that hold the render quads are stored in an `UnbakedGeometry`. The `UnbakedGeometry` is responsible for baking the model into a `QuadCollection`, which effectively holds the list of `BakedQuad`s to render. Currently, vanilla only has the `SimpleUnbakedGeometry`, which holds the familiar list of `BlockElement`s. These `UnbakedModel`, once loaded, are then passed to the `ModelDiscovery` for resolving the block state and item models. + +Next we have the `ResolvableModel`s, which is the base of both block state and item models. These models essentially function as markers requesting the `UnbakedModel`s that they will be using. From there, we have their subtypes `BlockStateModel$UnbakedRoot` for the block state JSON and `ItemModel$Unbaked` for the model referenced in the client item JSON. Each of these implement `resolveDependencies` in some way to call `ResolvableModel$Resolver#markDependency` with the model location they would like to use. + +> Technically, `BlockStateModel`s are a bit more complex as variants use `BlockStateModel$Unbaked` during loading which are then transformed into an `$UnbakedRoot` during initialization. + +Now that we know what models that should be loaded, they now have to be put into a usable state for baking. This is the job of the `ModelDiscovery`, which takes in a `ResolvableModel` and loads the `UnbakedModel`s into a `ResolvedModel` on first reference. `ResolvedModel`s are functionally wrappers around `UnbakedModel`s used to resolve all dependency chains, as the name implies. + +From there, model groups are built for `BlockState`s and the textures are loaded, leading to the final step of actually baking the `BlockStateModel` and the `ItemModel`. This is handled through the `bake` methods provided on the `$UnbakedRoot` (or `$Unbaked`) and the `ModelBakery`. In a nutshell, `bake` constructs the list of `BakedQuad`s stored with whatever additional information is desired by the block state or item model itself. The `ResolvedModel`s are obtained from the baker, from which the instance methods are called. For `BlockStateModel`s, this is resolved via `SimpleModelWrapper#bake`, from which the `ModelState` is obtained from the `Variant` data. They stored the baked quads in a `BlockModelPart`. For `ItemModel`s, it just consumes the `BakedQuad`s list directly along with information provided by `ModelRenderProperties#fromResolvedModel`. This does mean that each `BlockStateModel` and `ItemModel` may contain duplicated (but unique) `BakedQuad`s if the same model is referenced in multiple locations. + +#### Block Generators: The Variant Mutator + +Given all the changes that separated out the block state JSON loading, there have also been a number of changes to the `BlockModelGenerators`. While most of them are simply renames (e.g., `BlockStateGenerator` -> `BlockModelDefinitionGenerator`), the major change is the addition of the `VariantMutator`. The `VariantMutator` is functionally a `UnaryOperator` on a `Variant` used to set some setting. This addition has simplified (or more like codec construction) the use of the `PropertyDispatch` for more quickly dispatching blocks with variants based on their properties. + +```java +// Creates a property dispatch on the horizontal facing property +// Applies the associated variants, though if desired, a functional interface can be provided instead +public static final PropertyDispatch ROTATION_HORIZONTAL_FACING = PropertyDispatch.modify(BlockStateProperties.HORIZONTAL_FACING) + .select(Direction.EAST, BlockModelGenerators.Y_ROT_90) + .select(Direction.SOUTH, BlockModelGenerators.Y_ROT_180) + .select(Direction.WEST, BlockModelGenerators.Y_ROT_270) + .select(Direction.NORTH, BlockModelGenerators.NOP); + +// Then, with access to the `Consumer` blockStateOutput +this.blockStateOutput.accept( + MultiVariantGenerator.dispatch(EXAMPLE_BLOCK).with(ROTATION_HORIZONTAL_FACING) +); +``` + +- `net.minecraft.client.data.models` + - `BlockModelGenerators` + - `nonOrientableTrapdoor` -> `NON_ORIENTABLE_TRAPDOOR`, now static + - Constants are now available for common `VariantMutator`s, like rotating the block model some number of degrees + - `texturedModels` -> `TEXTURED_MODELS`, now static + - `MULTIFACE_GENERATOR` is now private + - `plainModel` - Creates a variant from the model location. + - `variant`, `variants` - Creates a regular `MultiVariant` from some number of `Variant`s + - `plainVariant` - Creates a `MultiVariant` with only one model from its location. + - `condition` - Creates a new condition builder for multipart models + - `or` - ORs multiple conditions together. + - Most generator methods now return the `BlockModelDefinitionGenerator`, `Variant`, or `MultiVariant` and take in a `Variant` or `MultiVariant` instead of a `ResourceLocation` pointing to the desired model + - `VariantProperties` have been replaced with `VariantMutator`s + - `Condition$TerminalCondition` is replaced with `Condition` + - `createHorizontalFacingDispatch`, `createHorizontalFacingDispatchAlt`, `createTorchHorizontalDispatch` is removed + - `createFacingDispatch` is removed + - `createRotatedVariant(Block, ResourceLocation)` is removed + - `selectMultifaceProperties` - Creates a map of properties to `VariantMutator`s based on the provided `BlockState` and direction to property function. + - `applyRotation` no longer takes in the `Variant` and returns a `VariantMutator` + - `ItemModelGenerators#generateSpawnEgg` is removed + - `ModelProvider#saveAll` is removed +- `net.minecraft.client.data.models.blockstates` + - `BlockStateGenerator` -> `BlockModelDefinitionGenerator`, not one-to-one + - `Condition` -> `net.minecraft.client.renderer.block.model.multipart.Condition`, not one-to-one + - `validate` -> `instantiate`, not one-to-one + - `ConditionBuilder` - Builds a condition using property values + - `MultiPartGenerator` now implements `BlockModelDefinitionGenerator` + - `with(List)` -> `with(MultiVariant)` + - `with(Variant)` is removed + - `with(Condition, ...)` -> `with(Condition, MultiVariant)` + - Overload taking in `ConditionBuilder` + - `$ConditionalEntry`, `$Entry` is removed + - `MultiVariantGenerator` now implements `BlockModelDefinitionGenerator` + - `multiVariant` -> `dispatch` + - `multiVariant(Block, ...)` -> `dispatch(Block, MultiVariant)` + - `$Empty` - A multi variant entry that matches every block state. + - `PropertyDispatch` has a generic containing the value of the dispatch + - The generic `V` replaces all values of `List` + - `property`, `properties` -> `initial` or `modify` + - `$C*#generateList` methods are removed + - `$*Function` are removed + - `Selector` -> `PropertyValueList`, not one-to-one + - `Variant` -> `net.minecraft.client.renderer.block.model.Variant`, not one-to-one + - `VariantProperties` -> `net.minecraft.client.renderer.block.model.VariantMutator`, not one-to-one + - `VariantProperty` -> `net.minecraft.client.renderer.block.model.VariantMutator$VariantProperty`, not one-to-one +- `net.minecraft.client.renderer.ItemInHandRenderer#renderItem` no longer takes in the boolean representing if the item is held in the left hand +- `net.minecraft.client.renderer.block` + - `BlockModelShaper#stateToModelLocation`, `statePropertiesToString` is removed + - `BlockRenderDispatcher#renderBatched` now takes in a list of `BlockModelPart`s instead of a `RandomSource` + - `ModelBlockRenderer` + - `tesselateBlock`, `tesselateWithAO`, `tesselateWithoutAO` no longer takes in a `RandomSource` and replaces `BlockStateModel` with a list of `BlockModelPart`s + - `renderModel` is now static and no longer takes in the `BlockState` + - `$AmbientOcclusionFace` -> `$AmbientOcclusionRenderStorage` + - `$CommonRenderStorage` - A class that holds some metadata used to render a block at its given position. + - `$SizeInfo` now takes in the direct index rather than computing the info from its direction and a flipped boolean +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` is now a record + - `BlockElement` is now a record + - `from`, `to` are now `Vector3fc` + - `BlockElementFace` now takes in a `Quadrant` for the face rotation + - `getU`, `getV` - Returns the texture coordinate after rotation. + - `$Deserializer#getTintIndex` is now private and static + - `BlockFaceUV` -> `BlockElementFace$UVs`, not one-to-one + - `BlockModel` is now a record, taking in an `UnbakedGeometry` instead of the direct list of `BlockElement`s + - `$Deserializer#getElements` now returns an `UnbakedGeometry` + - `BlockModelDefinition` is now a record, taking in `$SimpleModelSelectors` and `$MultiPartDefinition`s + - `GSON`, `fromStream`, `fromJsonElement` -> `CODEC`, not one-to-one + - `instantiate` now takes in a supplied string instead of the string directly + - `$Deserializer` is removed + - `$MultiPartDefinition` - A record that holds a list of selectors to get for the multi part model. + - `$SimpleModelSelectors` - A record that holds a map of variants to their unbaked model instances. + - `BlockModelPart` - A baked model representation of a block. + - `BlockStateModel` - A baked representation of a block state. + - `collectParts` - Obtains the list of baked models used to render this state. + - `$SimpleCachedUnbakedRoot` - A class that represents a delegate of some `$Unbaked` model. + - `$Unbaked` - An extension over `$UnbakedRoot` that can create a `$SimpleCachedUnbakedRoot` + - `FaceBakery` + - `bakeQuad` now takes in `Vector3fc`s instead of `Vector3f`s + - `recomputeUVs` is removed + - `extractPositions` - Extracts the face positions and passes them to a consumer for use. + - `ItemTransform` is now a record, vectors are `Vector3fc`s + - `MultiVariant` -> `net.minecraft.client.data.models.MultiVariant` + - `CODEC` + - `with` - Creates a `MultiVariant` with the specified mutators. + - `$Deserializer` class is removed + - `SimpleModelWrapper` now implements `BlockModelPart` + - `SimpleUnbakedGeometry` - An unbaked geometry that holds a list of `BlockElement`s to bake. + - `SingleVariant` - A `BlockStateModel` implementation with only one model for its state. + - `UnbakedBlockStateModel` -> `BlockStateModel$UnbakedRoot` + - `Variant` no longer implements `ModelState`, now taking in a `$SimpleModelState` instead of the direct rotation and uv lock + - The constructor now has an overload for only providing the `ResourceLocation` and no longer takes in the weight, leaving that to the `MultiVariant` + - `CODEC` + - `withXRot`, `withYRot`, `withUvLock`, `withModel`, `withState`, `with` - Mutates the variant into a new object with the given setting applied. + - `$Deserializer` class is removed + - `$SimpleModelState` - A record that holds the x/y rotations and uv lock. + - `VariantMutator` - A unary operator on a variant that applies the specified setting to the variant. Used during state generation. +- `net.minecraft.client.renderer.block.model.multipart` + - `AndCondition`, `OrCondition` -> `CombinedCondition`, not one-to-one + - `KeyValueCondition` is now a record that takes in a map of keys to terms to test + - `MultiPart` -> `MultiPartModel$Unbaked` + - `$Definition` + - `CODEC` + - `getMultiVariants` is removed + - `$Deserializer` class is removed + - `Selector` is now a record, taking in a `BlockStateModel$Unbaked` instead of a `MultiVariant` + - `$Deserializer` class is removed +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `renderItem` now takes in a `List` instead of a `BakedModel` + - `renderStatic` no longer takes in a boolean indicating what hand the item was held in +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` now has a public constructor that takes in the list of tint sources, the list of quads, and the `ModelRenderProperties` + - The list of quads and `ModelRenderProperties` replaces the direct `BakedModel`, or now `BlockStateModel` + - `computeExtents` - Extracts the vertices of the baked quads into an array. + - `ItemModel$BakingContext#bake` is removed + - `ItemModelResolver#updateForLiving`, `updateForTopItem` no longer takes in a boolean representing if the item is in the left hand + - `ItemStackReenderState` + - `isGui3d` is removed + - `transform` is removed + - `visitExtents` - Visits all vertices of the model to render and passes them into the provided consumer. + - `$LayerRenderState` + - `NO_EXTENTS_SUPPLIER` - An empty list of vertices. + - `setupBlockModel` has been broken into `prepareQuadList`, `setRenderType`, `setUsesBlockLight`, `setExtents`, `setParticleIcon`, `setTransform` + - `setupSpecialModel` no longer takes in the base `BakedModel` + - `MissingItemModel` now takes in a list of `BakedQuad`s and `ModelRenderProperties` instead of the direct `BakedModel` + - `ModelRenderProperties` - The properties used to render a model, typically retrieved from the `ResolvedModel`. + - `SpecialModelRenderer` now takes in the `ModelRenderProperties` insetad of the base `BakedModel` +- `net.minecraft.client.resources.model` + - `BakedModel` -> `net.minecraft.client.resources.model.QuadCollection`, not one-to-one + - `BlockModelRotation` + - `by` now takes in `Quadrant`s instead of integers + - `withUvLock` - Returns the model state with the rotation and a mention that it locks the UV for the rotation. + - `BlockStateDefinitions` - A manager for creating the mapper of block names to their state defintions. + - `BlockStateModelLoader` + - `ModelResourceLocation` fields are removed + - `loadBlockState` no longer takes in the missing model + - `$LoadedModel` class is removed + - `$LoadedModels` now takes in a `BlockStateModel$UnbakedRoot` instead of an `$Unbaked` + - `forResolving`, `plainModels` is removed + - `DelegateBakedModel` -> `net.minecraft.client.renderer.block.model.SimpleModelWrapper`, not one-to-one + - `MissingBlockModel#VARIANT` is removed + - `ModelBaker` + - `bake` -> `getModel`, not one-to-one + - The baker is simply retrieving the `ResolvedModel` + - `rootName` is removed + - `compute` - Computes the provided key that contains the `ModelBaker`. Typically used for baking `BlockStateModel`s + - `$SharedOperationKey` - An interface which typically computes some baking process for an unbaked model. + - `ModelBakery` now takes in a `Map` for the unbaked block state models, a `Map` for the loaded models, and a `ResolvedModel` for the missing model + - `bakeModels` now takes in a `SpriteGetter` and an `Executor` while returning a `CompletableFuture` for parallel loading and baking + - `$BakingResult` now takes in a `$MissingModels` for the missing block state and item model and a `Map` for the baked block state models; the missing item model is stored within `$MissingModels` + - `$MissingModels` - Holds the missing models for a block state and item. + - `$TextureGetter` interface is removed + - `ModelDebugName` no longer extends `Supplier`, instead using `debugName` + - `ModelDiscovery` + - `registerSpecialModels` is removed + - `discoverDependencies` is now private + - `getReferencedModels`, `getUnreferencedModels` is removed + - `addSpecialModel` - Adds a root model to the list of arbitrarily loaded models. + - `missingModel` - Returns the missing model + - `resolve` - Resolves all model dependencies, returning a map of model names to their models. + - `ModelGroupCollector$GroupKey#create` now takes in a `BlockStateModel$UnbakedRoot` instead of an `$Unbaked` + - `ModelManager` + - `getModel` is removed + - `getMissingModel` -> `getMissingBlockStateModel` + - `$ResolvedModels` - A map of models with their dependencies resolved. + - `ModelResourceLocation` record is removed + - `ModelState` + - `getRotation` -> `transformation` + - `isUvLocked` is removed + - `faceTransfomration`, `inverseFaceTransformation` - Handles returning the transformed `Matrix4fc` for baking the face vertices. + - `MultiPartBakedModel` -> `net.minecraft.client.renderer.block.model.multipart.MultiPartModel` + - Now implements `BlockStateModel` instead of extending `DelegateBakedModel` + - `$SharedBlockState` - A holder that contains the `BlockStateModel`s mapped to their `$Selector`s. + - `QuadCollection` - A data object containing the list of quads to render based on the associated direction and culling. + - `ResolvableModel$Resolver#resolve` -> `markDependency`, not one-to-one + - Instead of directly resolving, the dependency is marked for a later post processing step + - `ResolvedModel` - An `UnbakedModel` whose model and texture dependencies have been completely resolved. + - `SimpleBakedModel` -> `net.minecraft.client.renderer.block.model.SimpleModelWrapper` or `net.minecraft.client.renderer.block.model.SimpleUnbakedGeometry`, not one-to-one + - `SpriteGetter` + - `get`, `reportMissingReference` now take in the `ModelDebugName` + - `resolveSlot` - Resolves the key from the `TextureSlot`s into its `TextureAtlasSprite`. + - `UnbakedGeometry` - An interface that constructs a collection of quads the render when baked. + - `UnbakedModel` no longer implements `ResolvableModel` + - `DEFAULT_AMBIENT_OCCLUSION`, `DEFAULT_GUI_LIGHT` is removed + - `PARTICLE_TEXTURE_REFERENCE` - Holds the key representing the particle texture. + - `bake` is removed + - `getAmbientOcclusion` -> `ambientOcclusion` + - `getGuiLight` -> `guiLight` + - `getTransforms` - `transforms` + - `getTextureSlots` - `textureSlots` + - `geometry` - Holds the unbaked geometry representing the model elements. + - `getParent` -> `parent`, not one-to-one + - `bakeWithTopModelValues` is removed + - `getTopTextureSlots`, `getTopAmbientOcclusion`, `getTopGuiLight`, `getTopTransform`, `getTopTransforms` is removed + - `WeightedBakedModel` -> `WeightedVariants` + - Now implements `BlockStateModel` instead of extending `DelegateBakedModel` +- `net.minecraft.world.item.ItemDisplayContext#leftHand` - Returns whether the display context is rendering with the entity's left hand. + +### 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. + +#### Entity References + +Generally, the point of storing the UUID of another entity was to later grab that entity to perform some logic. However, storing the raw entity could lead to issues if the entity was removed at some point in time. As such, the `EntityReference` was added to handle resolving the entity from its UUID while also making sure it still existed at the time of query. + +An `EntityReference` is simply a wrapped `Either` which either holds the entity instance or the UUID. When resolving via `getEntity`, it will attempt to verify that the stored entity, when present, isn't removed. If it is, it grabs the UUID to perform another lookup for the entity itself. If that entity does exist, it will be return, or otherwise null. + +Most references to a UUID within an entity have been replaced with an `EntityReference` to facilitate this change. + +- `net.minecraft.network.syncher.EntityDataSerializers#OPTIONAL_UUID` -> `OPTIONAL_LIVING_ENTITY_REFERENCE`, not one to one as it can hold the entity reference +- `net.minecraft.server.level.ServerLevel#getEntity(UUID)` -> `Level#getEntity(UUID)` +- `net.minecraft.world.entity` + - `EntityReference` - A reference to an entity either by its entity instance when present in the world, or a UUID. + - `LivingEntity#lastHurtByPlayer`, `lastHurtByMob` are now `EntityReference`s + - `OwnableEntity` + - `getOwnerUUID` -> `getOwnerReference`, not one-to-one + - `level` now returns a `Level` instead of an `EntityGetter` + - `TamableAnimal#setOwnerUUID` -> `setOwner`, or `setOwnerReference`; not one-to-one +- `net.minecraft.world.entity.animal.horse.AbstractHorse#setOwnerUUID` -> `setOwner`, not one-to-one +- `net.minecraft.world.level.Level` now implements `UUIDLookup` +- `net.minecraft.world.level.entity` + - `EntityAccess` now implements `UniquelyIdentifyable` + - `UniquelyIdentifyable` - An interface that claims the object as a UUID and keeps tracks of whether the object is removed or not. + - `UUIDLookup` - An interface that looks up a type by its UUID. + +#### Descoping Player Arguments + +Many methods that take in the `Player` has been descoped to take in a `LivingEntity` or `Entity` depending on the usecase. The following methods below are a non-exhaustive list of this. + +- `net.minecraft.world.entity.EntityType` + - `spawn` + - `createDefaultStackConfig`, `appendDefaultStackConfig` + - `appendCustomEntityStackConfig`, `updateCustomEntityTag` +- `net.minecraft.world.item` + - `BucketItem#playEmptySound` + - `DispensibleContainerItem#checkExtraContent`, `emptyContents` +- `net.minecraft.world.level` + - `Level` + - `playSeededSound` + - `mayInteract` + - `LevelAccessor` + - `playSound` + - `levelEvent` +- `net.minecraft.world.level.block` + - `BucketPickup#pickupBlock` + - `LiquidBlockContainer#canPlaceLiquid` +- `net.minecraft.world.level.block.entity.BrushableBlockEntity#brush` + +#### Component Interaction Events + +Click and hover events on a `MutableComponent` have been reworked into `MapCodec` registry-like system. They are both now interfaces that register their codecs to an `$Action` enum. The implementation then creates a codec that references the `$Action` type and stores any necessary information that is needed for the logic to apply. However, there is no direct 'action' logic associated with the component interactions. Instead, they are hardcoded into their use locations. For click events, this is within `Screen#handleComponentClicked`. For hover events, this is in `GuiGraphics#renderComponentHoverEffect`. As such, any additional events added will need to inject into both the enum and one or both of these locations. + +- `net.minecraft.network.chat` + - `ClickEvent` is now an interface + - `getAction` -> `action` + - `getValue` is now on the subclasses as necessary for their individual types + - `HoverEvent` is now an interface + - `getAction` -> `action` + - `$EntityTooltipInfo` + - `CODEC` is now a `MapCodec` + - `legacyCreate` is removed + - `$ItemStackInfo` is removed, replaced by `$ShowItem` + - `$LegacyConverter` interface is removed + +#### Texture Atlas Reworks + +The texture atlas logic has been finalized into a registry codec system; however, the querying of the atlas data has changed. First, all atlas identifiers are stored within `AtlasIds` while the corresponding texture location is stored within `Sheets`. To get a material from an atlas, a `MaterialMapper` is used as a wrapper around the texture location and the associated prefix to append to the material. The `Material` can then be obtained using `apply` by passing in the id of the material you would like to use. + +For example: + +```java +// Found in sheets +public static final MaterialMapper ITEMS_MAPPER = new MaterialMapper(TextureAtlas.LOCATION_BLOCKS, "item"); +public static final MaterialMapper BLOCKS_MAPPER = new MaterialMapper(TextureAtlas.LOCATION_BLOCKS, "block"); + +// Finds the texture for the material at `assets/examplemod/textures/item/example_item.png` +public static final Material EXAMPLE_ITEM = ITEMS_MAPPER.apply(ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")); + +// Finds the texture for the material at `assets/examplemod/textures/block/example/block.png` +public static final Material EXAMPLE_BLOCK = ITEMS_MAPPER.apply(ResourceLocation.fromNamespaceAndPath("examplemod", "example/block")); +``` + +- `net.minecraft.client.data.AtlasProvider` - A data provider for generating the providers of a texture atlas. +- `net.minecraft.client.data.models.ItemModelGenerators` + - `SLOT_*` -> `TRIM_PREFIX_*`, now public and `ResourceLocation`s + - `TRIM_MATERIAL_MODELS` is now public + - `generateTrimmableItem` now takes in a `ResourceLocation` instead of a `String` + - `$TrimMaterialData` is now public, taking in a `MaterialAssetGroup` instead of the name and override materials +- `net.minecraft.client.renderer` + - `MaterialMapper` - An object that stores the location of the atlas texture and the prefix applied to the ids within the texture. + - `Sheets` + - `*_MAPPER` - `MaterialMapper`s for each texture atlas texture. + - `createBedMaterial(ResourceLocation)` is removed + - `createShulkerMaterial(ResourceLocation)` is removed + - `createSignMaterial(ResourceLocation)` is removed + - `chestMaterial(String)`, `chestMaterial(ResourceLocation)` are removed + - `createDecoratedPotMaterial(ResourceLocation)` is removed +- `net.minecraft.client.renderer.blockentity.ConduitRenderer#MAPPER` - A mapper to get the conduit textures from the block atlas. +- `net.minecraft.client.renderer.texture.atlas` + - `SpriteSource#type` -> `codec`, not one-to-one + - `SpriteSources` now contains logic similar to client registries via their id mapper + - `SpriteSourceType` record is removed +- `net.minecraft.client.renderer.texture.atlas.sources` + - `DirectoryLister` is now a record + - `PalettedPermutations` is now a record + - `SingleFile` is now a record + - `SourceFilter` is now a record + - `Unstitcher` is now a record + - `$Region` is now public +- `net.minecraft.client.resources.model.AtlasIds` - A class which holds the `ResourceLocation`s of all vanilla texture atlases. + +#### Registry Context Swapper + +Client items now store a `RegistryContextSwapper`, which is used to properly check client item information that accesses registry objects. Before level load, this is provided a placeholder to avoid crashing and populated with the correct value during rendering. + +- `net.minecraft.client.multiplayer` + - `CacheSlot` - An object that contains a value computed from some context. When updated, the previous value is overwritten and the context registers the slot to be cleaned. + - `ClientLevel` now implements `CacheSlot$Cleaner` +- `net.minecraft.client.renderer.item` + - `ClientItem` can now take in a nullable `RegistryContextSwapper` + - `withRegistrySwapper` - Sets the `RegistryContextSwapper` within a `ClientItem` + - `ItemModel$BakingContext` now takes in a `RegistryContextSwapper` +- `net.minecraft.util` + - `PlaceholderLookupProvider` - A provider that contains placeholders for referenced objects. Used within client items as they will be loaded before the `RegistyAccess` is populated. + - `RegistryContextSwapper` - An interface used to swap out some object for a different one. Used by client items to swap the placeholders for the loaded `RegistryAccess`. + +#### Reload Instance Creation + +Reload instances have been slightly rearranged. The `SimpleReloadInstance` base now only takes in the `List`, where the other fields are passed into the `of` function such that `#startTasks` can be called immediately. + +- `net.minecraft.server.packs.resources` + - `ProfiledReloadInstance` construct is now private, accessed through `of` + - `SimpleReloadInstance` only takes in the `List` + - `of` now returns a `ReloadInstance`, not one-to-one + - `allPreparations` is now package private + - `allDone` is now private + - `startTasks` - Begins the reload of the listener. + - `prepareTasks` - Runs the executor and sets up the futures needed to read and load all desired data. + - `StateFactory$SIMPLE` - A factory that calls `PreparableReloadListener#reload` + +#### Block Effect Appliers + +Effects that are applied to entities when inside a block are now handled through the `InsideBlockEffectApplier` and `InsideBlockEffectType`. The `InsideBlockEffectType` is an enum that contains a consumer on what to apply to an entity when called. `InsideBlockEffectApplier`, on the other hand, is stored on the entity has a way to apply an effect in a ordered manner based on the enum ordinals. + +To call one of the effect types, you must override `BlockBehaviour#entityInside` or `Fluid#entityInside` and call `InsideBlockEffectApplier#apply`. If something should apply before the effect type, like entinguishing fire before freezing in powder snow, then `InsideBlockEffectApplier#runBefore` should be called before `apply`. Similarly, if something should run afterward, like hurting an enemy after being placed in lava, then `runAfter` should be called. + +```java +// In some block or fluid subclass +@Override +protected void entityInside(Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier applier) { + applier.runBefore(InsideBlockEffectType.EXTINGUISH, entity -> { + // Modify entity here. + }); + + // Do the base application logic stored on the type + applier.apply(InsideBlockEffectType.FIRE_IGNITE); + + applier.runAfter(InsideBlockEffectType.FIRE_IGNITE, entity -> { + // Perform any final checks that are as a result of the effect being applied + entity.hurt(...); + }); +} +``` + +- `net.minecraft.world.entity` + - `InsideBlockEffectApplier` - An interface that defines how an entity should interact when within a given block. + - `InsideBlockEffectType` - An enum that defines what behavior to perform when side the specific block that references the type. +- `net.minecraft.world.level.block.state.BlockBehaviour#entityInside`, `$BlockStateBase#entityInside` now takes in an `InsideBlockEffectApplier` +- `net.minecraft.world.level.material.Fluid#entityInside`, `FluidState#entityInside` - A method called whenever the entity is considered inside the bounding box of the fluid. + +#### Timer Callbacks, joining the codec club! + +`TimerCallback`s, used in the server schedule for executing events, typically mcfunctions in datapacks, have now been reworked into a codec form. This means that a callback can be registered to the list of available callbacks by passing in the `MapCodec` to `TimerCallbacks#register` (via `TimerCallbacks#SERVER_CALLBACKS`) instead of the serializer. + +- `net.minecraft.world.level.timers` + - `FunctionCallback` is now a record + - `FunctionTagCallback` is now a record + - `TimerCallback` + - `codec` - Returns the codec used for serialization. + - `$Serializer` class is removed + - `TimerCallbacks` + - `serialize`, `deserialize` -> `codec`, not one-to-one + +#### The JOML Backing Interfaces + +Mojang has opted to lessen the restriction on JOML objects by passing around the implementing interface of their logic objects (usually implemented with a tacked on `c`). For example, `Vector3f` becomes `Vector3fc` or `Matrix4f` becomes `Matrix4fc`. This does not change any logic itself as the `c` interfaces are implemented by the class components. + +#### Tag Changes + +- `minecraft:worldgen/biome` + - `spawns_cold_variant_farm_animals` + - `spawns_warm_variant_farm_animals` +- `minecraft:block` + - `sword_instantly_mines` + - `replaceable_by_mushrooms` + - `plays_ambient_desert_block_sounds` + - `edible_for_sheep` + - `dead_bush_may_place_on` -> `dry_vegetation_may_place_on` + - `camels_spawnable_on` +- `minecraft:cat_variant` are removed +- `minecraft:entity_type` + - `can_equip_saddle` + - `can_wear_horse_armor` +- `minecraft:item` + - `book_cloning_target` + - `eggs` + - `flowers` + +#### Mob Effects Field Renames + +Some mob effects have been renamed to their in-game name, rather than some internal descriptor. + +- `MOVEMENT_SPEED` -> `SPEED` +- `MOVEMENT_SLOWDOWN` -> `SLOWNESS` +- `DIG_SPEED` -> `HASTE` +- `DIG_SLOWDOWN` -> `MINING_FATIGUE` +- `DAMAGE_BOOST` -> `STRENGTH` +- `HEAL` -> `INSTANT_HEALTH` +- `HARM` -> `INSTANT_DAMAGE` +- `JUMP` -> `JUMP_BOOST` +- `CONFUSION` -> `NAUSEA` +- `DAMAGE_RESISTANCE` -> `RESISTANCE` + +#### Very Technical Changes + +This is a list of technical changes that could cause highly specific errors depending on your specific setup. + +- The order of the `minecraft:patch_sugar_cane` feature and `minecraft:patch_pumpkin` feature have swapped orders (first pumpkin, then sugar cane), meaning modded biomes that generate both of these features will need to update their JSONs to the new ordering. + +- Serveral vanilla oak tree and tree selector features now have `_leaf_litter` appended at the end. + - For example: `trees_birch_and_oak` -> `trees_birch_and_oak_leaf_litter` + +#### List of Additions + +- `net.minecraft` + - `ChatFormatting#COLOR_CODEC` + - `CrashReportCategory#populateBlockLocationDetails` - Adds the block location details to a crash report. +- `net.minecraft.advancements.critereon.MinMaxBounds#createStreamCodec` - Constructs a stream codec for a `MinMaxBounds` implementation. +- `net.minecraft.client.Options#startedCleanly` - Sets whether the game started cleanly on last startup. +- `net.minecraft.client.data.models` + - `BlockModelGenerators#createSegmentedBlock` - Generates a multipart blockstate definition with horizontal rotation that displays up to four models based on some integer property. + - `ItemModelGenerators#prefixForSlotTrim` - Generates a vanilla `ResourceLocation` for a trim in some slot. +- `net.minecraft.client.MouseHandler` + - `fillMousePositionDetails` - Adds details about the current mouse location and screen size to a crash report. + - `getScaledXPos` - Gets the current x position scaled by the gui scaling option. + - `getScaledYPos` - Gets the current y position scaled by the gui scaling option. + - `drawDebugMouseInfo` - Draws information about the scaled position of the mouse to the screen. +- `net.minecraft.client.gui.components.toasts.Toast#getSoundEvent` - Returns the sound to play when the toast is displayed. +- `net.minecraft.client.gui.screens.options.VideoSettingsScreen#updateFullscreenButton` - Sets the fullscreen option to the specified boolean. +- `net.minecraft.client.model.geom.builders` + - `MeshDefinition#apply` - Applies the given transformer to the mesh before returning a new instance. + - `MeshTransformer#IDENTITY`- Performs the identity transformation. +- `net.minecraft.client.multiplayer.ClientPacketListener#decoratedHashOpsGenenerator` - Returns the generator used to create a hash of a data component and its value. +- `net.minecraft.client.particle` + - `FallingLeavesParticle$TintedLeavesProvider` - A provider for a `FallingLeavesParticle` that uses the color specified by the block above the particle the spawn location. + - `FireflyParticle` - A particle that spawns fireflies around a given non-air block position. +- `net.minecraft.client.renderer` + - `BiomeColors#getAverageDryFoliageColor` - Returns the average foliage color for dry biomes. + - `LevelRenderer$BrightnessGetter` - An interfaces which obtains the packed brightness at a given block position. + - `WorldBorderRenderer#invalidate` - Invalidates the current render of the world border to be rerendered. +- `net.minecraft.client.renderer.entity` + - `EntityRenderDispatcher#getRenderer` - Gets the renderer to use from the data stored on the render state. + - `EntityRenderer#extractAdditionalHitboxes` - Gets any additional hitboxes to render when the 'show hitboxes' debug state is enabled. +- `net.minecraft.client.renderer.entity.state` + - `EntityRenderState` + - `entityType` - The type of the entity. + - `hitboxesRenderState` - The hitbox information of the entity relative to the entity's position. + - `serverHitboxesRenderState` - The hitbox information of the entity synced from the server. + - `fillCrashReportCategory` - Sets the details for any crashes related to the render state. + - `HitboxesRenderState` - The render state of the hitboxes for the entity relative to the entity's position. + - `HitboxRenderState` - The render state of a single hitbox to render along with its color, such as the eye height of an entity. + - `ServerHitboxesRenderState` - The render state containing the last synced information from the related server entity. + - `PigRenderState#variant` - The variant of the pig. +- `net.minecraft.client.renderer.item.SelectItemModel$ModelSelector` - A functional interface that selects the item model based on the switch case and level. +- `net.minecraft.client.renderer.item.properties.conditional.ComponentMatches` - A conditional property that checks whether the given predicate matches the component data. +- `net.minecraft.client.renderer.item.properties.select` + - `ComponentContents` - A switch case property that operates on the contents within a data component. + - `SelectItemModelProperty#valueCodec` - Returns the `Codec` for the property type. +- `net.minecraft.client.resources.DryFoliageColorReloadListener` - A reload listener that loads the colormap for dry foliage. +- `net.minecraft.commands.arguments.ComponentArgument#getResolvedComponent` - Constructs a component with the resolved information of its contents. +- `net.minecraft.core` + - `Direction#getUnitVec3f` - Returns the float unit vector of the direction. + - `HolderGetter$Provider#getOrThrow` - Gets a holder reference from a resource key. + - `SectionPos#sectionToChunk` - Converts a compressed section position to a compressed chunk position. + - `Vec3i#STREAM_CODEC` +- `net.minecraft.network` + - `HashedPatchMap` - A record containing a map of components to their hashed type/value along with a set of removed components. + - `HashedStack` - An `ItemStack` representation that hashes the stored components. + - `ProtocolInfo$DetailsProvider` - Provides the details for a given protocol. + - `SkipPacketDecoderException` - An exception thrown when an error occurs during decoding before having its data ignored. + - `SkipPacketEncoderException` - An exception thrown when an error occurs during encoding before having its data ignored. +- `net.minecraft.network.chat` + - `LastSeenMessages` + - `computeChecksum` - Computes a byte representing the merged checksums of all message signatures. + - `$Update#verifyChecksum` - Verifies that the update checksum matches those within the last seen messages. + - `LastSeenMessagesValidator$ValidationException` - An exception thrown if the messages can not be validated. + - `MessageSignature` + - `describe` - Returns a stringified version of the message signature. + - `checksum` - Hashes the bytes within the signature into a single integer. + - `PlayerChatMessage#describeSigned` - Returns a stringified version of the chat message. +- `net.minecraft.network.codec` + - `ByteBufCodecs` + - `LONG_ARRAY` + - `lengthPrefixed` - Returns an operation that limits the size of the buffer to the given size. + - `IdDispatchCodec$DontDecorateException` - An interface that tells the exception handler to rethrow the raw exception rather than wrap it within an `EncoderException`. +- `net.minecraft.network.protocol` + - `CodecModifier` - A function that modifies some codec using a given object. + - `ProtocolInfoBuilder#context*Protocol` - Builds an `UnboundProtocol` with the given context used to modify the codecs to send. +- `net.minecraft.network.protocol.game.GameProtocols` + - `HAS_INFINITE_MATERIALS` - A modifier that checks the `ServerboundSetCreativeModeSlotPacket` for if the player has the necessary settings. If not, the packet is discarded. + - `$Context` - Returns the context used by the packet to modify the incoming codec. +- `net.minecraft.resources.DelegatingOps` + - `$DelegateListBuilder` - A list builder that can be subclassed if needed. + - `$DelegateRecordBuilder` - A record builder that can be subclassed if needed. +- `net.minecraft.server.bossevents.CustomBossEvent$Packed` - A record that backs the event information for serialization. +- `net.minecraft.server.commands.InCommandFunction` - A command function that takes in some input and returns a result. +- `net.minecraft.server.level` + - `DistanceManager#forEachBlockTickingChucnks` - Applies the provided consumer for each chunk with block ticking enabled. + - `ServerLevel` + - `areEntitiesActuallyLoadedAndTicking` - Returns whether the entity manager is actually ticking and loading entities in the given chunk. + - `tickThunder` - Ticks the thunger logic within a given level. + - `anyPlayerCloseEnoughForSpawning` - Returns if a player is close enough to spawn the entity at the given location. + - `ServerPlayer$RespawnConfig` - A record containing the respawn information for the player. +- `net.minecraft.util` + - `AbstractListBuilder` - A ops list builder which boils the implementation down to three methods which initializes, appends, and builds the final list. + - `Brightness` + - `block` - Returns the block light from a packed value. + - `sky` - Returns the sky light from a packed value. + - `HashOps` - A dynamic ops that generates a hashcode for the data. + - `ExtraCodecs` + - `UNTRUSTED_URI` - A codec for a URI that is not trusted by the game. + - `CHAT_STRING` - A codec for a string in a chat message. + - `legacyEnum` - A codec that maps an enum to its output in `Enum#toString`. + - `FileSystemUtil` - A utility for interacting with the file system. + - `GsonHelper#encodesLongerThan` - Returns whether the provided element can be written in the specified number of characters. + - `Unit#STREAM_CODEC` - A stream codec for a unit instance. + - `Util` + - `mapValues` - Updates the values of a map with the given function. + - `mapValuesLazy` - Updates the values of a map with the given function, but each value is resolved when first accessed. + - `growByHalf` - Returns an integer multiplied by 1.5, rounding down, clamping the value to some minimum and the max integer size. +- `net.minecraft.util.random.Weighted#map`, `WeightedList#map` - Transforms the stored object(s) to a new type. +- `net.minecraft.util.thread.ParallelMapTransform` - A helper that handles scheduling and batching tasks in parallel. +- `net.minecraft.world.effect.MobEffectInstance#withScaledDuration` - Constructs a new instance with the duration scaled by some float value. +- `net.minecraft.world.entity` + - `AreaEffectCloud#setPotionDurationScale` - Sets the scale of how long the potion should apply for. + - `DropChances` - A map of slots to probabilities indicating how likely it is for an entity to drop that piece of equipment. + - `Entity` + - `isInterpolating` - Returns whether the entity is interpolating between two steps. + - `sendBubbleColumnParticles` - Spawns bubble column particles from the server. + - `canSimulateMovement` - Whether the entity's movement can be simulated, usually from being the player. + - `propagateFallToPassengers` - Propogates the fall damage of a vehicle to its passengers. + - `lavaIgnite` - Ignites the entity for 15 seconds if not immune. + - `clearFreeze` - Sets the number of ticks the entity is frozen for to 0. + - `removeLatestMovementRecordingBatch` - Removes the last element from all movements performed this tick. + - `InterpolationHandler` - A class meant to easily handle the interpolation of the position and rotation of the given entity as necessary. + - `LivingEntity` + - `getLuck` - Returns the luck of the entity for random events. + - `getLastHurtByPlayer`, `setLastHurtByPlayer` - Handles the last player to hurt this entity. + - `getEffectBlendFactor` - Gets the blend factor of an applied mob effect. + - `applyInput` - Applies the entity's input as its AI, typically for local players. + - `INPUT_FRICTION` - The scalar to apply to the movements of the entity. +- `net.minecraft.world.entity.animal.camel.Camel#checkCamelSpawnRules` - Checks if a camel can spawn at a particular position. +- `net.minecraft.world.entity.animal.sheep.SheepColorSpawnRules` - A class that contains the color spawn configurations for a sheep's wool when spawning within a given climate. +- `net.minecraft.world.entity.npc.Villager#createDefaultVillagerData` - Returns the default type and profession of the villager to use when no data is set. +- `net.minecraft.world.entity.player.Player` + - `preventsBlockDrops` - Whether the player cannot drop any blocks on destruction. + - `gameMode` - Returns the current game mode of the player. + - `debugInfo` - Returns the common information about the player as a single string. +- `net.minecraft.world.inventory` + - `ContainerSynchronizer#createSlot` - Creates a `RemoteSlot` that represents a slot on the opposite side. + - `RemoteSlot` - A slot that represents the data on the opposing side, syncing when the data is not consistent. +- `net.minecraft.world.item` + - `EitherHolder#key` - Returns the resource key of the held registry object. + - `Item#STREAM_CODEC` + - `ItemStack` + - `OPTIONAL_UNTRUSTED_STREAM_CODEC` + - `MAP_CODEC` + - `canDestroyBlock` - Returns whether this item can destroy the provided block state. +- `net.minecraft.world.item.alchemy.PotionContents#getPotionDescription` - Returns the description of the mob effect with some amplifier. +- `net.minecraft.world.item.crafting` + - `Recipe#KEY_CODEC` + - `TransmuteResult` - A recipe result object that represents an item, count, and the applied components. +- `net.minecraft.world.item.equipment.trim.ArmorTrim#layerAssetId` - Returns the location of the the trim asset. +- `net.minecraft.world.level` + - `BlockGetter$BlockStepVisitor` - A consumer that takes in the current position and how many collisions within the desired path of travel. + - `ColorMapColorUtil` - A helper for getting the color from a map given the biome's temperature, downfall, colormap, and default color. + - `DryFoliageColor` - A color resolver for biomes with dry foliage. + - `GameRules` + - `getType` - Gets the game rule type from its key. + - `keyCodec` - Creates the codec for the key of a game rule type. + - `Level` + - `isMoonVisible` - Returns wehther the moon is currently visible in the sky. + - `getPushableEntities` - Gets all entities except the specified target within the provided bounding box. + - `getClientLeafTintColor` - Returns the color of the leaf tint at the specified location. + - `playPlayerSound` - Plays a sound to the current player on the client. + - `LevelReader#getHeight` - Returns the height of the map at the given position. + - `NaturalSpawner#INSCRIBED_SQUARE_SPAWN_DISTANCE_CHUNK` - Provides the minimum distance that the player is close enough for spawning to occur. +- `net.minecraft.world.level.biome` + - `Biome` + - `getDryFoliageColor`, `getDryFoliageColorFromTexture` - Gets the dry foliage color of the biome, either from the effects or from the climate settings. + - `BiomeSpecialEffects#getDryFoliageColorOverride`, `$Builder#dryFoliageColorOverride` - Returns the default dry foliage color when not pulling from a colormap texture. +- `net.minecraft.world.level.block` + - `BaseFireBlock#fireIgnite` - Lights an entity on fire. + - `Block` + - `UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS` - A flag that skips all potential sideeffects when updating a block entity. + - `UPDATE_SKIP_ALL_SIDEEFFECTS` - A flag that skips all sideeffects by skipping certain block entity logic, supressing drops, and updating the known shape. + - `UPDATE_SKIP_ON_PLACE` - A flag that skips calling `BlockState#onPlace` when set. + - `BonemealableBlock#hasSpreadableNeighbourPos`, `findSpreadableNeighbourPos` - Handles finding other positions that the vegetation can spread to on bonemeal. + - `CactusFlowerBlock` - A flower that grows on a cactus. + - `FireflyBushBlock` - A bush that spawns firefly particles around it. + - `SandBlock` - A colored sand block that can play ambient sounds. + - `SegmentableBlock` - A block that can typically be broken up into segments with unique sizes and placements. + - `ShortDryGrassBlock` - A single grass block that has been dried out. + - `TallDryGrassBlock` - A double grass block that has been dried out. + - `TerracottaBlock` - A terracotta block that can play ambient sounds. + - `TintParticleLeavesBlock` - A leaves block whose particles are tinted. + - `UntintedParticleLeavesBlock` - A leaves block whose particles are not tinted. + - `VegetationBlock` - A block that represents some sort of vegetation that can propogate light and need some sort of farmland or dirt to survive. +- `net.minecraft.world.level.block.entity.StructureBlockEntity#isStrict`, `setStrict` - Sets strict mode when generating structures. +- `net.minecraft.world.level.block.sounds.AmbientDesertBlockSoundsPlayer` - A helper to play sounds for a given block, typically during `animateTick`. +- `net.minecraft.world.level.block.state.BlockBehaviour#getEntityInsideCollisionShape` - Gets the collision shape of the block when the entity is within it. +- `net.minecraft.world.level.border.WorldBorder` + - `closestBorder` - Returns a list of the closest borders to the player based on their horizontal direction. + - `$DistancePerDirection` - A record containing the distance from the entity of the world border in a given direction. +- `net.minecraft.world.level.chunk.status.ChunkStatus#CODEC` +- `net.minecraft.world.level.entity.PersistentEntitySectionManager#isTicking` - Returns whether the specified chunk is currently ticking. +- `net.minecraft.world.level.levelgen.Heightmap$Types#STREAM_CODEC` +- `net.minecraft.world.level.levelgen.feature` + - `AbstractHugeMushroomFeature#placeMushroomBlock` - Places a mushroom block that specified location, replacing a block if it can. + - `FallenTreeFeature` - A feature that generates flane trees with a stump of given lengths. + - `TreeFeature#getLowestTrunkOrRootOfTree` - Retruns the lowest block positions of the tree decorator. +- `net.minecraft.world.level.levelgen.feature.configurations.FallenTreeConfiguration` - A configuration for fallen trees with stumps. +- `net.minecraft.world.level.levelgen.feature.treedecorators` + - `AttachedToLogsDecorator` - A decorator that attaches a random block to a given direction on a log with a set probability. + - `PlaceOnGroundDecorator` - A decorator that places the tree on a valid block position. +- `net.minecraft.world.level.levelgen.structure.pools` + - `ListPoolElement#getElements` - Returns the elements of the structure pool. + - `SinglePoolElement#getTemplateLocation` - Returns the location of the template used by the element. + - `StructureTemplatePool#getTemplates` - Returns a list of elements with their weights. +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure` + - `getStartPool` - Returns the starting pool of the jigsaw to generate. + - `getPoolAliases` - Returns all pools used by the jigsaw. +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate#getDefaultJointType` - Returns the default join type between two jigsaw pieces if none is specified or an error occurs during loading. +- `net.minecraft.world.level.material.Fluid#getAABB`, `FluidState#getAABB` - Returns the bounding box of the fluid. +- `net.minecraft.world.scores` + - `Objective#pack`, `$Packed` - Handles the serializable form of the objective data. + - `PlayerTeam#pack`, `$Packed` - Handles the serializable form of the player team data. + - `Scoreboard` + - `loadPlayerTeam`, `loadObjective` - Loads the data from the packed object. + - `$PackedScore` - Handles the serializable form of the scoreboard data. +- `net.minecraft.world.level.storage.loot.LootTable#KEY_CODEC` +- `net.minecraft.world.phys` + - `AABB$Builder` - A builder for constructing a bounding box by providing the vectors within. + - `Vec2#CODEC` +- `net.minecraft.world.phys.shapes.CollisionContext` + - `placementContext` - Constructs the context when placing a block from its item. + - `isPlacement` - Returns whether the context is being used for placing a block. +- `net.minecraft.world.ticks.TickPriority#CODEC` + +#### List of Changes + +- `net.minecraft.client.Screenshot` is now a utility instead of an instance class, meaning all instance methods are removed + - `takeScreenshot(RenderTarget)` -> `takeScreenshot(RenderTarget, Consumer)`, not returning anything +- `net.minecraft.client.multiplayer` + - `ClientChunkCache#replaceWithPacketData` now takes in a `Map` instead of a `CompoundTag` + - `MultiPlayerGameMode#hasInfiniteItems` -> `net.minecraft.world.entity.LivingEntity#hasInfiniteMaterials` + - `ClientPacketListener#markMessageAsProcessed` now takes in a `MessageSignature` instead of a `PlayerChatMessage` +- `net.minecraft.client.multiplayer.chat.ChatListener#handleChatMessageError` now takes in a nullable `MessageSignature` +- `net.minecraft.client.player` + - `ClientInput#leftImpulse`, `forwardImpulse` -> `moveVector`, now protected + - `LocalPlayer#spinningEffectIntensity`, `oSpinningEffectIntensity` -> `portalEffectIntensity`, `oPortalEffectIntensity` +- `net.minecraft.client.renderer.LevelRenderer#getLightColor(BlockAndTintGetter, BlockState, BlockPos)` -> `getLightColor(LevelRenderer$BrightnessGetter, BlockAndTintGetter, BlockState, BlockPos)` +- `net.minecraft.client.renderer.blockentity.BlockEntityRenderer#render` now takes in a `Vec3` representing the camera's position +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher` + - `$RenderSection` + - `getOrigin` -> `getRenderOrigin` + - `reset` is now public + - `releaseBuffers` is removed + - `$CompileTask#getOrigin` -> `getRenderOrigin` +- `net.minecraft.client.renderer.entity` + - `DonkeyRenderer` now takes in a `DonekyRenderer$Type` containing the textures, model layers, and equipment information + - `ItemEntityRenderer#renderMultipleFromCount` now has an overload that takes in the model bounding box + - `UndeadHorseRenderer` now takes in a `UndeadHorseRenderer$Type` containing the textures, model layers, and equipment information +- `net.minecraft.client.renderer.entity.layers` + - `EquipmentLayerRenderer$TrimSpriteKey#textureId` -> `spriteId` + - `VillagerProfessionLayer#getHatData` now takes in a map of resource keys to metadata sections and swaps the registry and value for a holder instance +- `net.minecraft.client.renderer.item` + - `ConditionalItemModel` now takes in a `ItemModelPropertyTest` instead of a `ConditionalItemModelProperty` + - `SelectItemModel` now takes in a `$ModelSelector` instead of an object map +- `net.minecraft.client.renderer.item.properties.conditional.ConditionalItemModelProperty` now implements `ItemModelPropertyTest` + - `ItemModelPropertyTest` holds the `get` method previously within `ConditionalItemModelProperty` +- `net.minecraft.commands.arguments` + - `ComponentArgument` + - `ERROR_INVALID_JSON` -> `ERROR_INVALID_COMPONENT` + - `getComponent` -> `getRawComponent` + - `ResourceKeyArgument#getRegistryKey` is now public + - `StyleArgument#ERROR_INVALID_JSON` -> `ERROR_INVALID_STYLE` +- `net.minecraft.commands.arguments.item` + - `ComponentPredicateParser$Context#createComponentTest`, `createPredicateTest` now takes in a `Dynamic` instead of a `Tag` + - `ItemPredicateArgument` + - `$ComponentWrapper#decode` now takes in a `Dynamic` instead of a `RegistryOps`, `Tag` pair + - `$PredicateWrapper#decode` now takes in a `Dynamic` instead of a `RegistryOps`, `Tag` pair +- `net.minecraft.core` + - `BlockMath` + - `VANILLA_UV_TRANSFORM_LOCAL_TO_GLOBAL`, `VANILLA_UV_TRANSFORM_GLOBAL_TO_LOCAL` is now private + - `getUVLockTransform` -> `getFaceTransformation` + - `Direction#rotate` now takes in a `Matrix4fc` instead of a `Matrix4f` + - `Rotations` is now a record +- `net.minecraft.data.loot.BlockLootSubProvider#createPetalDrops` -> `createSegmentedBlockDrops` +- `net.minecraft.network` + - `FriendlyByteBuf` + - `writeLongArray`, `readLongArray` now have static delegates which take in the `ByteBuf` and `*Fixed*` versions for fixed size arrays + - `ProtocolInfo$Unbound` -> `$Details`, `net.minecraft.network.protocol.SimpleUnboundProtocol`, `net.minecraft.network.protocol.UnboundProtocol`; not one-to-one + - `#bind` -> `net.minecraft.network.protocol.SimpleUnboundProtocol#bind`, `UnboundProtocol#bind`; not one-to-one + - `SkipPacketException` is now an interface instead of a subclass of `EncoderException` +- `net.minecraft.network.chat` + - `ComponentSerialization#flatCodec` -> `flatRestrictedCodec` + - `LastSeenMessages$Update` now takes in a byte representing the checksum value + - `LastSeenMessagesValidator` + - `applyOffset` now returns nothing and can throw a `$ValidationException` + - `applyUpdate` now returns the raw messages and can throw a `$ValidationException` +- `net.minecraft.network.codec.StreamCodec#composite` now has an overload for nine parameters +- `net.minecraft.network.protocol.ProtocolInfoBuilder` now takes in a third generic representing how to modify the provided codec. + - `addPacket` now has an overload that takes in a `CodecModifier` + - `build` -> `buildUnbound`, not one-to-one + - `protocol`, `serverboundProtocol`, `clientboundProtocol` now returns a `SimpleUnboundProtocol` +- `net.minecraft.network.protocol.ConfigurationProtocols` now contain `SimpleUnboundProtocol` constants +- `net.minecraft.network.protocol.game` + - `ClientboundContainerSetContentPacket` is now a record + - `ClientboundMoveEntityPacket#getyRot`, `getxRot` -> `getYRot`, `getXRot` + - `ClientboundPlayerChatPacket` now takes in a global index for the chat message + - `ClientboundLevelChunkPacketdata#getHeightmaps` now returns a `Map` + - `ClientboundUpdateAdvancementsPacket` now takes in a boolean representing whether to show the adavncements as a toast + - `GameProtocols` constants are now either `SimpleUnboundProtocol`s or `UnboundProtocol`s + - `ServerboundContainerClickPacket` is now a record + - `ServerboundMovePlayerPacket$Pos`, `$PosRot` now has an overload that takes in a `Vec3` for the position + - `ServerboundSetStructureBlockPacket` now takes in an additional boolean representing whether the structure should be generated in strict mode +- `net.minecraft.network.protocol.handshake.HandshakeProtocols#SERVERBOUND_TEMPLATE` is now a `SimpleUnboundProtocol` +- `net.minecraft.network.protocol.login.LoginProtocols#SERVERBOUND_TEMPLATE` constants are now `SimpleUnboundProtocol`s +- `net.minecraft.network.protocol.status.StatusProtocols#SERVERBOUND_TEMPLATE` constants are now `SimpleUnboundProtocol`s +- `net.minecraft.server.PlayerAdvancements#flushDirty` now takes in a boolean that represents whether the advancements show display as a toast +- `net.minecraft.server.bossevents.CustomBossEvent` + - `save` -> `pack`, not one-to-one + - `load` now takes in the id and the packed variant to unpack +- `net.minecraft.server.level` + - `DistanceManager` + - `hasPlayersNearby` now returns a `TriState` + - `forEachBlockTickingChunks` -> `forEachEntityTickingChunk`, not one-to-one + - `ServerEntity` now takes in a consumer for broadcasting a packet to all players but those in the ignore list + - `ServerLevel` + - `getForcedChunks` -> `getForceLoadedChunks` + - `isPositionTickingWithEntitiesLoaded` is now public + - `isNaturalSpawningAllowed` -> `canSpawnEntitiesInChunk`, `BlockPos` variant is removed + - `ServerPlayer` + - `getRespawnPosition`, `getRespawnAngle`, `getRespawnDimension`, `isRespawnForced` -> `getRespawnConfig`, not one-to-one + - `setRespawnPosition` now takes in a `$RespawnConfig` instead of the individual respawn information + - `loadAndSpawnParentVehicle`, `loadAndSpawnEnderpearls` now takes in a `CompoundTag` without the optional wrapping\ +- `net.minecraft.server.network.ServerGamePacketListenerImpl` now implements `GameProtocols$Context` +- `net.minecraft.sounds.SoundEvents` have the following sounds now `Holder` wrapped: + - `ITEM_BREAK` + - `SHIELD_BLOCK`, `SHIELD_BREAK`, + - `WOLF_ARMOR_BREAK` +- `net.minecraft.util` + - `Brightness` + - `FULL_BRIGHT` is now final + - `pack` now has a static overload that takes in the block and sky light. + - `ExtraCodecs#MATRIX4f` now is a `Codec` + - `Util#makeEnumMap` returns the `Map` superinstance rather than the specific `EnumMap` +- `net.minecraft.util.parsing.packrat.commands.TagParseRule` now takes in a generic for the tag type + - The construct is now public, taking in a `DynamicOps` +- `net.minecraft.util.profiling` + - `ActiveProfiler` now takes in a `BooleanSupplier` instead of a boolean + - `ContinuousProfiler` now takes in a `BooleanSupplier` instead of a boolean +- `net.minecraft.util.worldupdate.WorldUpgrader` now takes in the current `WorldData` +- `net.minecraft.world` + - `BossEvent$BossBarColor`, `$BossBarOverlay` now implements `StringRepresentable` + - `Container` now implements `Iterable` +- `net.minecraft.world.effect` + - `MobEffect` + - `getBlendDurationTicks` -> `getBlendInDurationTicks`, `getBlendOutDurationTicks`, `getBlendOutAdvanceTicks`; not one-to-one + - `setBlendDuration` now has an overload that takes in three integers to set the blend in, blend out, and blend out advance ticks + - `MobEffectInstance#tick` -> `tickServer`, `tickClient`; not one-to-one +- `net.minecraft.world.entity` + - `Entity` + - `cancelLerp` -> `InterpolationHandler#cancel` + - `lerpTo` -> `moveOrInterpolateTo` + - `lerpTargetX`, `lerpTargetY`, `lerpTargetZ`, `lerpTargetXRot`, `lerpTargetYRot` -> `getInterpolation` + - `onAboveBubbleCol` -> `onAboveBubbleColumn` now takes in a `BlockPos` for the bubble column particles spawn location + - Logic delegates to the protected static `handleOnAboveBubbleColumn` + - `isControlledByOrIsLocalPlayer` -> `isLocalInstanceAuthoritative`, now final + - `isControlledByLocalInstance` -> `isLocalClientAuthoritative`, now protected + - `isControlledByClient` -> `isClientAuthoritative` + - `fallDistance`, `causeFallDamage` is now a double + - `absMoveto` -> `absSnapTo` + - `absRotateTo` -> `asbSnapRotationTo` + - `moveTo` -> `snapTo` + - `sendBubbleColumnParticles` is now static, taking in the `Level` + - `onInsideBubbleColumn` logic delegates to the protected static `handleOnInsideBubbleColumn` + - `EntityType` + - `POTION` -> `SPLASH_POTION`, `LINGERING_POTION`, not one-to-one + - `$EntityFactory#create` can now return a null instance + - `ExperienceOrb#value` -> `DATA_VALUE` + - `ItemBasedSteering` no longer takes in the accessor for having a saddle + - `LivingEntity` + - `lastHurtByPlayerTime` -> `lastHurtByPlayerMemoryTime` + - `lerpSteps`, `lerpX`, `lerpY`, `lerpZ`, `lerpYRot`, `lerpXRot` -> `interpolation`, not one-to-one + - `isAffectedByFluids` is now public + - `removeEffectNoUpdate` is now final + - `tickHeadTurn` now returns nothing + - `canDisableShield` -> `canDisableBlocking`, now set via the `WEAPON` data component + - `calculateFallDamage` now takes in a double instead of a float + - `Mob` + - `handDropChances`, `armorDropChances`, `bodyArmorDropChance` -> `dropChances`, not one-to-one + - `getEquipmentDropChance` -> `getDropChances`, not one-to-one +- `net.minecraft.world.entity.ai.Brain#addActivityWithConditions` now has an overload that takes in an integer indiciating the starting priority +- `net.minecraft.world.entity.ai.behavior` + - `LongJumpToRandomPos$PossibleJump` is now a record + - `VillagerGoalPackages#get*Package` now takes in a holder-wrapped profession +- `net.minecraft.world.entity.ai.gossip.GossipContainer#store`, `update` -> `clear`, `putAll`, `copy`; not one-to-one +- `net.minecraft.world.entity.animal` + - `Pig` is now a `VariantHolder` + - `Sheep` -> `.sheep.Sheep` + - `WaterAnimal#handleAirSupply` now takes in a `ServerLevel` +- `net.minecraft.world.entity.animal.axolotl.Axolotl#handleAirSupply` now takes in a `ServerLevel` +- `net.minecraft.world.entity.monster.ZombieVillager#setGossips` now takes in a `GossipContainer` +- `net.minecraft.world.entity.monster.warden.WardenSpawnTracker` now has an overload which sets the initial parameters to zero +- `net.minecraft.world.entity.npc` + - `Villager` now takes in either a key or a holder of the `VillagerType` + - `setGossips` now takes in a `GossipContainer` + - `VillagerData` is now a record + - `set*` -> `with*` + - `VillagerProfession` now takes in a `Component` for the name + - `VillagerTrades` + - `TRADES` now takes in a resource key as the key of the map + - This is similar for all other type specific trades + - `$FailureItemListing` is now private +- `net.minecraft.world.entity.player.Player` + - `stopFallFlying` -> `LivingEntity#stopFallFlying` + - `isSpectator`, `isCreative` no longer abstract in the `Player` class +- `net.minecraft.world.entity.projectile.ThrownPotion` -> `AbstractThrownPotion`, implemented in `ThrownLingeringPotion` and `ThrownSplashPotion` +- `net.minecraft.world.entity.raid.Raid(int, ServerLevel, BlockPos)` -> `Raid(BlockPos, Difficulty)` + - `tick`, `addWaveMob` now takes in the `ServerLevel` +- `net.minecraft.world.entity.vehicle` + - `AbstractMinecart#setDisplayBlockState` -> `setCustomDisplayBlockState` + - `MinecartBehavior` + - `cancelLerp` -> `InterpolationHandler#cancel` + - `lerpTargetX`, `lerpTargetY`, `lerpTargetZ`, `lerpTargetXRot`, `lerpTargetYRot` -> `getInterpolation` + - `MinecartTNT#primeFuse` now takes in the `DamageSource` cause +- `net.minecraft.world.inventory` + - `AbstractContainerMenu` + - `setRemoteSlotNoCopy` -> `setRemoteSlotUnsafe`, not one-to-one + - `setRemoteCarried` now takes in a `HashedStack` + - `ClickType` now takes in an id for its representations + - `ContainerSynchronizer#sendInitialData` now takes in a list of stacks rather than a `NonNullList` +- `net.minecraft.world.item` + - `EitherHolder` now takes in an `Either` instance rather than just an `Optional` holder and `ResourceKey` + - `Item` + - `canAttackBlock` -> `canDestroyBlock` + - `hurtEnemy` no longer returns anything + - `onCraftedBy` no longer takes in a separate `Level` instance, now relying on the one provided by the `Player` + - `ItemStack` + - `validateStrict` is now public + - `onCraftedBy` no longer takes in a separate `Level` instance, now relying on the one provided by the `Player` + - `MapItem` + - `create` now takes in a `ServerLevel` instead of a `Level` + - `lockMap` is now private + - `ThrowablePotionItem` is now abstract, containing two methods to create the `AbstractThrownPotion` entity + - `WrittenBookItem#resolveBookComponents` -> `WrittenBookContent#resolveForItem` +- `net.minecraft.world.item.alchemy.PotionContents` now implements `TooltipProvider` + - `forEachEffect`, `applyToLivingEntity` now takes in a float representing a scalar for the duration +- `net.minecraft.world.item.component.WrittenBookContent` now implements `TooltipProvider` +- `net.minecraft.world.item.crafting` + - `SmithingRecipe#baseIngredient` now returns an `Ingredient` + - `SmithingTransformRecipe` now takes in a `TransmuteResult` instead of an `ItemStack` and an `Ingredient` for the base + - `SmithingTrimRecipe` now takes in `Ingredient`s instead of `Optional` wrapped entries along with a `TrimPattern` holder + - `TransmuteRecipe` now takes in a `TransmuteResult` instead of an `Item` holder +- `net.minecraft.world.item.crafting.display.SlotDisplay$SmithingTrimDemoSlotDisplay` now takes in a `TrimPattern` holder +- `net.minecraft.world.item.enchantment.EnchantmentInstance` is now a record +- `net.minecraft.world.level` + - `BlockGetter#boxTraverseBlocks` -> `forEachBlockIntersectedBetween`, not one-to-one + - `CustomSpawner#tick` no longer returns anything + - `GameRules$Type` now takes in a value class + - `Level` + - `onBlockStateChange` -> `updatePOIOnBlockStateChange` + - `isDay` -> `isBrightOutside` + - `isNight` -> `isDarkOutside` + - `setMapData` -> `net.minecraft.server.level.ServerLevel#setMapData` + - `getFreeMapId` -> `net.minecraft.server.level.ServerLevel#getFreeMapId` + - `LevelAccessor#blockUpdated` -> `updateNeighborsAt` +- `net.minecraft.world.level.biome.MobSpawnSettings$SpawnerData` is now a record +- `net.minecraft.world.level.block` + - `AttachedStemBlock` now extends `VegetationBlock` + - `AzaleaBlock` now extends `VegetationBlock` + - `Block#fallOn` now takes a double for the fall damage instead of a float + - `BushBlock` now extends `VegetationBlock` and implements `BonemealableBlock` + - `ColoredFallingBlock#dustColor` is now protected + - `CropBlock` now extends `VegetationBlock` + - `DeadBushBlock` -> `DryVegetationBlock` + - `DoublePlantBlock` now extends `VegetationBlock` + - `FallingBlock#getDustColor` is now abstract + - `FlowerBedBlock` now extends `VegetationBlock` + - `FlowerBlock` now extends `VegetationBlock` + - `FungusBlock` now extends `VegetationBlock` + - `LeafLitterBlock` now extends `VegetationBlock` + - `LeavesBlock` is now abstract, taking in the chance for a particle to spawn + - Particles are spawned via `spawnFallingLeavesParticle` + - `MangroveLeavesBlock` now extends `TintedParticleLeavesBlock` + - `MushroomBlock` now extends `VegetationBlock` + - `NetherSproutsBlock` now extends `VegetationBlock` + - `NetherWartBlock` now extends `VegetationBlock` + - `ParticleLeavesBlock` -> `LeafLitterBlock` + - `PinkPetalsBlock` -> `FlowerBedBlock` + - `RootsBlock` now extends `VegetationBlock` + - `Rotation` now has an index used for syncing across the network + - `SaplingBlock` now extends `VegetationBlock` + - `SeagrassBlock` now extends `VegetationBlock` + - `SeaPickleBlock` now extends `VegetationBlock` + - `StemBlock` now extends `VegetationBlock` + - `SweetBerryBushBlock` now extends `VegetationBlock` + - `TallGrassBlock` now extends `VegetationBlock` + - `TntBlock#prime` now returns whether the primed tnt was spawned. + - `WaterlilyBlock` now extends `VegetationBlock` +- `net.minecraft.world.level.block.entity` + - `BlockEntity` + - `parseCustomNameSafe` now takes in a nullable `Tag` instead of a string + - `getPosFromTag` now takes in the `ChunkPos` + - `$ComponentHolder#COMPONENTS_CODEC` is now a `MapCodec` + - `BLockEntityType#create` is no longer nullable +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner#codec` now returns a `MapCodec` +- `net.minecraft.world.level.block.state.StateHolder` + - `getNullableValue` is now private + - `hasProperty` no longer contains a generic +- `net.minecraft.world.level.chunk` + - `ChunkAccess#setBlockState` now takes in the block flags instead of a boolean, and has an overload to update all set + - `LevelChunk#replaceWithPacketData` now takes in a `Map` instead of a `CompoundTag` +- `net.minecraft.world.level.chunk.storage.SerializableChunkData#getChunkTypeFromTag` -> `getChunkStatusFromTag`, not one-to-one +- `net.minecraft.world.level.gameevent.vibrations.VibrationSystem#DEFAULT_VIBRATION_FREQUENCY` -> `NO_VIBRATION_FREQUENCY` +- `net.minecraft.world.level.levelgen.feature.TreeFeature#isVine` is now public +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `Direct` -> `DirectPoolAlias` + - `Random` -> `RandomPoolAlias` + - `RandomGroup` -> `RandomGroupPoolAlias` +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate$JigsawBlockInfo` now takes in a `ResourceKey` to the `StructureTemplatePool` instead of a raw `ResourceLocation` +- `net.minecraft.world.level.saveddata.maps.MapFrame` is now a record + - `save`, `load` -> `CODEC`, not one-to-one +- `net.minecraft.world.level.storage.loot.functions.SetWrittenBookPagesFunction#PAGE_CODEC` -> `WrittenBookContent#PAGES_CODEC` +- `net.minecraft.world.scores` + - `Score#write` -> `CODEC`, not one-to-one + - `Scoreboard` + - `savePlayerScores` -> `packPlayerScores`, not one-to-one + - `loadPlayerScores` -> `loadPlayerScore`, not one-to-one + - `Team$CollisionRule`, `$Visibility` are now `StringRepresentable` +- `net.minecraft.world.phys.shapes.EntityCollisionContext` now takes in a boolean representing if it is used for placing a block +- `net.minecraft.world.ticks.SavedTick` + - `loadTick`, `saveTick`, `save` -> `codec`, not one-to-one + - `loadTickList` -> `filterTickListForChunk`, not one-to-one + +#### List of Removals + +- `com.mojang.blaze3d.vertex.BufferUploader` +- `net.minecraft.core.Rotations#getWrapped*` +- `net.minecraft.network.chat.ComponentSerialization#FLAT_CODEC` +- `net.minecraft.network.protocol.game` + - `ClientboundAddExperimentOrbPacket` + - `ClientGamePacketListener#handleAddExperienceOrb` +- `net.minecraft.resources.ResourceLocation$Serializer` +- `net.minecraft.server.network.ServerGamePacketListenerImpl#addPendingMessage` +- `net.minecraft.world` + - `BossEvent$BossBarColor#byName`, `$BossBarOverlay#byName` + - `Clearable#tryClear` +- `net.minecraft.world.effect.MobEffectInstance#save`, `load` +- `net.minecraft.world.entity` + - `Entity` + - `isInBubbleColumn` + - `isInWaterRainOrBubble`, `isInWaterOrBubble` + - `newDoubleList`, `newFloatList` + - `recordMovementThroughBlocks` + - `EntityEvent#ATTACK_BLOCKED`, `SHIELD_DISABLED` + - `ItemBasedSteering` + - `addAdditionalSaveData`, `readAdditionalSaveData` + - `setSaddle`, `hasSadddle` + - `LivingEntity` + - `timeOffs`, `rotOffs` + - `rotA` + - `oRun`, `run` + - `animStep`, `animStep0` + - `appliedScale` + - `canBeNameTagged` + - `Mob` + - `DEFAULT_EQUIPMENT_DROP_CHANCE` + - `PRESERVE_ITEM_DROP_CHANCE_THRESHOLD`, `PRESERVE_ITEM_DROP_CHANCE` + - `NeutralMob#setLastHurtByPlayer` + - `PositionMoveRotation#ofEntityUsingLerpTarget` +- `net.minecraft.world.entity.ai.attributes.AttributeModifier#save`, `load` +- `net.minecraft.world.entity.animal` + - `Dolphin#setTreasurePos`, `getTreasurePos` + - `Fox$Variant#byName` + - `MushroomCow$Variant#byName` + - `Panda$Gene#byName` + - `Salmon$Variant#byName` + - `Turtle` + - `getHomePos` + - `setTravelPos`, `getTravelPos` + - `isGoingHome`, `setGoingHome` + - `isTravelling`, `setTravelling` +- `net.minecraft.world.entity.animal.armadillo.Armadillo$ArmadilloState#fromName` +- `net.minecraft.world.entity.npc.VillagerTrades#EXPERIMENTAL_WANDERING_TRADER_TRADES` +- `net.minecraft.world.entity.projectile.AbstractArrow#getBaseDamage` +- `net.minecraft.world.entity.raid.Raid` + - `getLevel`, `getId` + - `save` +- `net.minecraft.world.entity.vehicle.AbstractMinecart#hasCustomDisplay`, `setCustomDisplay` +- `net.minecraft.world.item.ItemStack#parseOptional`, `saveOptional` +- `net.minecraft.world.item.equipment.trim.TrimPattern#templateItem` +- `net.minecraft.world.level.Level#updateNeighborsAt(BlockPos, Block)` +- `net.minecraft.world.level.block.entity` + - `CampfireBlockEntity#dowse` + - `PotDecorations#save`, `load` +- `net.minecraft.world.level.levelgen.BelowZeroRetrogen#read` +- `net.minecraft.world.level.levelgen.structure.structures.RuinedPortalPiece$VerticalPlacement#byName` +- `net.minecraft.world.level.saveddata.maps.MapBanner#LIST_CODEC` +- `net.minecraft.world.scores.Team` + - `$CollisionRule#byName` + - `$Visibility#getAllNames`, `byName` +- `net.minecraft.world.ticks.LevelChunkTicks#save`, `load` + +### Step 4: 1.21.5 -> 1.21.6 + +## Minecraft 1.21.5 -> 1.21.6 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.5 to 1.21.6. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Soaryn for some `ItemStack` best practices and typo fixes +- @earthcomputer for color changes when drawing strings + +### 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](https://misode.github.io/versions/?id=1.21.6&tab=changelog). + +### GUI Changes + +The GUI rendering system has significantly changed from the previous version. While it may seem somewhat similar on the surface, the actual implementation details are much more complex and roundabout. This will explain a high-level overview of the new system with some basic examples. + +#### Prepare and Render + +Rendering a GUI has been broken into two phases: 'prepare' and 'render'. + +The prepare phase is what we typically consider the GUI render methods (e.g., `Gui#render`, `AbstractContainerScreen#renderBg`, etc.). These methods, instead of actually rendering the components, now submit them to the `GuiRenderState` to be stored for use during the 'render' phase. The `GuiRenderState` is stored on the `GameRenderer` and passed to the `GuiGraphics` which uses the previous methods to add the desired objects to the render state. + +The render phase is what actually handles the rendering of all the objects. This is handled through the `GuiRenderer`, which reads the data from the `GuiRenderState` and, after a bit of delegated preparation and sorting, renders the objects to the screen. The `GuiRenderer` is also stored on the `GameRenderer`. + +#### Element Ordering + +Now, how are elements rendered onto screen? In the previous versions, this happened mainly based on the order of the render calls. However, the new system using two different methods of sorting. The first method handles the depth using strata and a linear tree. The second method uses a comparator based on three things (in order of priorty): the `ScreenRectangle` scissor, the `RenderPipeline` order, and the `TextureSetup`'s hash code. These are all stored on the `GuiElementRenderState` passed to the `GuiRenderState` via `GuiRenderState#submitGuiElement`. + +Once the elements have been ordered, they are rendered starting at a Z of `0`, with each element rendered `0.01` ahead of the previous. + +As a warning, due to the element sort order, certain custom configurations may result in incorrect screen renders. As such, it is imperative that you understand how the methods and their assigned values work when sorting elements. + +##### Strata and Trees + +The first method of sorting handles the z-depth an object is rendered at. + +First let's start with the linear tree. As the name implies, it is basically a doubly-linked `GuiRenderState$Node` list. Each node contains its own list of elements to render. Navigating the node list is handled using `GuiRenderState#up` or `down`, where each either gets the next node, or creates a new one if it doesn't exist. Nodes within a given tree are rendered from bottom to top, meaning that `down` will render any elements submitted before the current node, while `up` will render any elements submitted after the current node. + +Determining what node an object is added to is computed automatically when submitting an element using its `ScreenArea`. The `ScreenArea` defines the `bounds` of your element to be rendered. Essentially, a node will be added in the `up` direction if the bounds of the element intersect with any other element on the current node. + +Then there are strata. A stratum is essentially a linear tree. Strata are rendered in the order they are created, which means calling `nextStratum` will render all elements after the previous stratum. This can be used if you want to group elements into a specific layer. Note: you cannot navigate to a prior stratum. + +##### The Comparator + +The comparator handles sorting the elements within a given node in a linear tree in a strata. + +###### Screen Rectangle Scissor + +The `ScreenRectangle` is simply the area that the element is allowed to draw to, stored via `GuiElementRenderState#scissorArea`. Elements with no specified `ScreenRectangle` will be ordered first, followed by the minimum Y, the maximum Y, the minimum X, and the maximum X. + +###### Render Pipeline + +`RenderPipeline`s define the pipeline used to render some object to the screen, including its shaders, format, uniforms, etc. This is stored via `GuiElementRenderState#pipeline`. Pipelines are sorted in the order they are built. This means that `RenderPipelines#ENTITY_TRANSLUCENT` will be rendered before `RenderPipelines#GUI` if on the same layer and scissor rectangle. As this is a system that relies on classloading constants, if you want to add new elements, make sure your mod loader supports some kind of dynamic pipeline ordering. + +###### Texture Hash Code + +`TextureSetup` defines `Sampler0`, `Sampler1`, and `Sampler2` for use in the render pipelines, stored via `GuiElementRenderState#textureSetup`. Elements with no textures will be ordered first, followed by `getSortKey` of the record object. Note that, at the moment, this returns the `hashCode` of the `TextureSetup`, which may be non-deterministic as `GpuTextureView` does not implement `hashCode`, relying instead on the identity object hash. + +#### GuiElementRenderState + +Now that we understand ordering, what exactly is the `GuiElementRenderState` that we've been using? Well essentially, every object rendered to the screen is represented by a `GuiElementRenderState`, from the player seen in the inventory menu to each individual item. A `GuiElementRenderState` defines four methods. First, there are the common ones used for ordering and how to render to the screen (`pipeline`, `scissorArea`, `textureSetup`, `bounds`). Then there is `buildVertices`, which takes in the `VertexConsumer` to write the vertices to and the z-depth. For GUIs, this typically calls `VertexConsumer#addVertexWith2DPose`. + +There are three types of `GuiElementRenderState`s provided by vanilla: `BlitRenderState`, `ColoredRectangleRenderState`, `GlyphEffectRenderState`, and `GlyphRenderState`. `ColoredRectangleRenderState` and `GlyphRenderState`/`GlyphEffectRenderState` are simple cases for handling a basic color rectangle and text character, respectively. `BlitRenderState` covers every other case as almost every method eventually writes to a `GpuTexture` which is then consumed by this. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState$Node#submitGuiElement`. The `GuiRenderState` makes `submitBlitToCurrentLayer` and `submitGlyphToCurrentLayer` available to add textures and glyphs. For example, these are called by `GuiGraphics#*line`, `fill`, and `blit*` methods. + +##### GuiItemRenderState + +`GuiItemRenderState` is a special case used to render an item to the screen. It takes in the stringified name of the item, the current pose, its XY coordinates, and its scissor area. The `ItemStackRenderState` it holds is what defines how the item is rendered. The rendering bounds are computed based on the item model bounding box when `ClientItem$Properties#oversizedInGui` is true; otherwise, using a 16x16 square when false. + +Just before the 'render' phase, the `GuiRenderer` effectively turns the `GuiItemRenderState` into a `GuiElementRenderState`, more specifically a `BlitRenderState`. This is done by constructing an item atlas `GpuTexture` which the item is drawn to, and then that texture is submitted as a `BlitRenderState`. All `GuiItemRenderState`s use `RenderPipelines#GUI_TEXTURED_PREMULTIPLIED_ALPHA`. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitItem`. This is called by `GuiGraphics#render*Item*` methods. + +##### GuiTextRenderState + +`GuiTextRenderState` is a special case used to render text to the screen. It takes in the `Font`, `FormattedCharSequence`, current pose, its XY coordinates, color, background color, whether it has a drop shadow, and its rendering bounds. + +Just before the 'render' phase, the `GuiRenderer` turns the `GuiTextRenderState` into a `GuiElementRenderState`, more specifically a `GlyphRenderState` or `GlyphEffectRenderState` depending on what should be rendered via `GuiTextRenderState#ensurePrepared`. This performs a similar process as the item render state where the text is written to a `GpuTexture` to be consumed. Any backgrounds are rendered first, followed by the background effects, then the character, then finally the foreground effects. + +`GuiElementRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitText`. This is called by `GuiGraphics#draw*String` and `render*Tooltip` methods. + +##### Picture-in-Picture + +Picture-in-Picture is a special case used to render arbitrary objects to a `GpuTexture` to be passed into a `BlitRenderState`. A Picture-in-Picture is made up of two components the `PictureInPictureRenderState`, and the `PictureInPictureRenderer`. + +`PictureInPictureRenderState` is an interface which can store some data used to render the object to the texture. By default, it must supply the minimum and maximum XY coordinates, the texture scale, its scissor area, and its rendering bounds. You can also choose to specify the transformation matrix via `pose`. Any other data can be added by the implementor. + +```java +public record ExamplePIPRenderState(boolean data, int x0, int x1, int y0, int y1, float scale, @Nullable ScreenRectangle scissorArea, @Nullable ScreenRectangle bounds) + implements PictureInPictureRenderState {} +``` + +`PictureInPictureRenderer` is the renderer which writes the data to the `GpuTexture`. It does this by taking advantage of the fact that the `RenderSystem#output*Override` textures are written to in a `BufferSource` if they are not null. A `PictureInPictureRenderer` method must implement three methods. `getRenderStateClass` returns the class of the `PictureInPictureRenderState` implementation. `getTextureLabel` returns the texture label for debugging purposes. `renderToTexture` is where the render logic is called to write the data to the texture. + +```java +public class ExamplePIPRenderer extends PictureInPictureRenderer { + + // Takes in the buffer source from `RenderBuffers` + public ExamplePIPRenderer(MultiBufferSource.BufferSource bufferSource) { + super(bufferSource); + } + + @Override + public Class getRenderStateClass() { + // The class of the render state + return ExamplePIPRenderState.class; + } + + @Override + protected void renderToTexture(ExamplePIPRenderState renderState, PoseStack pose) { + // Render whatever you want here + // You can make use of the buffer source via `this.bufferSource` + } + + @Override + protected void blitTexture(ExamplePIPRenderState renderState, GuiRenderState guiState) { + // You can override this if you want to change how your layer is submitted to the render state + // By default, this uses the `BlitRenderState` + + // Remove this if you want to handle submission yourself + super.blitTexture(renderState, guiState); + } + + @Override + protected boolean textureIsReadyToBlit(ExamplePIPRenderState renderState) { + // When true, this will skip setting up the textures and projection matrices and use whatever is currently available + return false; + } + + @Override + protected String getTextureLabel() { + // This can be anything, but it should be unique + return "examplemod: example pip"; + } +} +``` + +To be able to use the renderer, is must be added to `GuiRenderer#pictureInPictureRenderers`. As the constructor takes in an immutable list while the renderer stores an immutable map, use whatever method is provided by your mod loader. + +```java +// We will assume: +// - `GuiRenderer#bufferSource` is accessible +// - The map is made mutable +// For some GuiRenderer renderer + +var examplePIP = new ExamplePIPRenderer(renderer.bufferSource); + +renderer.pictureInPictureRenderers.put( + examplePIP.getRenderStateClass(), + examplePIP +); +``` + +`PictureInPictureRenderState`s are added to the `GuiRenderState` via `GuiRenderState#submitPicturesInPictureState`. This is called by `GuiGraphics#submit*RenderState` methods. + +#### Logic Changes + +`GuiGraphics#drawString` now joins the rest of the `GuiGraphics` methods by allowing the `int` color argument to accept an alpha channel (upper eight bits). This means that any color string without an alpha specified will not be rendered. Previous behavior can be replicated by ORing your `int` color with `0xFF000000` or by passing your color into `ARGB#opaque`. + +#### Contextual Bars + +Many HUD elements on the screen take over where the experience bar is rendered. However, how these are rendered and which one is prioritized is handled through the contextual bar system. A contextual bar is made up of two parts, the `ContextualBarRenderer`, responsible for rendering the bar to the screen, and the `Gui$ContextualInfo`, which is used as the bar's identifier. + +A `ContextualBarRenderer` requires two methods to be implemented: `renderBackground`, which renders the bar itself, and `render`, which renders elements that appear on top of the bar. + +```java +public class ExampleContextualBarRenderer implements ContextualBarRenderer { + + @Override + public void renderBackground(GuiGraphics graphics, DeltaTracker delta) { + // Render background bar sprites here + } + + @Override + public void render(GuiGraphics graphics, DeltaTracker delta) { + // Render anything that might sit on top of the bar + } +} +``` + +`Gui$ContextInfo` is an enum, so your mod loader will need to either allow extensions or some other method of identifying a bar renderer. Then, the renderer needs to be added to map of renderers stored in `Gui#contextualInfoBarRenderers`. As this is an immutable map, use whatever method is provided by your mod loader. + +```java +// We will assume: +// - Created a new enum value `EXAMPLEMOD_EXAMPLE` +// - The map is made mutable +// For some Gui gui +gui.contextualInfoBarRenderers.put( + EXAMPLEMOD_EXAMPLE, + ExampleContextualBarRenderer::new +); +``` + +Finally, to get your bar to be called and prioritized, you need to modify `Gui#nextContextualInfoState` to return your enum value, or whatever method is provided by your mod loader. + +#### Dialogs + +To more generally handle screens which provide some basic functionalities -- such as confirmation screens, button selection, or user input, Vanilla has provided a generic dialog system. These dialogs can be constructed in a datapack and delivered on the client by calling `Player#openDialog`. The basic JSON description is documented in [Minecraft Snapshot 25w20a](https://www.minecraft.net/en-us/article/minecraft-snapshot-25w20a). + +For a quick overview, a basic `Dialog` contains the following components: a title, an optional external title for navigation, whether the screen can be closed by pressing 'esc', and its `DialogBody` contents. Everything else is determined by the dialog itself, but it has functionality for user inputs via `InputControl`s. Buttons are typically added through `ClickAction`s which hold the common button data and an event to execute on click. If the dialog is canceled (e.g., closed), then `onCancel` is run. + +`DialogBody` and `InputControl` are simply generic interfaces that have no defined structure. Implementing them, or any dialog for that matter, requires some registration to the available types on both the client and server. + +##### Custom Bodies + +A `DialogBody` is simply the contents of a dialog screen. This is generally immutable information that should be displayed at all times. Every dialog holds a list of these `DialogBody`s as every screen has some text to explain what it is for. It only contains one method `mapCodec`, which is used as the registry key and encoder for the body information. + +```java +// Obviously, a body would have actual contents, but this is simply an example implementation +public record ExampleDialogBody(boolean val1, int val2) implements DialogBody { + public static final MapCodec BODY_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.BOOL.fieldOf("val1").forGetter(ExampleDialogBody::val1), + Codec.INT.fieldOf("val2").forGetter(ExampleDialogBody::val2) + ).apply(ExampleDialogBody::new)); + + @Override + public MapCodec mapCodec() { + return BODY_CODEC; + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_BODY_TYPE, "examplemod:example_body", ExampleDialogBody.BODY_CODEC); +``` + +```json5 +// For some dialog +{ + // ... + "body": [ + { + // Our body + "type": "examplemod:example_body", + "val1": true, + "val2": 0 + }, + // ... + ] +} +``` + +How does this body actually render then? Well, that is done via a `DialogBodyHandler`. This contains a single method `createControls` that generates the `LayoutElement` to render given the `DialogScreen` and the dialog data. This body handler can be linked to the `MapCodec` via `DialogBodyHandlers#register`. + +```java +public class ExampleDialogBodyHandler implements DialogBodyHandler { + + @Override + public LayoutElement createControls(DialogScreen screen, ExampleDialogBody body) { + // Create the element (widgets, layouts, etc.) + return new StringWidget(...); + } +} + +// Note that `register` is not public, so this needs to be access widened +DialogBodyHandlers.register(BODY_CODEC, new ExampleDialogBodyHandler()); +``` + +##### Custom Inputs + +An `InputControl` represents some input a user can provide, whether that would be some text or a button submission click. This is generally made up of components that can accept or provide some string value or tag based on a state. All dialogs can provide these inputs; through the `DialogControlSet`. It only contains one method `mapCodec`, which is used as the registry key and encoder for the input control. + +```java +public record ExampleInputControl(int value) implements InputControl { + public static final MapCodec INPUT_CODEC = Codec.INT.fieldOf("value").xmap( + ExampleInputControl::new, ExampleInputControl::value + ); + + @Override + public MapCodec mapCodec() { + return INPUT_CODEC; + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.INPUT_CONTROL_TYPE, "examplemod:example_input", ExampleInputControl.INPUT_CODEC); +``` + +```json5 +// For some dialog (assume `minecraft:simple_input_form`) +{ + "inputs": [ + { + // Our input + "type": "examplemod:example_input", + + // The identifier for the data of this input + "key": "example_input", + + "value": 0 + }, + // ... + ] +} +``` + +Like above, the input is rendered via a `InputControlHandler`. This contains a single method `addControl`, which provides the `Screen` and input control and creates the `LayoutElement` and its associated `Action$ValueGetter` via `$Output`. This input handler can be linked to the `MapCodec` via `InputControlHandlers#register`. + +```java +public class ExampleInputControlHandler implements InputControlHandler { + + @Override + public void addControl(ExampleInputControl control, Screen screen, InputControlHandler.Output output) { + EditBox box = new EditBox(...); + box.setValue(String.valueOf(control.value())); + + // Add the elements to the output + output.accept( + // The element to render + box, + // The value output of the input + Action.ValueGetter.of(box::getValue) + ); + } +} + +// Note that `register` is not public, so this needs to be access widened +InputControlHandlers.register(INPUT_CODEC, new ExampleInputControlHandler()); +``` + +#### Custom Actions + +As shown above, an input can provide some value to pass to an `Action`. The former is known as a `$ValueGetter`, which essentially gets a stringified or tagged input to use. The latter, meanwhile, ends up creating the `ClickEvent` that is sent to the server. These are typically created through `ActionButton`s which defines some common button data along with the `Action` to perform. + +A custom action contains two methods: one which returns the `MapCodec` (`codec`) to use during encoding, while the other creates the `ClickEvent` based on the map of input strings to their `$ValueGetter`s. + +```java +public record ExampleAction() implements Action { + public static final MapCodec ACTION_CODEC = MapCodec.unit(new ExampleAction()); + + @Override + public MapCodec codec() { + return ACTION_CODEC; + } + + @Override + public Optional createAction(Map keysToGetters) { + // Handle how you want to map the key input map to some click event + return Optional.empty(); + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_ACTION_TYPE, "examplemod:example_action", ExampleAction.ACTION_CODEC); +``` + +```json5 +// For some dialog (assume `minecraft:notice`) +{ + "action": { + // Button data + "label": "Example!", + "tooltip": "This is an example!", + "width": 80, + + // The action to perform + "action": { + // Out action type + "type": "examplemod:example_action" + } + } +} +``` + +Depending on how you implement your `Dialog` below, the action button will automatically be added to the screen, or you will need to add it in one of the methods via `DialogControlSet#createActionButton`: + +```java +// For some DialogScreen implementation, we will assume some `SimpleDialog` +@Override +protected void updateHeaderAndFooter(HeaderAndFooterLayout layout, DialogControlSet controls, SimpleDialog dialog, DialogConnectionAccess access) { + dialog.mainActions().forEach(actionButton -> layout.addToFooter(controls.createActionButton(actionButton).build())); +} +``` + +##### Custom Dialogs + +A `Dialog` is pretty much all of the above components put together as desired. It is up to the user to choose how to implement them. Every `Dialog` must provide its `CommonDialogData`, which defines the basic title, body contents, and functionality. In additional, a `Dialog` may choose to execute an `Action` on close via `onCancel`. + +```java +// `common` is already implemented by the record +public record ExampleDialog(CommonDialogData common, boolean val1, int val2) implements Dialog { + public static final MapCodec DIALOG_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + CommonDialogData.MAP_CODEC.forGetter(ExampleDialog::common), + Codec.BOOL.fieldOf("val1").forGetter(ExampleDialog::val1), + Codec.INT.fieldOf("val2").forGetter(ExampleDialog::val2) + ).apply(ExampleDialog::new)); + + @Override + public MapCodec codec() { + return DIALOG_CODEC; + } + + @Override + public Optional onCancel() { + // You can choose to return something here, or empty if nothing should be done + return Optional.empty(); + } +} + +// Register the codec to the registry +Registry.register(BuiltInRegistries.DIALOG_TYPE, "examplemod:example_dialog", ExampleDialog.DIALOG_CODEC); +``` + +```json5 +// For some dialog in `data/examplemod/dialog/example.json` +{ + // Our dialog type + "type": "examplemod:example_dialog", + + // Common button data + "title": "Example dialog!", + "can_close_with_escape": true, + "after_action": "wait_for_response", + + // Our custom params + "val1": true, + "val2": 0 +} +``` + +Like the others, a dialog type can only be rendered through a `DialogScreen$Factory`. This interface constructs a `DialogScreen` given the parent `Screen`, `Dialog` instance, and `DialogConnectionAccess` used to communicate to the server. This dialog screen can then be linked to the `MapCodec` via `DialogScreens#register`. + +```java +public class ExampleDialogScreen extends DialogScreen { + + public ExampleDialogScreen(@Nullable Screen previousScreen, ExampleDialog dialog, DialogConnectionAccess connectionAccess) { + super(previousScreen, dialog, connectionAccess); + } + + // You can choose to implement the other methods as you wish + // See existing dialog screens for an example + + @Override + protected void populateBodyElements(LinearLayout layout, DialogControlSet controls, ExampleDialog dialog, DialogConnectionAccess access) { + // Add elements and actions to the body of the screen (usually the center) + } + + @Override + protected void updateHeaderAndFooter(HeaderAndFooterLayout layout, DialogControlSet controls, ExampleDialog dialog, DialogConnectionAccess access) { + // Add elements and actions to the header and footer of the screen (top and bottom) + } +} + +// Note that `register` is not public, so this needs to be access widened +DialogScreens.register(DIALOG_CODEC, ExampleDialogScreen::new); +``` + +- `com.mojang.blaze3d.vertex.VertexConsumer#addVertexWith2DPose` - Adds a vertex to be rendered in 2d space. +- `net.minecraft.client.gui` + - `Font` + - `drawInBatch` no longer returns anything + - `prepareText` - Prepares the text to be rendered to the screen. + - `splitIgnoringLanguage` - Splits the text in the order provided without being processed by the language handler. + - `ALPHA_CUTOFF` is removed + - `$GlyphVisitor` - An interface that handles a glyph or effect to be rendered. + - `$PreparedText` - An interface that defines how a piece of text should be rendered by visiting each glyph. + - `$StringRenderOutput` -> `$PreparedTextBuilder`, no longer takes in the `MultiBufferSource`, `Matrix4f`, `$DisplayMode`, packed light coords, and the inverse depth boolean + - `Gui` + - `shouldRenderDebugCrosshair` - Returns true if the debug crosshair should be rendered. + - `$RenderFunction` - An interface that defines how a certain section or element is rendered on the gui. + - `GuiGraphics` now takes in a `GuiRenderState` instead of the `MultiBufferSource$BufferSource` + - `MAX_GUI_Z`, `MIN_GUI_Z` are removed + - `pose` now returns a `Matrix3x2fStack` + - `flush` is removed + - `nextStratum` - Adds another layer to traverse through that renders after all nodes in the previous tree. + - All methods no longer take in a `RenderType`, `VertexConsumer`, or `Function`, instead specifying a `RenderPipeline` and a `TextureSetup` depending on the call + - `drawString`, `drawStringWithBackdrop` no longer returns anything + - `draw*String` methods must now pass in an ARGB value, where A cannot be 0. + - `renderItem(ItemStack, int, int, int, int)` is removed + - `drawSpecial` is removed, replaced by individual `submit*RenderState` depending on the special case + - `blurBeforeThisStratum` - Notifies the render state that a blur effect should render between this strata and all previously rendered ones. This can only be applied between once per frame. + - `render*Tooltip` -> `set*TooltipForNextFrame`, does not directly add to the render state, instead waiting for `renderDeferredTooltip` to be called when not present or overridden + - `renderDeferredTooltip` - Adds the tooltip information to be rendered on a new stratum. + - `blitSprite` now has an overload that takes in a float R tint color + - `$ScissorStack#peek` - Gets the last rectangle on the stack. + - `LayeredDraw` class is removed +- `net.minecraft.client.gui.components` + - `AbstractTextAreaWidget` now has an overload which takes in two additional booleans of whether to show the background or decorations + - `AbstractWidget#getTooltip` is removed + - `CycleButton$Builder#displayOnlyValue` now has an overload that takes in the `boolean` to set + - `EditBox` + - `setCentered` - Sets whether the text position should be centered. + - `setTextShadow` - Sets whether the text should have a drop shadow effect. + - `FocusableTextWidget` can now take in a boolean indicating whether to fill the background + - `DEFAULT_PADDING` is now public + - `ImageWidget#updateResource` - Updates the sprite of the image on the component. + - `ItemDisplayWidget` - A widget that displays an `ItemStack`. + - `LogoRenderer#keepLogoThroughFade` - When true, keeps the logo visible even when the title screen is fading. + - `MultiLineEditBox` is now package private and should be constructed via `builder`, calling the `$Builder#set*` methods + - `setLineLimit` - Sets the line limit of the text field. + - `setValue` now has an overload that takes in the `boolean` to determine whether it should force pass the max line limit + - `MultiLineLabel` + - `getStyleAtCentered` - Computes the component style for centered text. + - `getStyleAtLeftAligned` - Computes the component style for left aligned text. + - `MultilineTextField#NO_CHARACTER_LIMIT` -> `NO_LIMIT` + - `setLineLimit` - Sets the maximum number of lines that can be written on the text field. + - `hasLineLimit` - Returns whether the text field has some line limit. + - `setValue` now has an overload that takes in the `boolean` to determine whether it should force pass the max line limit + - `MultiLineTextWidget#configureStyleHandling` - Sets whether something is displayed when hovering over components and what to do on click. + - `ScrollableLayout` - A layout with some defined bounds that can be scrolled through. + - `SplashRenderer#render` now takes in a float for the R color instead of an int + - `WidgetTooltipHolder#refreshTooltipForNextRenderPass` now takes in the `GuiGraphics` and the XY position +- `net.minecraft.client.gui.components.spectator.SpectatorGui#renderTooltip` -> `renderAction` +- `net.minecraft.client.gui.components.tabs` + - `LoadingTab` - A tab that indicates information is currently being loaded. + - `Tab#getTabExtraNarration` - Returns the hint narration of the tab. + - `TabManager` can now take in two `Consumer`s on what to do when a tab is selected or deselected + - `TabNavigationBar` + - `getTabs` - Returns the list of tabs on the navigation bar. + - `setTabActiveState` - Sets the active state of the given tab index. + - `setTabTooltip` - Sets the tooltip information of the given tab index. +- `net.minecraft.client.gui.components.toasts` + - `NowPlayingToast` - A toast that displays the currently playing background music. + - `Toast` + - `xPos`, `yPos` - Gets the x and y position in relation to the current toast index. + - `onFinishedRendering` - A method called once the toast has finished rendered on screen. + - `ToastManager` now takes in the `Options` + - `showNowPlayingToast`, `hideNowPlayingToast`, `createNowPlayingToast`, `removeNowPlayingToast` - Handles the 'Now Playing' music toast. + - `$ToastInstance#resetToast` - Resets the toast. +- `net.minecraft.client.gui.contextualbar` + - `ContextualBarRenderer` - An interface which defines an object with some background to render. + - `ExperienceBarRenderer` - Draws the experience bar. + - `JumpableVehicleBarRenderer` - Draws the jump power bar (e.g. horse jumping). + - `LocatorBarRenderer` - Draws the bar that points to given waypoints. +- `net.minecraft.client.gui.font.GlyphRenderTypes` now takes in a `RenderPipeline` for the gui rendering +- `net.minecraft.client.gui.font.glyphs.BakedGlyph` now takes in a `GpuTextureView` + - `extractEffect` - Extracts a glyph effect (e.g. drop shadow) submits the element to be rendered. + - `extractBackground` - Extracts a glyph effect and submits the element to be rendered on the background Z. + - `left`, `top`, `right`, `bottom` - Computes the bounds of the glyph. + - `textureView` - Returns the view of the texture making up the glyph. + - `guiPipeline` - Returns the pipeline to render the glyph. + - `renderChar`, `renderEffect` now takes in an additional boolean that sets the Z offset to `0` when true and `0.001` when false + - `$Effect#left`, `top`, `right`, `bottom` - Computes the bounds of the glyph effect. + - `$GlyphInstance#left`, `top`, `right`, `bottom` - Computes the bounds of the glyph instance. +- `net.minecraft.client.gui.navigation.ScreenRectangle` + - `transformAxisAligned` now takes in a `Matrix3x2f` instead of a `Matrix4f` + - `intersects` - Returns whether this rectangle overlaps with another rectangle. + - `encompasses` - Returns whether this rectangle contains the entirety of another rectangle. + - `transformMaxBounds` - Returns a new rectangle that is moved into a given position by the provided matrix. +- `net.minecraft.client.gui.render` + - `GuiRenderer` - A class that renders all submitted elements to the screen. + - `TextureSetup` - A record that specifies samplers 0-2 for use in a render pipeline. The first two textures views are arbitrary with the third being for the current lightmap texture. +- `net.minecraft.client.gui.render.pip` + - `GuiBannerResultRenderer` - A renderer for the banner result preview. + - `GuiBookModelRenderer` - A renderer for the book model in the enchantment screen. + - `GuiEntityRenderer` - A renderer for a given entity. + - `GuiProfilerChartRenderer` - A renderer for the profiler chart. + - `GuiSignRenderer` - A renderer for the sign background in the edit screen. + - `GuiSkinRenderer` - A renderer for a player with a given skin. + - `OversizedItemRenderer` - A rendered for when an item model should be rendered larger than its item slot. + - `PictureInPictureRenderer` - An abstract class meant for rendering dynamic elements that are not standard 2d elements, items, or text. +- `net.minecraft.client.gui.render.state` + - `BlitRenderState` - An element state for a basic 2d texture blit. + - `ColoredRectangleRenderState` - An element state for a simple rectangle with a tint. + - `GlyphEffectRenderState` - An element state for a glyph effect (e.g., font text drop shadow). + - `GlyphRenderState` - An element state for a glyph (font text). + - `GuiElementRenderState` - An interface representing the state of a element to render. + - `GuiItemRenderState` - A record representing the state of an item to render. + - `GuiRenderState` - The state of the GUI to render to the screen. + - `GuiTextRenderState` - A record representing the state of the text and its location to render. + - `ScreenArea` - An interface which defines the render area of an element. This does not affect scissoring, instead layer orders. +- `net.minecraft.client.gui.render.state.pip` + - `GuiBannerResultRenderState` - The state of the banner result preview. + - `GuiBookModelRenderState` - The state of the book model in the enchantment screen. + - `GuiEntityRenderState` - The state of a given entity. + - `GuiProfilerChartRenderState` - The state of the profiler chart. + - `GuiSignRenderState` - The state of the sign background in the edit screen. + - `GuiSkinRenderState` - The state of a player with a given skin. + - `OversizedItemRenderState` - The state of an item model that can be rendered at an arbitrary size. + - `PictureInPictureRenderState` - An interfaces that defines the basic state necessary to render the picture-in-picture to the screen. +- `net.minecraft.client.gui.screens` + - `ConfirmScreen` + - `layout` - Defines a vertical list of elements spaced by eight units. + - `yesButton`, `noButton` -> `yesButtonComponent`, `noButtonComponent` + - `yesButton`, `noButton` now represent the actual buttons + - `addAdditionalText` - Adds any additional text before the buttons in the layout. + - `addButtons` - Adds the buttons in the layout. + - `PauseScreen` + - `rendersNowPlayingToast` - Returns whether the 'Now Playing' toast should be rendered. + - `onDisconnect` -> `disconnectFromWorld`, now public and static; not one-to-one + - `Screen` + - `CUBE_MAP` -> `net.minecraft.client.renderer.GameRenderer#cubeMap` + - `PANORAMA` -> `net.minecraft.client.renderer.GameRenderer#panorama` + - `renderBlurredBackground` now takes in the `GuiGraphics` + - `*TooltipForNextRenderPass` methods are either removed or moved to `GuiGraphics` + - `FADE_IN_TIME` - Represents how much time in milliseconds does it take for some element to fade in. + - `fadeWidgets` - Sets the alpha of the `AbstractWidget`s added as children to the screen. + - `handleClickEvent` - Handles the event to play when the component is clicked. + - `defaultHandleClickEvent` - The default logic to execute when the component is clicked. + - `clickUrlAction` - The logic to perform when a URL is clicked (has the Open URL style). + - `clickCommandAction` - The logic to perform when a command should be executed (has the \* Command style). +- `net.minecraft.client.gui.screens.dialog` + - `ButtonListDialogScreen` - A dialog screen that contains some list of buttons. + - `DialogConnectionAccess` - A client side interface that processes general interaction information from the dialog. + - `DialogControlSet` - An input handler for a dialog screen. + - `DialogListDialogScreen` - A button list of `DialogListDialog`s. + - `DialogScreen` - A screen for some dialog modal. + - `DialogScreens` - A factory registry of dialog modals to their associated screen. + - `MultiButtonDialogScreen` - A button list of `MultiActionDialog`s. + - `ServerLinksDialogScreen` - A button list of `ServerLinksDialog`s. + - `SimpleDialogScreen` - A dialog screen for some simple dialog. + - `WaitingForResponseScreen` - A screen that handles the downtime between client/server communication of dialog submissions. +- `net.minecraft.client.gui.screens.dialog.body` + - `DialogBodyHandler` - A list of body elements describing the contents between the title and actions/inputs. + - `DialogBodyHandlers` - A registry of `DialogBody`s to their `DialogBodyHandler`s. +- `net.minecraft.client.gui.screens.dialog.input` + - `InputControlHandler` - A user input handler. + - `InputControlHandlers`- A registry of `InputControl`s to their `InputControlHandler`s. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractContainerScreen` + - `SLOT_ITEM_BLIT_OFFSET` is removed + - `renderContents` - Renders the slot and labels of an inventory. + - `renderCarriedItem` - Renders the held item. + - `renderSnapbackItem` - Renders the swapped item with the held item. + - `$SnapbackData` - Holds the information about the dragging or swapped item as it moves from the held location to its slot location. + - `AbstractSignEditScreen#offsetSign` -> `getSignYOffset`, not one-to-one + - `BookEditScreen` + - `TEXT_*`, `IMAGE_*`, `BACKGROUND_TEXTURE_*` are now public + - `BookSignScreen` - A screen for signing a book. + - `BookViewScreen` + - `closeScreen` -> `closeContainerOnServer`, not one-to-one + - `$BookAccess#getPage` now returns a `Component` + - `EffectsInInventory` + - `renderEffects` is now public + - `renderTooltip` has been overloaded to a public method + - `InventoryScreen#renderEntityInInventory` no longer takes in the XY offset, instead taking in 4 `int`s to represent the region to render to + - `ItemCombinerScreen#renderFg` is removed +- `net.minecraft.client.gui.screens.inventory.tooltip` + - `ClientTooltipComponent#renderText` no longer takes in the pose and buffer, instead the `GuiGraphics` to submit the text for rendering + - `TooltipRenderUtil#renderTooltipBackground` no longer takes in a Z offset +- `net.minecraft.client.gui.screens.multiplayer.ServerLinksScreen` class is removed, replaced by dialog modal +- `net.minecraft.client.gui.screens.social` + - `PlayerEntry#refreshHasDraftReport` - Sets whether the current context as a report for this player. + - `SocialInteractionsPlayerList#refreshHasDraftReport` - Refreshes whether the current context as a report for all players. +- `net.minecraft.client.gui.screens.worldselection.ExperimentsScreen$ScrollArea` class is removed, replaced by the `ScrollableLayout` +- `net.minecraft.client.model.geom.ModelPart#getExtentsForGui` - Gets the set of vectors representing the part transformed into their appropriate space. +- `net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl` + - `showDialog` - Shows the current dialog, creating the screen dynamically. + - `serverLinks` - Returns the entries of server links the client can access. + - `createDialogAccess` - Creates the dialog handler on the client used for communication. + - `clearDialog` - Closes the current dialog screen. +- `net.minecraft.client.player.LocalPlayer#experienceDisplayStartTick` - Represents the start tick of when the experience display should be prioritized. +- `net.minecraft.client.renderer` + - `GameRenderer` no longer takes in a `ResourceManager` + - `ITEM_ACTIVATION_ANIMATION_LENGTH` is removed + - `setRenderHand` is removed + - `renderZoomed` is removed + - `getPanorama` - Returns the panorama renderer. + - `LightTexture#getTexture` -> `getTextureView`, not one-to-one + - `MapRenderer#WIDTH`, `HEIGHT` are now public + - `PanoramaRenderer#registerTextures` - Registers the texture for use by the cube map. + - `PostPass$Input#texture` now returns a `GpuTextureView` instead of a `GpuTexture` + - `RenderPipelines` + - `GUI_OVERLAY`, `GUI_GHOST_RECIPE_OVERLAY`, `GUI_TEXTURED_OVERLAY` are removed + - `GUI_TEXTURED_PREMULTIPLIED_ALPHA` - A pipeline that assumes the textures have already had their transparency premultiplied during the composite stage. + - `RenderStateShard` + - `$Builder#add` no longer takes in whether the shard should be blurred + - `$TextureStateShard` no longer takes in a `TriState` to set the blur mode + - `RenderType` + - `debugLine` is removed + - `gui`, `guiOverlay`, `guiTexturedOverlay`, `guiOpaqueTexturedBackground`, `guiNauseaOverlay`, `guiTextHighlight`, `guiGhostRecipeOverlay`, `guiTextured` are removed + - `vignette` is removed + - `crosshair` is removed + - `mojangLogo` is removed + - `ScreenEffectRenderer` is now an instance implementation instead of simply a static method + - The constructor takes in the current `Minecraft` instance and a `MultiBufferSource` + - `renderScreenEffect` is now an instance method, taking in whether the entity is sleeping and the partial tick + - `resetItemActivation`, `displayItemActivation` - Handles when an item is automatically activated (e.g., totem). +- `net.minecraft.client.renderer.blockentity` + - `*Renderer#getExtents` - Adds the transformed vectors representing all models to a set. + - `HangingSignRenderer` + - `MODEL_RENDER_SCALE` is now public + - `translateBase` is now public + - `SignRenderer` + - `RENDER_SCALE` is now public + - `applyInHandTransforms` - Transforms the stack to properly represent the held sign's position. + - `SkullBlockRenderer#getRenderType(SkullBlock$Type, ResolvableProfile, ResourceLocation)` -> `getSkullRenderType`, `getPlayerSkinRenderType`; not one-to-one +- `net.minecraft.client.renderer.entity.ItemRenderer` + - `GUI_SLOT_CENTER_X`, `GUI_SLOT_CENTER_Y`, `ITEM_DECORATION_BLIT_OFFSET` are removed + - `COMPASS_*` -> `SPECIAL_*` +- `net.minecraft.client.renderer.item` + - `ClientItem$Properties#oversizedInGui` - When true, allows an item to render outside the 16x16 box in a GUI; otherwise, clips the size to the box. + - `ItemStackRenderState` + - `setAnimated`, `isAnimated` - Returns whether the item is animated (e.g., foil). + - `appendModelIdentityElement`, `getModelIdentity`, `clearModelIdentity` - Handles the identity component being rendered. + - `getModelBoundingBox` - Computes the bounding box of the model. + - `setOversizedInGui`, `isOversizedInGui` - Handles when the item can be oversized in the GUI based on its property. +- `net.minecraft.client.renderer.special` + - `PlayerHeadSpecialRenderer` - Renders an player head based on its render info. + - `SkullSpecialRenderer` now implements `NoDataSpecialModelRenderer`, no longer taking in the model or texture override, instead just the `RenderType` to use + - `SpecialModelRenderer#getExtents` - Adds the transformed vectors representing all models used by this renderer to a set. +- `net.minecraft.client.renderer.texture.TextureAtlasSprite#isAnimated` - Returns whether the sprite has any animation. +- `net.minecraft.commands.arguments.ResourceOrIdArgument#dialog`, `getDialog`, `$DialogArgument` - Handles command arguments for dialog screens. +- `net.minecraft.core.registries` + - `BuiltInRegistries#DIALOG_TYPE`, `DIALOG_ACTION_TYPE`, `INPUT_CONTROL_TYPE`, `DIALOG_BODY_TYPE` + - `Registries#DIALOG_TYPE`, `DIALOG_ACTION_TYPE`, `INPUT_CONTROL_TYPE`, `DIALOG_BODY_TYPE`, `DIALOG` +- `net.minecraft.data.tags.DialogTagsProvider` - A tags provider for dialogs. +- `net.minecraft.network.chat` + - `ClientEvent` + - `$Action#SHOW_DIALOG`, `CUSTOM` + - `valueCodec` - Returns the map codec used to encode this action. + - `$Custom` - An event that contains some nbt payload to send to the server, currently does nothing. + - `$ShowDialog` - An event that shows the specified dialog. + - `CommonComponents` + - `GUI_RETURN_TO_MENU` - The component that displays the 'Return to Menu' text. + - `disconnectButtonLabel` - Returns the component based on whether the server is local. +- `net.minecraft.network.protocol.common` + - `ClientboundClearDialogPacket` - Closes the current dialog screen. + - `ClientboundShowDialogPacket` - Opens a new dialog screen. + - `ServerboundCustomClickActionPacket` - Sends a custom action to the server. +- `net.minecraft.server.dialog` + - `ActionButton` - A button that can perform some `Action` on click. + - `ButtonListDialog` - A dialog modal that has some number of columns to click buttons of. + - `CommonButtonData` - The data that is associated with every button within a dialog modal. + - `CommonDialogData` - The data that is associated with every dialog modal. + - `ConfirmationDialog` - A dialog modal whether you can either click yes or no. + - `Dialog` - The base interface that defines some dialog modal. + - `DialogAction` - The action to perform typically after some action button is clicked. + - `DialogListDialog` - A scrollable list of buttons that lead to other dialogs. + - `Dialogs` - A datapack bootstrap registering `Dialog`s. + - `DialogTypes` - A registry of map codecs to encode some dialog model. + - `Input` - A handler that maps some key to an `InputControl`. + - `MultiActionDialog` - A scrollable list of actions arrange in columns. + - `NoticeDialog` - A simple screen with one action in the footer. + - `ServerLinksDialog` - A scrollable list of links received from the server, arrange in columns. + - `SimpleDialog` - A dialog that defines the main actions that can be taken. +- `net.minecraft.server.dialog.action` + - `Action` - A general operation to perform on some input, usually a button click. + - `ActionTypes` - A registry of map codecs to encode some action. + - `CustomTemplate` - Builds a command and requests the server to run it. + - `CustomAll` - Builds a custom server click action from all inputs and requests the server to run it. + - `ParsedTemplate` - A template that encodes some string similar to how function macros work. + - `StaticAction` - An action that fires a `ClickEvent` on activation. +- `net.minecraft.server.dialog.body` + - `DialogBody` - A body element describing the content between the title and actions/inputs. + - `DialogBodyTypes` - A registry of map codecs to encode some body. + - `ItemBody` - An item with an optional description. + - `PlainMessage` - A multiline label. +- `net.minecraft.server.dialog.input` + - `BooleanInput` - A plain checkbox with a label. + - `InputControl` - A control mechanism to accept user input. + - `InputControlTypes` - A registry of map codecs to encode some input control. + - `NumberRangeInput` - A slider for picking a numeric value from some range. + - `SingleOptionInput` - A button that cycles between a set of options. + - `TextInput` - Simple text input. +- `net.minecraft.world.entity.player.Player#openDialog` - Opens the specified dialog screen. + +### Waypoints + +Waypoints are simply a method to track the position of some object in the game. The underlying system is handled by the `WaypointManager`, responsible for holding the waypoints it is tracking while also allowing updates and removals as necessary. The server handles waypoints through the `ServerWaypointManager` (obtained via `ServerLevel#getWaypointManager`), which holds an active connect to the transmitter to receive live updates. The client receives these waypoints via the `ClientWaypointManager` (obtained via `ClientPacketListener#getWaypointManager`), which simply holds some identifier along with an exact position, a chunk if the position is not within the view distance, or an angle if the distance is further than the stored `Waypoint$Fade#farDist`, which is over 332 blocks away by default. + +Entities track waypoints by default. + +#### Styles and Icons + +Every waypoint is represents by an icon of some kind, which is defined by its `WaypointStyle` and the color of the icon. A `WaypointStyle` is similar to a client item or a equipment model, where it has some key pointed to by a `WaypointStyleAsset` that's located in `assets//waypoint_style/.json`. This contains a list of sprites located within `assets//textures/gui/sprites/hud/locator_bar_dot/.png` which is chosen based upon the distance from the tracker. The sprites change between the range specified by the near and far distance. + +```json5 +// For some style examplemod:example_style +// It will be found in `assets/examplemod/waypoint_style/example_style.json` +{ + // Represents that any value closer will use the first sprite when rendering the bar + // Defaults to 128 when not specified + "near_distance": 100, + // Represents that any value further will use the last sprite when rendering the bar + // Defaults to 332 when not specified + // Must be greater than near distance + "far_distance": 400, + // A non-empty list of textures relative to `assets//textures/gui/sprites/hud/locator_bar_dot/.png` + // This is what's used to lerp between the two distances + "sprites": [ + // Points to `assets/examplemod/textures/gui/sprites/hud/locator_bar_dot/example_style_0.png` + "examplemod:example_style_0", + "examplemod:example_style_1", + "examplemod:example_style_2" + ] +} +``` + +The icon can then be constructed using its constructor and referenced via `WaypointTransmitter#waypointIcon` or `TrackedWaypoint#icon` on the server or client, respectively. + +```java +// We will assume that this constructor is made public for a more dynamic usage +// Currently, it can only be set on a `LivingEntity` through its `CompoundTag` via `locator_bar_icon` +public static Waypoint.Icon EXAMPLE_ICON = new Waypoint.Icon( + // The registry key of the waypoint style + // Points to `assets/examplemod/waypoint_style/example_style.json` + ResourceKey.create(WaypointStyleAssets.ROOT_ID, ResourceLocation.fromNamespaceAndPath("examplemod", "example_style")), + // The color of the waypoint + // When not present, uses the hashcode of the waypoint identifier + Optional.of(0xFFFFFF) +); +``` + +#### Connections + +Waypoints, when tracked, are managed through their connections via `WaypointTransmitter$Connection`. A connection is responsible for syncing information to the client, whether connecting, disconnecting, or updating. + +```java +public class ExampleBlockConnection implements WaypointTransmitter.Connection { + + private final BlockState state; + private final BlockPos pos; + private final Waypoint.Icon icon; + private final ServerPlayer receiver; + + public ExampleBlockConnection(BlockState state, BlockPos pos, Waypoint.Icon icon, ServerPlayer receiver) { + this.state = state; + this.pos = pos; + this.icon = icon; + this.recevier = receiver; + } + + public static boolean doesSourceIgnoreReceiver(BlockPos pos, ServerPlayer player) { + double receiveRange = player.getAttributeValue(Attributes.WAYPOINT_RECEIVE_RANGE); + return pos.distSqr(player.blockPosition()) >= receiveRange * receiveRange; + } + + @Override + public boolean isBroken() { + // When true, it will attempt to remake the connection to this transmitter + // This is only called when updating the position + return ExampleBlockConnection.doesSourceIgnoreReceiver(this.pos, this.receiver); + } + + @Override + public void connect() { + // This sends the tracking packet to the client + this.receiver.connection.send(ClientboundTrackedWaypointPacket.addWaypointPosition(this.state.toString() + ": " + this.pos.toString(), this.icon, this.pos)); + } + + @Override + public void disconnect() { + // This sends the removal packet to the client + this.receiver.connection.send(ClientboundTrackedWaypointPacket.removeWaypoint(this.state.toString() + ": " + this.pos.toString())); + } + + @Override + public void update() { + // This updates the tracked value on the client assuming that the connect has not broken + // In our case, we can assume this never changes as the position of a block should remain consistent + } +} +``` + +#### Transmitters + +A `WaypointTransmitter` is responsible for constructing the connection between it and the server. For your object to transmit a location, it must implement `WaypointTransmitter` and its three methods. `waypointIcon` simply returns the icon to display. `isTransmittingWaypoint` will determine whether the waypoint can be transmitted from this object. `makeWaypointConnectionWith` actually handles constructing the connection used to track the position or angle of the connection. + +```java +public class ExampleWaypointBlock extends BlockEntity implements WaypointTransmitter { + + // ... + + @Override + public boolean isTransmittingWaypoint() { + // This should return false if no connection should be made + return true; + } + + @Override + public Optional makeWaypointConnectionWith(ServerPlayer player) { + // Make a connection if nothing is ignored + return ExampleBlockConnection.doesSourceIgnoreReceiver(this.getBlockPos(), player) + ? Optional.empty() + : Optional.of(new ExampleBlockConnection(this.getBlockState(), this.getBlockPos(), this.waypointIcon(), player)); + } + + @Override + public Waypoint.Icon waypointIcon() { + return EXAMPLE_ICON; + } +} +``` + +Then, all you need to do is track, update, or untrack the transmitter as necessary. This can be done using the methods provided by `ServerWaypointManager`: + +```java +// We will assume we have access to: +// - ServerLevel serverLevel +// - ExampleWaypointBlock be + +// Tracking the waypoint, such as on some initialization +serverLevel.getWaypointManager().trackWaypoint(be); + +// Update the waypoint if the position changes +serverLevel.getWaypointManager().updateWaypoint(be); + +// Remove the waypoint once it no longer exists +serverLevel.getWaypointManager().untrackWaypoint(be); +``` + +- `net.minecraft.client` + - `Camera` now implements `TrackedWaypoint$Camera` + - `Minecraft#getWaypointStyles` - Returns a manager of keys to the style of a waypoint. +- `net.minecraft.client.data.models.WaypointStyleProvider` - A data provider that generates waypoint styles. +- `net.minecraft.client.multiplayer.ClientPacketListener#getWaypointManager` - Gets the client manager used for tracking waypoints. +- `net.minecraft.client.renderer.GameRenderer` now implements `TrackedWaypoint$Projector` +- `net.minecraft.client.resources` + - `WaypointStyle` - Defines the style used to render a waypoint. + - `WaypointStyleManager` - The manager that maps some key to the style of a waypoint. +- `net.minecraft.client.waypoints.ClientWaypointManager` - A client-side manager for tracked waypoints. +- `net.minecraft.commands.arguments.WaypointArgument` - A static method holder that gets some waypoint transmitter from an entity. +- `net.minecraft.network.protocol.game` + - `ClientboundTrackedWaypointPacket` - A packet that sends some operation for a waypoint to the client. + - `ClientGamePacketListener#handleWaypoint` - Handles the waypoint packet on the client. +- `net.minecraft.server.ServerScoreboard$Method` enum is removed +- `net.minecraft.server.level.ServerLevel#getWaypointManager` - Gets the server manager used for tracking waypoints. +- `net.minecraft.server.level.ServerPlayer#isReceivingWaypoints` - Whether the player is receiving waypoints from other locations or entities. +- `net.minecraft.server.waypoints.ServerWaypointManager` - A server-side manager for tracked waypoints (e.g., players and transmitters). +- `net.minecraft.world.entity` + - `Entity#getRequiresPrecisePosition`, `setRequiresPrecisePosition` - Handles when a more precise position is needed for tracking. + - `LivingEntity` now implements `WaypointTransmitter` +- `net.minecraft.world.waypoints` + - `TrackedWaypoint` - A waypoint that is identified by some UUID or string, displayed via a `Waypoint$Icon`, and specified via `$Type`. + - `TrackedWaypointManager` - A waypoint manager for `TrackedWaypoint`s. + - `Waypoint` - An interface that represents some positional location. This holds no information, and is typically used in the context of `TrackedWaypoint`. + - `WaypointManager` - An interface that tracks and updates waypoints. + - `WaypointStyleAsset` - A class that indicates a style asset. + - `WaypointStyleAssets` - A class that defines all vanilla style assets. + - `WaypointTransmitter` - An object that transmits some position that can be connected to and tracked. + +### Blaze3d Changes + +Just like the previous update Blaze3d has new redesigns that change how rendering is handled. + +#### Buffer Slices + +The most important change within the rendering system is the use of `GpuBufferSlice`s. As the name implies, it simply takes some slice of a `GpuBuffer`, using an `offset` to indicate the starting index, and the `length` to indicate its size. When dealing with anything rendering related, even when passing to a shader, you will almost always be dealing with a `GpuBufferSlice`. A way to think about it is that the buffer is just some arbitrary list of object where a slice represents a specific object. + +To create a slice, simply call `GpuBuffer#slice`, optionally providing the starting index and length. In most instances, you will not be calling this method directly, instead dealing with other methods that call it for you. Note that as you are generally writing data to these slices, they should be constructed before a try-with-resources `RenderPass` is created. + +#### Uniform Rework + +The uniform system has been completely overhauled such that, unless you are familiar with specific features, it might seem completely foreign. In a nutshell, uniforms are now stored as either interface objects, a texel buffer, or a sampler. These are populated either by `GpuBuffer`s or `GpuBufferSlice`s. + +##### Uniform Types + +A uniform is currently represented as one of two `UniformType`s: either as an `UNIFORM_BUFFER`/interface block, or a `TEXEL_BUFFER`. When setting up a pipeline and calling `withUniform`, you must specify your uniform with one of the above types. If you choose to use a texel buffer, you must also specify the format of the texture data. Samplers have not changed. + +```java +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder(...) + // Uses a uniform interface block called 'ExampleUniform' + .withUniform("ExampleUniform", UniformType.UNIFORM_BUFFER) + // Uses a buffer called 'ExampleTexel' that stores texture data as a 8-bit R value + .withUniform("ExampleTexel", UniformType.TEXEL_BUFFER, TextureFormat.RED8I) + // Perform other setups + .build(); +``` + +##### Interface Blocks + +A `UNIFORM_BUFFER` is stored as a `std140` interface block. In GLSL, this is represented like so: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +// ExampleUniform is the name of the block +layout(std140) uniform ExampleUniform { + // The data within the block + // Post Effects can only use int, float, vec2, vec3, ivec3, vec4, or mat4 + vec4 Param1; + float Param2; +}; +``` + +The values can be used freely inside the main block like so: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +out vec4 fragColor; + +void main() { + fragColor = Param1; +} +``` + +The uniform block can either be inside the same file as the main function or, if it will be reused, as a `moj_import`, where the uniform file is within `assets//shaders/include/`. Note that any shaders used before resource packs are loaded cannot use `moj_import`. + +Post Effects define their interface blocks in the `uniform` input: + +```json5 +// In assets/examplemod/post_effect/example_post_effect.json +// Inside a 'passes' object +{ + "vertex_shader": "...", + // ... + "uniforms": { + // The name of the interface block + "ExampleUniform": [ + // A parameter within the uniform block + // See `UniformValue` for codec formats + { + // The name of the parameter + "name": "Param1", + // The parameter type, one of: + // - int + // - ivec3 + // - float + // - vec2 + // - vec3 + // - vec4 + // - matrix4x4 (mat4) + "type": "vec4", + // The value stored in the uniform + // Dynamic values from the codebase are no longer supported + "value": [ 0.0, 0.0, 0.0, 0.0 ] + }, + { + "name": "Param2", + "type": "float", + "value": 0 + } + ] + } +} +``` + +##### Texel Buffers + +Texel buffers are typically represented as a `isamplerBuffer` to be queried from, typically using `texelFetch`: + +```glsl +// In assets/examplemod/shaders/core/example_shader.json + +uniform isamplerBuffer ExampleTexel; + +void main() { + // Read the documentation to understand how texel fetch works + texelFetch(ExampleTexel, gl_InstanceID); +} +``` + +##### Writing Custom Uniforms + +Writing custom uniforms can only happen when you are the one responsible for creating the `RenderPass`. Like before, you create and cache the object before opening the `RenderPass`, then you set the uniform by calling `RenderPass#withUniform`. The only difference is that, instead of providing arbitrary objects, you must now either provide a `GpuBuffer` or `GpuBufferSlice` with the uniform data written to it. For a texel buffer, this is usually some encoded data in the desired texture format (such as a mesh). For an interface block, the easiest method is to use the `Std140Builder` to populate the buffer with the correct values. + +There are many different methods of writing to a `GpuBuffer` or `GpuBufferSlice`, such as using the newly created `MappableRingBuffer`. It is up to you to figure out what method works best in your scenario. The following is simply one solution out of many. + +```java +// Buffer for 'ExampleUniform' +// Takes in the name of the buffer, its usage, and the size +private final MappableRingBuffer ubo = new MappableRingBuffer( + // Buffer name + () -> "Example UBO", + // Buffer Usage + // We set 128 as its used for a uniform and 2 since we are writing to it + // Other bits can be found as constants in `GpuBuffer` + GpuBuffer.USAGE_UNIFORM | GpuBuffer.USAGE_MAP_WRITE, + // The size of the buffer + // Easiest method is to use Std140SizeCalculator to properly calculate this + new Std140SizeCalculator() + // Param1 + .putVec4() + // Param2 + .putFloat() + .get() +); + +// Buffer for 'ExampleTexel' +private final MappableRingBuffer utb = new MappableRingBuffer( + // Buffer name + () -> "Example UTB", + // We set 256 as its used for a texel buffer and 2 since we are writing to it + GpuBuffer.USAGE_UNIFORM_TEXEL_BUFFER | GpuBuffer.USAGE_MAP_WRITE, + // The size of the buffer + // It will likely be larger than this for you + 3 +); + +// In some render method + +// Populate the buffers as required + +// As we are using a ring buffer, this simply uses the next available buffer in the list +this.ubo.rotate(); +// Write the data to the buffer +try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.ubo.currentBuffer(), false, true)) { + Std140Builder.intoBuffer(view.data()) + .putVec4(0f, 0f, 0f, 0f) + .putFloat(0f); +} + +// Similar thing here +this.utb.rotate(); +try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.utb.currentBuffer(), false, true)) { + view.data() + .put((byte) 0) + .put((byte) 0) + .put((byte) 0); +} + +// Create the render pass and pass in the buffers as part of the uniform +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(...)) { + // .. + pass.setUniform("ExampleUniform", this.ubo.currentBuffer()); + pass.setUniform("ExampleTexel", this.utb.currentBuffer()); + // ... +} +``` + +#### Fog Environments + +The fog system has been reworked into an environment/render state-like handler. Each environment mostly handles setting up the fog data and color. Some additional processing is provided for the individual `FogType`s and special mob effects. + +All environments are handled through the `FogEnvironment`. A environment is setup via the `setupFog` method, which is responsible for mutating the passed in `FogData` to the values associated with that environment. If the fog colors its surroundings, then `providesColor` should return true, with the base color tint applied in `getBaseColor`. Likewise, if the fog darkens its surroundings, then `modifiesDarkness` should return true, with the modified darkness returned via `getModifiedDarkness`. To determine whether an environment should apply, `isApplicable` is checked. If not applicable, then `onNotApplicable` is called. + +All environments are registered to `FogRenderer#FOG_ENVIRONMENTS`; however, what environment to use is based on `isApplicable` and the list order. For the color and darkness, the fog environment chosen is the last one in the list where one of the `provides*` methods return true. For the actual fog setup, the fog environment chosen is the first one in the list. + +#### Render Pass Scissoring now only OpenGL + +The scissoring state has been removed from the generic pipeline code, now only accessible through the OpenGL implementation. Generic region handling has been delegated to `CommandEncoder#clearColorAndDepthTextures`. Note that this does not affect the existing `ScreenRectangle` system that handles the blit facing scissoring. + +- `com.mojang.blaze3d.buffers` + - `BufferType` enum is removed + - `BufferUsage` enum is removed + - `GpuBuffer` now takes two ints represent the size and usage, the type is no longer specified + - `type` is removed + - `usage` now returns an int + - `slice` - Returns a record representing a slice of some buffer. The actual buffer is not modified in any way. + - `$ReadView` -> `$MappedView` + - `GpuBufferSlice` - A record that represents a slice of some buffer by holding a reference to the entire buffer, an offset index of the starting point, and the length of the slice. + - `GpuFence` is now an interface, with its OpenGL implementation moved to `blaze3d.opengl.GlFence` + - `Std140Builder` - A buffer inserter for an interface block laid out in the `std140` format. This is used for the uniform blocks within shaders. + - `Std140SizeCalculator` - An object used for keeping track of the size of some interface block. +- `com.mojang.blaze3d.opengl` + - `AbstractUniform` is removed, replaced by the `Std140*` classes + - `BufferStorage` - A class that create buffers given its types. Its implementations define its general usage. + - `DirectStateAccess` + - `createBuffer` - Creates a buffer. + - `bufferData` - Initializes a buffer's data store. + - `bufferSubData` - Updates a subset of a buffer's data store. + - `bufferStorage` - Creates the data store of a buffer. + - `mapBufferRange` - Maps a section of a buffer's data store. + - `unmapBuffer` - Relinguishes the mapping of a buffer and invalidates the pointer to its data store. + - `GlBuffer` now takes in a `DirectStateAccess`, two ints, and a `ByteBuffer` instead of a `GlDebugLabel` and its `Buffer*` enums + - `initialized` is removed + - `persistentBuffer` - Holds a reference to an immutable section of some buffer. + - `$ReadView` -> `$GlMappedView` + - `GlCommandEncoder` + - `executeDrawMultiple` now takes in a collection of strings that defines the list of required uniforms and a generic indicating the object of the draw call + - `executeDraw` now takes in two `int`, the number of instances of the specified range of indices to be rendered and the base vertex + - `GlConst#toGl` for `BufferType` and `BufferUsage` -> `bufferUsageToGlFlag`, `bufferUsageToGlEnum` + - `GlDebugLabel#pushDebugGroup`, `popDebugGroup` - Profiler commands for grouping similar calls. + - `GlDevice` + - `USE_GL_ARB_buffer_storage` - Sets the extension flag for `GL_ARB_buffer_storage`. + - `getBufferStorage` - Returns the storage responsible for creating buffers. + - `GlProgram` + - `Uniform` fields have been removed + - `safeGetUniform`, `setDefaultUniforms` are removed + - `bindSampler` is removed + - `getSamplerLocations`, `getSamplers`, `getUniforms` -> `getUniforms` which returns a map of names to their `Uniform` objects + - `GlRenderPass` + - `uniforms` now is a `HashMap` + - `dirtSamplers` is removed + - `samplers` map now holds a `GpuTextureView` value + - `pushedDebugGroups` - Returns the number of groups pushed onto the stack. No debug groups must be open for the render pass to be closed. + - `isScissorEnabled` - Returns whether the scissoring state is enabled which crops the area that is rendered to the screen. + - `getScissorX`, `getScissorY`, `getScissorWidth`, `getScissorHeight` - Returns the values representing the scissored rectangle. + - `GlTexture` now takes in an additional integer for the usage and depth/layers + - `flushModeChanges` now takes in an `int` which represents the texture target + - `addViews`, `removeViews` - Manages the views looking at a texture for some mip levels. + - `GlTextureView` - A view implementation of a texture for some mip levels. + - `Uniform` is now a sealed interface which is implemented as either a buffer object, texel buffer, or a sampler +- `com.mojang.blaze3d.pipeline` + - `BlendFunction#PANORAMA` is removed + - `CompiledRenderPipeline#containsUniform` is removed + - `RenderPipeline` + - `$Builder#withUniform` now has an overload that can take in a `TextureFormat` + - `$UniformDescription` now takes in a nullable `TextureFormat` + - `RenderTarget` + - `colorTextureView`, `depthTextureView`, `getColorTextureView`, `getDepthTextureView` - A view of the current color and depth textures. + - `blitAndBlendToTexture` now takes in a `GpuTextureView` instead of a `GpuTexture` +- `com.mojang.blaze3d.platform.Lightning` is now `AutoCloseable` + - `setup*` -> `setupFor`, an instance method that takes in an `$Entry` + - `updateLevel` - Updates the lighting buffer, taking in whether to use the nether diffused lighting. +- `com.mojang.blaze3d.shaders` + - `FogShape` -> `net.minecraft.client.renderer.fog.FogData`, not one-to-one + - `UniformType` now only holds two types: `UNIFORM_BUFFER`, or `TEXEL_BUFFER`, and no longer takes in a count +- `com.mojang.blaze3d.systems` + - `CommandEncoder` + - `clearColorAndDepthTextures` now has an overload that takes in four `int`s representing the region to clear the texture information within + - `writeToBuffer`, `mapBuffer(GpuBuffer, int, int)` now take in a `GpuBufferSlice` instead of a `GpuBuffer` + - `createFence` - Creates a new sync fence. + - `createRenderPass` now takes in a `Supplier`, used for determining the name of the pass to use as a debug group, and `GpuTextureView`s instead of `GpuTexture`s + - `writeToTexture` now takes in an additional `int` representing the depth or layer to write to + - `presentTexture` now takes in a `GpuTextureView` instead of a `GpuTexture` + - `GpuDevice` + - `createBuffer` no longer takes in a `BufferUsage`, with `BufferType` replaced by an `int` + - `getUniformOffsetAlignment` - Returns the uniform buffer offset alignment. + - `createTexture` now takes in additionals `int` for the usage and the number of depth/layers, see `GpuTexture` constants + - `createTextureView` - Creates a view of a texture for a certain range of mip levels. + - `RenderPass` + - `enableScissor` is removed + - `bindSampler` can now take in a nullable `GpuTextureView` + - `setUniform` can either take in a `GpuBuffer` or `GpuBufferSlice` instead of the raw inputs + - `drawIndexed` now takes the following `int`s: the base vertex, the start index, the number of elements, and the prim count + - `drawMultipleIndexed` now takes in a collection of strings that defines the list of required uniforms and a generic indicating the object of the draw call + - `pushDebugGroup`, `popDebugGroup` - Profiler commands for grouping similar calls. + - `$UniformUploader#upload` now takes in a `GpuBufferSlice` instead of an array of `float`s + - `$Draw` now has a generic that passed in to upload any uniforms to the buffer + - `RenderSystem` + - `SCISSOR_STATE` -> `scissorStateForRenderTypeDraws`, now private + - Accessible through `getScissorStateForRenderTypeDraws` + - `enableScissor`, `disableScissor` -> `enableScissorForRenderTypeDraws`, `disableScissorForRenderTypeDraws`, not one to one + - `PROJECTION_MATRIX_UBO_SIZE` - Returns the size of the projection matrix uniform + - `setShaderFog`, `getShaderFog` now deals with a `GpuBufferSlice` + - `setShaderGlintAlpha`, `getShaderGlintAlpha` is removed + - `setShaderLights`, `getShaderLights` now deals with a `GpuBufferSlice` + - `setShaderColor`, `getShaderColor` + - `setup*Lighting` methods are removed + - `setProjectionMatrix`, `getProjectionMatrix` (now `getProjectionMatrixBuffer`) now deals with a `GpuBufferSlice` + - `setShaderGameTime`, `getShaderGameTime` -> `setGlobalSettingsUniform`, `getGlobalSettingsUniform`; not one-to-one + - `getDynamicUniforms` - Returns a list of uniforms to write for the shader. + - `bindDefaultUniforms` - Binds the default uniforms to be used within a `RenderPass` + - `outputColorTextureOverride`, `outputDepthTextureOverride` are now `GpuTextureView`s + - `setupOverlayColor`, `setShaderTexture`, `getShaderTexture` now operate on `GpuTextureView`s instead of `GpuTexture`s +- `com.mojang.blaze3d.textures` + - `GpuTexture` now takes in an int representing the usage flags and number of depth/layers + - `usage` - The flags that define how the texture can be used. + - `depthOrLayers`, `getDepthOrLayers` - Defines how many layers or depths are available for a given texture. This is meant as a generic count for available texture encodings. Only cubemap support is currently available (meaning the layer count must be a multiple of 6). + - `GpuTextureView` - A view of some texture for a range of mip levels. + - `TextureFormat#RED8I` - An 8-bit signed integer handling the red color channel. +- `com.mojang.blaze3d.vertex` + - `ByteBufferBuilder` now takes in a long for the maximum capacity + - `exactlySized` - Returns a buffer that is its maximum capacity. This should be called over the public constructor. + - `DefaultVertexFormat#EMPTY` - A vertex format with no elements. +- `net.minecraft.client.renderer` + - `CachedOrthoProjectionMatrixBuffer` - An object that caches the orthographic projection matrix, rebuilding if the width or height of the screen changes. + - `CachedPerspectiveProjectionMatrixBuffer` - An object that caches the perspective projection matrix, rebuilding if the width, height, or field of view changes. + - `CloudRenderer` + - `FLAG_INSIDE_FACE`, `FLAG_USE_TOP_COLOR` are now private + - `RADIUS_BLOCKS` is removed + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `CubeMap` is now `AutoCloseable` + - `render` no longer takes in the float for the partial tick. + - `DynamicUniforms` - A class that writes the uniform interface blocks to the buffer for use in shaders. + - `DynamicUniformStorage` - A class that holds the uniforms within a slice of a mappable ring buffer. + - `FogParameters` record is removed, now stored in a general `GpuBufferSlice` + - `FogRenderer` now implements `AutoCloseable` -> `.fog.FogRenderer` + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `getBuffer` - Gets the buffer slice that holds the uniform for the current fog mode. + - `setupFog` no longer takes in the `FogMode`, returning nothing + - `$FogData#mode` is removed, replaced by `skyEnd`, `cloudEnd` + - `$FogMode` enums have been replaced with `NONE` and `WORLD`, not one-to-one + - `GameRenderer` + - `getGlobalSettingsUniform` - Returns the uniform for the game settings. + - `getLighting` - Gets the lighting renderer. + - `setLevel` - Sets the current level the renderer is rendering. + - `GlobalSettingsUniform` - An object fod handling the uniform holding the current game settings. + - `LevelRenderer` + - `endFrame` - Ends the current frame being rendered to by constructing a fence. + - `renderLevel` now takes in a `GpuBufferSlice`, the fog vector, and whether the current position is foggy instead of the `GameRenderer` + - `MappableRingBuffer` - An object that contains three buffers that are written to as required, then rotates to the next buffer to use on end. These are synced using fences. + - `PanoramaRenderer#render` now takes in a boolean for whether to change the spin up the spin rather than two floats. + - `PerspectiveProjectionMatrixBuffer` - An object that holds the projection matrix uniform. + - `PostChain` + - `load` now takes in the `CachedOrthoProjectionMatrixBuffer` + - `addToFrame` no longer takes in the `Consumer` + - `process` no longer takes in the `Consumer` + - `PostChainConfig` + - `$FixedSizedTarget` record is removed + - `$FullScreenTarget` record is removed + - `$InternalTarget` is now a record which can take in an optional width, height, whether the target is persistent, and the clear color to use + - `$Pass#uniforms` is now a `Map>` + - `$Uniform` record is removed + - `PostPass` is now `AutoCloseable`, taking in a `Map>` for the uniforms along with a list of `PostPass$Input`s + - `addToFrame` no longer takes in the `Consumer`, with the `Matrix4f` passed in as a `GpuBufferSlice` + - `$Input` + - `bindTo` is removed + - `texture` - Constructs a `GpuTexture` for the input given the map of resources. + - `samplerName` - Returns the name of the sampler. + - `SkyRenderer#renderSunMoonAndStars` no longer takes in the `FogParameters` + - `UniformValue` - An interface that represents a uniform stored within an interface block. +- `net.minecraft.client.renderer.chunk.SectionRendererDispatcher$RenderSection#setDynamicTransformIndex`, `getDynamicTransformIndex` - Handles the index used to query the correct dynamic transforms for a given section. +- `net.minecraft.client.renderer.fog.environment` + - `AirBasedFogEnvironment` - An environment whose color is derived from the air of the biome + - `AtmosphericFogEnvironment` - The default fog environment if no other special cases match. + - `BlindessFogEnvironment` - An environment that activates if the entity has the blindness effect. + - `DarknessFogEnvironment` - An environment that activates if the entity has the darkness effect. + - `DimensionOrBossFogEnvrionment` - An environment that activates based on if there are any bosses or the dimension special effects. + - `FogEnvironment` - An abstract class that determines how the fog should render at a given location for an entity. + - `LavaFogEnvironment` - An environment that activates if the entity is within lava. + - `MobEffectFogEnvironment` - An environment that activates based on if the entity has a given mob effect. + - `PowderedSnowFogEnvironment` - An environment that activates if the entity is within powdered snow. + - `WaterFogEnvironment` - An environment that activates if the entity is within water. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `setUseMipmaps` - Sets whether the texture should use mipmapping. + - `textureView`, `getTextureView` - Represents the current texture view. + - `CubeMapTexture` - A cubemap compatible texture, textures are expected to have suffixes `_0` to `_5`. + - `ReloadableTexture#doLoad` is now protected +- `net.minecraft.world.level.material.FogType` + - `DIMENSION_OR_BOSS` - Fog for dimension special effects or bosses. + - `ATMOSPHERIC` - Default fog type. + +### Tag Providers: Appender Rewrite + +The `TagAppender` has been rewritten to a degree, changing the basic implementations of `TagsProvider`s. + +By default, the `TagsProvider` no longer provides any useful methods for adding content to a `TagBuilder`. The most you can do is construct the builder using `TagsProvider#getOrCreateRawBuilder` and add elements or tags via their `ResourceLocation` using one of the available `add*` methods. + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends TagsProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries, CompletableFuture> parentProvider) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries, + // Optional: A parent provider to use the generate tags of + // Typically obtained from TagsProvider#contentsGetter + parentProvider + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagBuilder builder = this.getOrCreateRawBuilder(EXAMPLE_TAG); + builder + // Add single element + .addElement(ResourceLocation.fromNamespaceAndPath("minecraft", "apple")) + // Add tag to builder + .addTag(ItemTags.WOOL.location()); + } +} +``` + +But what if we want to reference tags by their `ResourceKey`? Or registry object? This is where the rewritten `TagAppender` comes in. `TagAppender` is an interface with two generics, `E` which represents the type of the entry to add, and `T` which represents the type of the objects within the tag. A `TagAppender` has five common methods: three that add entries (`add`, `addAll`, `addOptional`), and two that add tags (`addTag`, `addOptionalTag`). A `TagAppender` can be created via `forBuilder`, which accepts `ResourceKey`s for entries. + +`KeyTagProvider` provides this for you by adding a `tag` method, creating the appender from a `TagKey`. Generally, datapack registry objects have their tags generated using this provider: + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends KeyTagProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagAppender, Item> builder = this.tag(EXAMPLE_TAG); + builder + // Add single element + .add(ResourceKey.create(Registries.ITEM, ResourceLocation.fromNamespaceAndPath("minecraft", "apple"))) + // Add tag to builder + .addTag(ItemTags.WOOL); + } +} +``` + +`TagAppender`s can also be mapped to change their entry type using the `map` method. This takes in a function which maps the new entry type to the original entry type. `IntrinsicHolderTagsProvider` provides this for you via a `tag` method, creating the appender from a `TagKey` and mapping it using a key extractor. Generally, built-in registry objects have their tags generated using this provider: + +```java +// We will assume there is some TagKey EXAMPLE_TAG +public class ExampleTagsProvider extends IntrinsicHolderTagsProvider { + + public ExampleTagsProvider(PackOutput output, CompletableFuture registries) { + super( + // The output location of the pack + output, + // The registry key to generate tags for + Registries.ITEM, + // The registry of registries + registries, + // Maps the registry object to its resource key + item -> item.builtInRegistryHolder().key() + ); + } + + @Override + protected void addTags(HolderLookup.Provider registries) { + // Add tags here + TagAppender builder = this.tag(EXAMPLE_TAG); + builder + // Add single element + .add(Items.APPLE) + // Add tag to builder + .addTag(ItemTags.WOOL); + } +} +``` + +#### Copying Tags: Block and Item + +Copying tags no longer exists in the traditional sense, where it loops through the elements of an existing tag. Instead, the implementation has been narrowed down to a general `BlockItemTagsProvider`. This method provides a `TagAppender` by taking in both a block and an item tag, and then converting them appropriately within the `Vanilla*TagsProvider`. As such, it is less copying and more mapping blocks to their associated items. + +The one drawback is that tags that are used within other tags (calling `addTag`) must have the same name. For example, adding `BlockTags#LOGS` only works because there is a `minecraft:logs` for both block and item tags. Meanwhile, adding `BlockTags#CEILING_HANGING_SIGNS` would fail as the associated item tag is `minecraft:hanging_signs` instead of `minecraft:ceiling_hanging_signs`. + +```java +// We will assume there is some TagKey BLOCK_EXAMPLE_TAG +// We will assume there is some TagKey ITEM_EXAMPLE_TAG +public class ExampleBlockItemTagsProvider extends BlockItemTagsProvider { + + @Override + public void run() { + // Add block item tags here + // Will add entries to block or item tag depending on the provider + TagAppender builder = this.tag(BLOCK_EXAMPLE_TAG, ITEM_EXAMPLE_TAG); + builder + // Add single element + .add(Blocks.TERRACOTTA) + // Add tag to builder + // There exists both `minecraft:logs` in block and item tags + .addTag(BlockTags.LOGS); + } +} + +// For some IntrinsicHolderTagsProvider or IntrinsicHolderTagsProvider +@Override +protected void addTags(HolderLookup.Provider registries) { + // Add tags here + new ExampleBlockItemTagsProvider() { + // Or depending on the situation + protected TagAppender tag(TagKey blockTag, TagKey itemTag) { + // Return a TagAppender + // See VanillaItemTagsProvider$BlockToItemConverter for an item example + // See VanillaBlockTagsProvider for a block example + } + }.run(); +} +``` + +- `net.minecraft.data.tags` + - `BlockItemTagsProvider` - A provider that generates tags for block items, using the block and item tag equivalents as a starting point. + - `IntrinsicHolderTagsProvider` + - `tag` now returns the raw `TagAppender` + - `$IntrinsicTagAppender` class is removed + - `ItemTagsProvider` class is removed + - `KeyTagProvider` - A provider which appends elements via their `ResourceKey`. + - `TagsProvider` + - `tag` is removed + - `$TagAppender` -> `TagAppender`, not one-to-one + - `VanillaItemTagsProvider` now implements `IntrinsicHolderTagsProvider` + - `BlockToItemConverter` - A tag appender that adds a block to an item tag. + +### Generic Encoding and Decoding: Replacing Direct NBT Access + +Direct access to get data out of some NBT has been removed completely from higher level objects like entities and block entities. This means that, generally, you cannot directly touch the `CompoundTag` during the serialization process. Instead, indirect access is provided to nbt tags via `ValueInput` and `ValueOutput`. As their name implies, these read values from and write values to the data object, respectively. The methods available are similar to those on `CompoundTag`s. For `ValueInput`, there's the `get*` methods by providing the associated key, and `get*Or` for a get-or-default if not present. There is also `read` for handling `Codec`s. For `ValueOutput`, there's the `put*` methods by providing the associated key and value, and also a `store` for `Codec`s. List variants exists separately on the input/output access. + +As such, most methods that take in a `CompoundTag` now instead take in a `ValueInput` for `read`/`load` or `ValueOutput` for `write`/`save`. + +```java +// For some Entity with an ItemStack stack +@Override +protected void readAdditionalSaveData(ValueInput in) { + super.readAdditionalSaveData(in); + // By default, the input uses a registry ops + this.stack = in.read("example_stack", ItemStack.CODEC).orElse(ItemStack.EMPTY); +} + +@Override +protected void addAdditionalSaveData(ValueOutput out) { + super.addAdditionalSaveData(out); + // By default, the output uses a registry ops + in.storeNullable("example_stack", ItemStack.CODEC, this.stack); +} + +// For some BlockEntity with an int value +@Override + protected void loadAdditional(ValueInput in) { + super.loadAdditional(in); + this.value = in.getIntOr("value", 0); + } + + @Override + protected void saveAdditional(ValueOutput out) { + super.saveAdditional(out); + out.putInt("value", this.value); + } +``` + +#### NBT Implementations + +To provide indirect access to `CompoundTag`s, there are implementations of `ValueInput` and `ValueOutput` called `TagValueInput` and `TagValueOutput` respectively. + +A `TagValueOutput` can be created using either `createWithContext` or `createWithoutContext`. 'With context' means that the output has access to the `HolderLookup$Provider` for registry objects while 'without context' does not. Currently, no location uses `createWithoutContext`. Internally, this creates a new `CompoundTag`. Then, this output is passed around to be populated before finally returning the NBT for writing via `buildResult`. + +A `TagValueInput`, on the other hand, can be created via `create`, taking in the `HolderLookup$Provider` and the `CompoundTag` to read from. If the data is stored as a list of objects rather than a single object, you can pass in a `List` and get back a `ValueInputList`. Note this does not handle indicies, only providing an iterable or stream associated implementation. + +#### Problem Reporter + +In addition to what's mentioned above, the `create*` methods also take in a `ProblemReporter`, used for collecting all problems encountered when attempting to serialize/deserialize the data. It is up to the implementation to determine whether this report causes a crash or gives a warning. A `ProblemReporter` contains two methods: `report`, which reports a `$Problem`; and `forChild`, which further groups `$Problem`s using a `$PathElement`. Both problems and path elements are simply interface objects that return a string indicating what the problem is or the grouping, respectively. + +There are two common `ProblemReporter`s that are used: `$Collector`, which is typically used with data providers, and `$ScopedCollector`, which is used with disk objects (e.g., entities, block entities, chunks, etc.). A `$Collector` typiccally uses either `forEach` to report each problem one by one, `getReport`/`getTreeReport` to return a stringified problems, or `isEmpty` to list if there are any problems. A `$ScopedCollector` does the same, except this is `AutoCloseable`, in case nothing is done with the output. In these scenarios, the reports are written to a logger. + +Each collector takes in an initial `$PathElement`. This typically comes from the object itself containing some method called `problemPath`, which implements the interface. The `HolderLookup$Provider` is provided in the same fashion. + +```java +// For some object with HolderLookup.Provider registries +// There is also a Logger LOGGER + +// Let's assume our root path element is implemented like so +public record ExamplePathElement(String name) implements ProblemReporter.PathElement { + + @Override + public String get() { + return "Example: " + this.name(); + } +} + +// For a data provider +ProblemReporter.Collector problems = new ProblemReporter.Collector( + // Can be empty for a non-specified root + new ExamplePathElement("data_provider") +); +// Pass around the provider + +// For a disk-based object +try (ProblemReporter.ScopedCollector problems = new ProblemReporter.ScopedCollector(new ExamplePathElement("EXAMPLE TEST"), LOGGER)) { + TagValueOutput out = TagValueOutput.createWithContext(problems, this.registries); + // Pass around the output to write data + + // For the input + // The last parameter can be whatever CompoundTag, using the output as an example + TagValueInput in = TagValueInput.create(problems, this.registries, out.buildResult()); + // Pass around the input to read data +} +``` +- `net.minecraft.nbt.StringTag#escapeWithoutQuotes` - Creates a string that escapes control characters, quotations, apostrophes, and backslashes. +- `net.minecraft.server.level.ServerPlayer` + - `loadAndSpawnParentVehicle` now takes in a `ValueInput` + - `loadAndSpawnEnderPearls` now takes in a `ValueInput` + - `loadGameTypes` now takes in a `ValueInput` +- `net.minecraft.server.players.PlayerList#load` takes in a `ProblemReporter`, returning an optional `ValueInput` +- `net.minecraft.util.ProblemReporter` + - `DISCARDING` - A reporter which discards all reporters. + - `forChild` now takes in a `$PathElement` + - `report` now takes in a `$Problem` + - `$Collector` now has a constructor that takes in the root `$PathElement` + - `isEmpty` - Returns whether there are no reports. + - `forEach` - Loops through all available problems. + - `getReport` now returns a regular `String` + - `getTreeReport` - Gets the report and all its children using DFS. + - `$ElementReferencePathElement` - A path element that references some `ResourceKey`. + - `$FieldPathElement` - A path element that references some string. + - `$IndexedFieldPathElement` - A path element that references some string at an index. + - `$IndexedPathElement` - A path element that references some index. + - `$PathElement` - An interface that defines the grouping or element. + - `$Problem` - An interface that defines a problem with an element. + - `$RootElementPathElement` - A path element that references some `ResourceKey` as the root. + - `$RootFieldPathElement` - A path element that references some string as the root. + - `$ScopedCollector` - A collector that logs warnings when problems arise. +- `net.minecraft.world` + - `ContainerHelper` + - `saveAllItems` now takes in a `ValueOutput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` while returning nothing + - `loadAllItems` now takes in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `LockCode#addToTag`, `fromTag` now takes in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `RandomziableContainer#tryLoadLootTable`, `trySaveLootTable` now takes in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` + - `SimpleContainer` + - `fromTag` -> `fromItemList`, not one-to-one + - `createTag` -> `storeAsItemList`, not one-to-one +- `net.minecraft.world.entity` + - `Entity` + - `saveAsPassenger` now takes in a `ValueOutput` instead of a `CompoundTag` + - `save` now takes in a `ValueOutput` instead of a `CompoundTag` + - `saveWithoutId` now takes in a `ValueOutput` instead of a `CompoundTag`, returning nothing + - `load` now takes in a `ValueInput` instead of a `CompoundTag` + - `readAdditionalSaveData` now takes in a `ValueInput` instead of a `CompoundTag` + - `addAdditionalSaveData` now takes in a `ValueOutput` instead of a `CompoundTag` + - `problemPath` - Returns the path element to report problems from. + - `EntityRenference` + - `store` now takes in a `ValueOutput` instead of a `CompoundTag` + - `read`, `readWithOldOwnerConversion` now take in a `ValueInput` instead of a `CompoundTag` + - `Entity` + - `UUID_TAG` -> `TAG_UUID` + - `create`, `by` now take in a `ValueInput` instead of a `CompoundTag` + - `loadEntityRecursive` now takes in a `ValueInput` instead of a `CompoundTag` + - `loadEntitiesRecursive` now takes in a `ValueInput$ValueInputList` instead of a list of nbt tags + - `loadStaticEntity` now takes in a `ValueInput` instead of a `CompoundTag` + - `EntityReference#store` - Writes the reference data to the `ValueOutput`. + - `Leashable#readLeashData`, `writeLeashData` now take in a `ValueInput`/`ValueOutput` instead of a `CompoundTag` + - `LivingEntity#ATTRIBUTES_FIELD` -> `TAG_ATTRIBUTES` + - `NeutralMob#addPersistentAngerSaveData`, `readPersistentAngerSaveData` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` +- `net.minecraft.world.entity.npc.InventoryCarrier#readInventoryFromTag`, `writeInventoryToTag` now take in a `ValueInput`/`ValueOutput` instead of a `CompoundTag` +- `net.minecraft.world.entity.player.Inventory` + - `save` now takes in a `ValueOutput$TypedOutputList`, returning nothing + - `load` now takes in a `ValueOutput$TypedInputList` +- `net.minecraft.world.entity.variant.VariantUtils` + - `writeVariant` now takes in a `ValueOutput` instead of a `CompoundTag` + - `readVariant` now takes in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `RegistryAccess` +- `net.minecraft.world.entity.vehicle.ContainerEntity#addChestVehicleSaveData`, `readChestVehicleSaveData` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` +- `net.minecraft.world.inventory.PlayerEnderChestContainer` + - `fromTag` -> `fromSlots`, not one-to-one + - `createTag` -> `storeAsSlots`, not one-to-one +- `net.minecraft.world.item` + - `BlockItem#setBlockEntityData` now takes in a `TagValueOutput` instead of a `CompoundTag` + - `ItemStack#parse`, `save` are removed +- `net.minecraft.world.level` + - `BaseCommandBlock#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider`, returning nothing + - `BaseSpawner#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag`, returning nothing +- `net.minecraft.world.level.block.SculkSpreader#save`, `load` now take in a `ValueOutput`/`ValueInput` instead of a `CompoundTag` +- `net.minecraft.world.level.block.entity.BlockEntity` + - `load*` methods now take in a `ValueInput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `save*` methods now take in a `ValueOutput` instead of a `CompoundTag`, and no longer takes in a `HolderLookup$Provider` + - `removeComponentsFromTag` now takes in a `ValueOutput` instead of a `CompoundTag` + - `parseCustomNameSafe` now takes in a `ValueInput` and key instead of a tag and `HolderLookup$Provider` + - `problemPath` - Returns the path element to report problems from. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner#load`, `store` - Handles writing the spawner data. +- `net.minecraft.world.level.chunk.ChunkAccess#problemPath` - Returns the path element to report problems from. +- `net.minecraft.world.level.storage` + - `PlayerDataStorage#load` now returns a `ValueInput` instead of a `CompoundTag`, taking in a `ProblemReporter` + - `TagValueInput` - A compound tag input. + - `TagValueOutput` - A compound tag output. + - `ValueInput` - An interface that defines how to read data from some object. + - `ValueInputContextHelper` - A class that contains the context used to read object data. + - `ValueOutput` - An interface that defines how to write data to some object. +- `net.minecraft.world.level.storage.loot.ValidationContext` + - `forChild`, `enterElement` now takes in a `ProblemReporter$PathElement` instead of a `String` + - `reportProblem` now takes in a `ProblemReporter$Problem` instead of a `String` + - `$MissingReferenceProblem` - A problem where the referenced object is missing. + - `$ParametersNotProvidedProblem` - A problem where the loot context params are missing. + - `$RecursiveReferenceProblem` - A problem where the referenced object is referencing itself. + - `$ReferenceNotAllowedProblem` - A problem where the referenced object is not allowed to be referenced. +- `net.minecraft.world.level.storage.loot.entries` + - `AlternativesEntry#UNREACHABLE_PROBLEM` - A problem where the altnerative entry can never be executed. + - `CompositeEntryBase#NO_CHILDREN_PROBLEM` - A problem where the composite has no entries. + - `NestedLootTable#INLINE_LOOT_TABLE_PATH_ELEMENT` - An element which indicates that a table is inlined. + +### Server Player Changes + +`MinecraftServer` is no longer publicly exposed on the `ServerPlayer`. Additionally, `serverLevel` has been removed, now replaced with overloading `level` to return the `ServerLevel`. + +- `net.minecraft.server.level.ServerPlayer` + - `server` field is now private + - `serverLevel` -> `level`, still returns `ServerLevel` + +### 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. + +#### Leashes + +The leash system has been updated to support up to four on enabled entities. Additionally, the physics have been updated to more properly handle real-world elasicity of some stretchable object. + +- `net.minecraft.client.renderer.entity.state.EntityRenderState` + - `leashState` now returns a list of `$LeashState`s + - `$LeashState#slack` - Whether the leash has any slack. +- `net.minecraft.world.entity` + - `Entity` + - `shearOffAllLeashConnections` - Handles when shears are used to removed a leash. + - `dropAllLeashConnections` - Handles when all leashes should be removed from an entity. + - `getQuadLeashHolderOffsets` - Gets the offsets when four leashes attached to an entity. + - `supportQuadLeashAsHolder` - Returns whether the entity can be leashed up to four times. + - `notifyLeashHolder`, `notifyLeasheeRemoved` - Handles when the leash is ticked on an entity and when its removed. + - `setLeashOffset` is removed + - `getLeashOffset` -> `Leashable#getLeashOffset` + - `Leashable` + - `MAXIMUM_ALLOWED_LEASHED_DIST` - The maximum distance a leash can be attached to an entity. + - `AXIS_SPECIFIC_ELASTICITY` - The resistance of the leash along each axis. + - `SPRING_DAMPENING` - The loss of energy when the leash is oscillating on stretch. + - `TORSIONAL_ELASTICITY` - The resistance of the leash under torque. + - `STIFFNESS` - The stiffness of the leash. + - `ENTITY_ATTACHMENT_POINT` - Specifies the attachment point of the leash on the entity. + - `LEASHER_ATTACHMENT_POINT` - Specifies the attachment point of the leash on the holder. + - `SHARED_QUAD_ATTACHMENT_POINTS` - Specifies the attachment points of the leashes on an entity. + - `canHaveALeashAttachedToIt` -> `canHaveALeashAttachedTo`, not one-to-one + - `leashDistanceTo` - Returns the distance of the leash traveled between the holder and leashee. + - `onElasticLeashPull` - Handles when the leash is being pulled upon. + - `leashSnapDistance` - Returns when the leash will attempt to remove itself from the entity. + - `leashElasticDistance` - Returns the max distance before the elasticity of the leash becomes a physics factor. + - `handleLeashAtDistance` is removed + - `angularFriction` - Returns the angular friction of the entity on a block or within a liquid. + - `whenLeashedTo` - Notifies the entity that the leash is attached. + - `elasticRangeLeashBehaviour`, `legacyElasticRangeLeashBehaviour` -> `checkElasticInteractions`, not one-to-one + - `supportQuadLeash` - Whether the entity can be leashed up to four times. + - `getQuadLeashOffsets` - Returns the offsets of each leash attached to the entity. + - `createQuadLeashOffsets` - Creates the offsets for each of the four possible leash positions. + - `leashableLeashedTo` - Gets all entities within a 32-block radius that are leashed to this holder. + - `$LeashData#angularMomentum` - Returns the angular momentum of the entity when leashed. + - `$Wrench` - A record which handles the force and torque applied to the leash. +- `net.minecraft.world.item.LeadItem#leashableInArea` -> `Leashable#leashableInArea` + +#### Removal of Mob Effects Atlas + +The mob effect atlas has been removed and merged with the gui altas. + +- `net.minecraft.client.Minecraft#getMobEffectTextures` is removed +- `net.minecraft.client.gui.Gui#getMobEffectSprite` - Gets the location of the mob effect sprite. +- `net.minecraft.client.resources.MobEffectTextureManage` class is removed +- `AtlasIds#MOB_EFFECTS` is removed + +#### Permission Sources + +The permission checks for commands have been abstracted into its own `PermissionSource` interface. This provides the previously provided `hasPermission` method, in addition to a new method `allowsSelectors`, which returns whether the source has the necessary permission to select other entities (defaults to level 2 perms). You can incoporate the permission check into your commands by calling `Commands#hasPermission` with the desired level in `ArgumentBuilder#requires`. + +- `net.minecraft.client.multiplayer` + - `ClientPacketListener` + - `getCommands` now returns a `ClientSuggestionProvider` generic + - `sendUnattendedCommand` now takes in a `Screen` instead of a `boolean` + - `ClientSuggestionListener` now implements `PermissionSource`, taking in a boolean of whether it allows restricted commands + - `allowRestrictedCommands` - Returns whether restricted commands can be suggested. +- `net.minecraft.commands` + - `Commands#hasPermission` - Returns a permission check for the given level. + - `CommandSourceStack` now implements `PermissionSource` + - `ExecutionCommandSource` now implements `PermissionSource` + - `PermissionSource` - Returns the source of the permission to run a command. + - `SharedSuggestionProvider` + - `suggestResgitryElements` now takes in a `HolderLookup` instead of a `Registry` + - `listSuggestions` - Lists the suggestion for some registry elements. + - `hasPermission` is removed +- `net.minecraft.commands.synchronization.SuggestionProviders` + - `AVAILABLE_SOUNDS`, `SUMMONABLE_ENTITIES` now take in a `SharedSuggestionProvider` for their generic + - `cast` - Casts the suggestion provider to the correct type. + - `safelySwap` is removed + - `$Wrapper` -> `$RegisteredSuggestion` +- `net.minecraft.world.entity.Entity#getCommandSenderWorld` is removed + +#### Animation Baking + +Animations are now baked into `KeyframeAnimation`. Each `KeyframeAnimation` is made up of entries that apply the keyframes to a given `ModelPart`. To create an animation, the definition should be baked via `AnimationDefinition#bake` in the model constructor, then calling `#apply` or `#applyWalk` as required during `EntityModel#setupAnim`. + +```java +// For some entity model +// Assume some AnimationDefinition EXAMPLE_DEFN +// Assume our ExampleEntityState has some AnimationState exampleAnimState +public class ExampleModel extends EntityModel { + + private final KeyframeAnimation exampleAnim; + + public ExampleModel(ModelPart root) { + // We pass in whatever 'root' that can apply all animations + this.exampleAnim = EXAMPLE_DEFN.bake(root); + } + + @Override + public void setupAnim(ExampleEntityState state) { + super.setupAnim(state); + this.exampleAnim.apply(state.exampleAnimState, state.ageInTicks); + } +} +``` + +- `net.minecraft.client.animation` + - `AnimationDefinition#bake` - Bakes a defined animation to be used on a `Model`. + - `KeyframeAnimation` - A baked animation used to move `ModelPart`s on a given `Model`. + - `KeyframeAnimations#animate` -> `KeyframeAnimation$Entry#apply` +- `net.minecraft.client.model.Model` + - `getAnyDescendantWithName` is removed + - `animate` -> `KeyframeAnimation#apply` + - `animateWalk` - `KeyframeAnimation#applyWalk` + - `applyStatic` -> `KeyframeAnimation#applyStatic` +- `net.minecraft.client.model.geom.ModelPart` + - `getAllParts` now returns a `List` + - `createPartLookup` - Creates a lookup of part names to their `ModelPart`, any duplicate names are ignored. + +#### ChunkSectionLayers + +`RenderType`s used for defining how a block or fluid should render are now replaced with `ChunkSectionLayer`s. These functionally do the same thing as the `RenderType`; however, they only specify the `RenderPipeline` to use along with the buffer information. This also means that certain `RenderType`s are removed, like `TRANSLUCENT`, as they were only used for the block chunk rendering. + +This also means that adding to `ItemBlockRenderTypes#TYPE_BY_BLOCK` must specify the `ChunkSectionLayer` instead of the associated `RenderType`. + +- `net.minecraft.client.renderer` + - `ItemBlockRenderTypes` + - `getChunkRenderType` now returns a `ChunkSectionLayer` + - `getRenderLayer(FluidState)` now returns a `ChunkSectionLayer` + - `RenderType` + - `translucent` is removed + - `getRenderTarget`, `getRenderPipeline` is removed + - `chunkBufferLayers` is removed +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` - An enum that defines how an individual chunk layer (e.g., solid blocks, translucent blocks) is rendered. + - `ChunkSectionLayerGroup` - An enum that groups the layers for rendering. + - `ChunkSectionsToRender` - A record that contains the draws of a given chunk, allowing them to be rendered per layer group. + - `RenderChunk` -> `SectionCopy` + - `RenderChunkRegion` -> `RenderSectionRegion` + - `RenderRegionCache#createRegion` now takes in a `long` instead of a `SectionPos` + - `SectionCompiler$Results` + - `globalBlockEntities` -> - `net.minecraft.client.multiplayer.ClientLevel#getGloballyRenderedBlockEntities` + - `renderedLayers` now takes in a `ChunkSectionLayer` for the key + - `SectionMesh` - An interface that defines the mesh of a given section within a chunk + - `SectionRenderDispatcher` + - `getBatchToCount` -> `getCompileQueueSize` + - `setCamera`, `getCameraPosition` are removed + - `blockUntilClear` is removed + - `clearBatchQueue` -> `clearCompileQueue`, now public + - `$CompiledSection` -> `CompiledSectionMesh` + - `$RenderSection` + - `getBuffers` is removed + - `uploadSectionLayer(RenderType, MeshData)` -> `upload(Map, CompiledSectionMesh)`, not one-to-one + - `uploadSectionIndexBuffer` now takes in a `CompiledSectionMesh` and a `ChunkSectionLayer` instead of a `RenderType` + - `getDistToPlayerSqr` is removed + - `getCompiled` -> `getSectionMesh`, not one-to-one + - `rebuildSectionAsync` no longer takes in the `SectionRenderDispatcher` + - `setDynamicTransformIndex`, `getDynamicTransformIndex` are removed + - `$SectionBuffers` -> `SectionBuffers` + - `$TranslucencyPointOfView` -> `TranslucencyPointOfView` +- `net.minecraft.server.level.ChunkMap#getUpdatingChunkIfPresent` is now public +- `net.minecraft.world.level.TicketStorage` + - `purgeStaleTickets` now takes in the `ChunkMap` + - `removeTicketIf` now takes in a `BiPredicate` instead of a `Predicate`, taking in the chunk position and the ticket +- `net.minecraft.world.level.chunk.ChunkAccess#isSectionEmpty` is removed + +#### Tag Changes + +- `minecraft:block` + - `plays_ambient_desert_block_sounds` is split into `triggers_ambient_desert_sand_block_sounds`, `triggers_ambient_desert_dry_vegetation_block_sounds` + - `happy_ghast_avoids` + - `triggers_ambient_dried_ghast_block_sounds` +- `minecraft:dialog` + - `pause_screen_additions` + - `quick_actions` +- `minecraft:entity_type` + - `can_equip_harness` + - `followable_friendly_mobs` +- `minecraft:item` + - `harnesses` + - `happy_ghast_food` + - `happy_ghast_tempt_items` + +#### List of Additions + +- `com.mojang.blaze3d.pipeline` + - `BlendFunction#TRANSLUCENT_PREMULTIPLIED_ALPHA` - A blend function that assumes the target has a premultiplied alpha from the composite step. + - `RenderPipeline` + - `getSortKey` - Returns a value representing how the element should be sorted for rendering. Used for layer sorting. + - `updateSortKeySeed` - Updates the seed of the sort key, currently unused. +- `com.mojang.blaze3d.systems.RenderSystem` + - `outputColorTextureOverride` - Holds a texture containing the override color used instead of whatever is specified in the `RenderType` target. + - `outputDepthTextureOverride` - Holds a texture containing the override depth used instead of whatever is specified in the `RenderType` target. +- `com.mojang.blaze3d.textures.GpuTexture#setUseMipmaps` - Sets whether the texture should use mipmaps at different distances. +- `net.minecraft` + - `FileUtil#isPathPartPortable` - Returns whether the provided string does not match any of the windows reserved filenames. + - `WorldVersion$Simple` - A simple implementation of the current world version. +- `net.minecraft.advancements.critereon` + - `ItemUsedOnLocationTrigger$TriggerInstance#placedBlockWithProperties` - Creates a trigger where a block was placed with the specified property. + - `PlayerInteractTrigger$TriggerInstance#equipmentSheared` - Creates a criterion trigger that actus upon a player taking off an item on some entity. +- `net.minecraft.client` + - `GameNarrator#saySystemChatQueued` - Narrates a component if either system or chat message narration is enabled. + - `Minecraft#disconnectWithSavingScreen` - Disconnects the current client instance and shows the 'Saving Level' screen. + - `Options` + - `keyQuickActions` - A key mapping for showing the quick actions dialog. + - `cloudRange` - Returns the maximum distance clouds can render at. + - `musicFrequency` - Returns how frequency the background music handled by the `MusicManager` should play. + - `showNowPlayingToast` - Returns whether the 'Now Playing' toast is shown. + - `getFinalSoundSourceVolume` - Computes the volume for the given sound source, with non-master sources being scaled by the master source. + - `NarratorStatus#shouldNarrateSystemOrChat` - Returns whether the current narration status is anything but `OFF`. +- `net.minecraft.client.color.ColorLerper` - A utility class for lerping between color types based on some partial tick. +- `net.minecraft.client.data.models.BlockModelGenerators#createDriedGhastBlock` - Creates the dired ghast block model definition. +- `net.minecraft.client.data.models.model` + - `ModelTemplates#DRIED_GHAST` - A template that uses the `minecraft:block/dried_ghast` parent. + - `TextureMapping#driedGhast` - Creates the default texture mapping for the dried ghast model. + - `TextureSlot#TENTACLES` - Provides a texture key `tentacles`. +- `net.minecraft.client.model` + - `GhastModel#animateTentacles` - Animates the tentacles of a ghast. + - `HappyGhastHarnessModel` - A model representing the a ghast harness. + - `HappyGhastModel` - A model representing a 'tamed' ghast. + - `QuadrupedModel#createBodyMesh` now takes in two booleans for handling if the left and right hind leg textures are mirrored, respectively. +- `net.minecraft.client.multiplayer.ClientLevel` + - `DEFAULT_QUIT_MESSAGE` - The component holding the quit game text. + - `disconnect(Copmonent)` - Disconnects from the current level instance, showing the associated component. +- `net.minecraft.client.renderer.entity.HappyGhastRenderer` - The renderer for a 'tamed' ghast. +- `net.minecraft.client.renderer.entity.layers.RopesLayer` - The render layer for the ropes used on a 'tamed' ghast. +- `net.mienecraft.client.renderer.entity.state.HappyGhastRenderState` - The state of a 'tamed' ghast. +- `net.minecraft.client.resources.model.EquipmentclientInfo$LayerType#HAPPY_GHAST_BODY` - A layer representing the body of a happy ghast. +- `net.minecraft.client.resources.sounds.RidingHappyGhastSoundInstance` - A tickable sound instance that plays when riding a happy ghast. +- `net.minecraft.client.sounds` + - `MusicManager` + - `getCurrentMusicTranslationKey` - Returns the translation key of the currently playing music. + - `setMinutesBetweenSongs` - Sets the frequency between the background tracks. + - `showNowPlayingToastIfNeeded` - Shows the now playing toast if it needs to be seen. + - `$MusicFrequency` - The frequency of the background tracks being played. + - `SoundEngine$PlayResult` - The starting state of the sound trying to be played. +- `net.minecraft.commands.arguments` + - `HexColorArgument` - An integer argument that takes in a hexadecimal color. + - `ResourceOrIdArgument` + - `createGrammar` - Creates the grammar used to parse the argument. + - `$InlineResult` - A result that returns a direct holder. + - `$ReferenceResult` - A result that returns a reference holder. + - `$Result` - An interface that represents the result of some argument parsing. +- `net.minecraft.data.loot.LootTableProvider$MissingTableProblem` - A record that holds the key of some missing built-in table generator. +- `net.minecraft.data.recipes.RecipeProvider` + - `dryGhast` - The recipe for a dried ghast. + - `harness` - The recipe for a colored harness. +- `net.minecraft.gametest.framework.GameTestTicker#startTicking` - Starts ticking the runner for the game tests. +- `net.minecraft.nbt.NbtUtils` + - `addCurrentDataVersion`, `addDataVersion`, adds the data version to some nbt tag. +- `net.minecraft.network.FriendlyByteBuf#writeEither`, `readEither` - Handles an `Either` with the given stream encoders/decoders. +- `net.minecraft.network.codec.ByteBufCodecs` + - `RGB_COLOR` - A stream codec that writes the RGB using three bytes. + - `lenientJson` - Creates a stream codec that parses a json in lenient mode. + - `optionalTagCodec` - Creates a stream codec that parses an `Optional`-wrapped `Tag` using the supplied `NbtAccounter`. +- `net.minecraft.network.protocol.game` + - `ServerboundChangeGameModePacket` - Changes the current gamemode. + - `ServerboundCustomClickActionPacket` - Executes a custom action on the server, currently does nothing. +- `net.minecraft.server.MinecraftServer#handleCustomClickAction` - Handles a custom action sent from a click event. +- `net.minecraft.server.level.ServerLevel` + - `updateNeighboursOnBlockSet` - Updates the neighbors of the current position. If the blocks are not the same (not including their properties), then `BlockState#affectNeighborsAfterRemoval` is called. + - `waitForChunkAndEntities` - Adds a task that causes the server to wait until entities are loaded in the provided chunk range. +- `net.minecraft.sources.SoundSource#UI` - Sounds that come from some user interface. +- `net.minecraft.stats` + - `RecipeBookSettings#MAP_CODEC` + - `ServerRecipeBook#pack`, `loadUntrusted`, `$Packed` - Handles encoding and decoding the data of the recipe book. +- `net.minecraft.util` + - `ARGB` + - `setBrightness` - Returns the brightness of some color using a float between 0 and 1. + - `color` - Returns a ARGB color from a float red and integer alpha. + - `ExtraCodecs` + - `VECTOR2F` + - `VECTOR3I` + - `NBT` + - `LenientJsonParser` - A json parser using lenient rules. + - `Mth#smallestSquareSide` - Takes the ceiled square root of a number. + - `StrictJsonParser` - A json parser using strict rules. +- `net.minecraft.world` + - `Difficulty#STREAM_CODEC` + - `ItemStackWithSlot` - A record which holds a stack along with its slot index. +- `net.minecraft.world.entity` + - `Entity` + - `MAX_MOVEMENTS_HANDELED_PER_TICK` - The maximum number of movements that can be applied to an entity in a given tick. + - `isInClouds` - Returns whether the entity's Y position is between the cloud height and four units above. + - `teleportSpectators` - Teleports the spectators currently viewing from the player's perspective. + - `isFlyingVehicle` - Returns whether the vehicle can fly. + - `clearMovementThisTick` - Clears all movement the entity will make this tick. + - `EntityAttachments#getAverage` - Returns the average location of all attachment points. + - `ExperienceOrb` + - `awardWithDirection` - Adds an experience orb that moves via the specified vector. + - `unstuckIfPossible` - Attempts to find and move the orb to a free position. + - `Mob` + - `isWithinHome` - Returns whether the position is within the entity's restriction radius. + - `canShearEquipment` - Returns whether the current player can shear the equipment off of this mob. +- `net.minecraft.world.entity.ai.control.MoveControl#setWait` - Sets the operation to `WAIT`. +- `net.minecraft.world.entity.ai.goal.TemptGoal` + - `stopNavigation`, `navigateTowards` - Handles navigation towards the player. + - `$ForNonPathfinders` - A tempt goal that navigates towards a wanted position rather than immediately pathfinding. +- `net.minecraft.world.entity.ai.navigation.PathNavigation#canNavigateGround` - Returns whether the entity can pathfind while on the ground. +- `net.minecraft.world.entity.ai.sensing.AdultSensorAnyType` - An adult sensor that ignores whether the entity is the same type as the child. +- `net.minecraft.world.entity.animal` + - `HappyGhast` - An entity representing a happy ghast. + - `HappyGhastAi` - The brain of the happy ghast. +- `net.minecraft.world.entity.decoration.ArmorStand` + - `setArmorStandPose`, `getArmorStandPose`, `$ArmorStandPose` - Handles the pose of the armor stand. +- `net.minecraft.world.entity.monster.Ghast` + - `faceMovementDirection` - Rotates the entity to face its current movement direction. + - `$RandomFloatAroundGoal#getSuitableFlyToPosition` - Gets a position that the ghast should fly to. +- `net.minecraft.world.entity.player.Inventory#SLOT_BODY_ARMOR`, `SLOT_SADDLE` - The indicies for the corresponding slot. +- `net.minecraft.world.entity.projectile.ProjectileUtil#computeMargin` - Computes the bounding box margin to check for a given entity based on its tick count. +- `net.minecraft.world.item.component` + - `ItemAttributeModifiers` + - `forEach` - Applies the consumer to all attributes within the slot group. + - `$Builder#add` - Adds an attribute to apply for a given slot group with a display. + - `$Display` - Defines how an attribute modifier should be displayed within its tooltip. + - `$Default` - Shows the default attribute display. + - `$Hidden` - Does not show any attribute info. + - `$OverrideText` - Overrides the attribute text with the component provided. + - `Equippable$Builder` + - `setCanBeSheared` - Sets whether the equipment can be sheared off the entity. + - `setShearingSound` - Sets the sound to play when a piece of equipment is sheared off an entity. + - `ResolvableProfile#pollResolve` - Returns the profile of the stored id or name. +- `net.minecraft.world.item.equipment.Equippable#harness` - Represents a harness to equip. +- `net.minecraft.world.level` + - `CollisionGetter` + - `getPreMoveCollisions` - Returns an iterable of shapes containing the entity and block collisions at the given bounding box and futue movement direction. + - `getBlockCollisionsFromContext` - Gets the block shapes from the given collision context. + - `GameType#STREAM_CODEC` + - `Level` + - `precipitationAt` - Returns the precipitation at a given position. + - `onBlockEntityAdded` - Logic to run when a block entity is added to the level. +- `net.minecraft.world.level.block` + - `BaseRailBlock#rotate` - Rotates the current rail shape in the associated direction. + - `DriedGhastBlock` - A block that represents a dried ghast. +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner$FullConfig` - Represents the entire configuration of a trial. +- `net.minecraft.world.level.dimension.DimensionDefaults` + - `CLOUD_THICKNESS` - The block thickness of the clouds. + - `OVERWORLD_CLOUD_HEIGHT` - The cloud height level in the overworld. +- `net.minecraft.world.level.levelgen.flat.FlatLayerInfo#heightLimited` - Returns a new layer info whether the current height is limited to the specified value, as long as that value is not within the maximum range already. +- `net.minecraft.world.phys` + - `AABB` + - `intersects` - Returns whether the `BlockPos` intersects with this box. + - `distanceToSqr` - Returns the squared distance of the bounding boxes from their furthest point. + - `Vec3#rotateClockwise90` - Rotates the vector 90 degrees clockwise (flip x and z and invert new x value). +- `net.minecraft.world.phys.shapes.CollisionContext` + - `withPosition` - Returns the collision context of an entity with its bottom y position. + +#### List of Changes + +- `com.mojang.blaze3d.platform.Window#setGuiScale`, `getGuiScale` now deals with an `int` instead of a `double` +- `net.mineraft` + - `DetectedVersion` no longer implements `WorldVersion` + - `WorldVersion` methods now use record naming schema due to `WorldVersion$Simple` usage + - `getDataVersion` -> `dataVersion` + - `getId` -> `id` + - `getName` -> `name` + - `getProtocolVersion` -> `protocolVersion` + - `getPackVersion` -> `packVersion` + - `getBuildTime` -> `buildTime` + - `isStable` -> `stable` +- `net.minecraft.client` + - `GameNarrator` + - `sayChat` -> `sayChatQueued` + - `say` -> `saySystemQueued` + - `sayNow` -> `saySystemNow` + - `Minecraft` + - `grabPanoramixScreenshot` no longer takes in the window width and height to set + - `disconnect()` -> `disconnectWithProgressScreen` + - `Screenshot#grab`, `takeScreenshot` now takes in an `int` representing the downscale factor +- `net.minecraft.client.main.GameConfig$QuickPlayData` now takes in a `$QuickPlayVariant` + - `path` -> `logPath` + - `singleplayer` -> `variant` with `$QuickPlaySinglePlayerData` + - `multiplayer` -> `variant` with `$QuickPlayMultiplayerData` + - `realms` -> `variant` with `$QuickPlayRealmsData` + - null for `singleplayer`, `multiplayer`, `realms` is represented by `variant` with `$QuickPlayDisabled` +- `net.minecraft.client.data.models.ItemModelGenerators#generateWolfArmor` -> `generateTwoLayerDyedItem` +- `net.minecraft.client.gui.components.DebugScreenOverlay#render3dCrosshair` now takes in the current `Camera` +- `net.minecraft.client.gui.components.debugchart.ProfilerPieChart` + - `RADIUS` is now public + - `CHART_Z_OFFSET` -> `PIE_CHART_THICKNESS`, now public +- `net.minecraft.client.multiplayer` + - `ClientLevel$ClientLevelData#getClearColorScale` -> `voidDarknessOnsetRange`, not one-to-one + - `MultiPlayerGameMode#createPlayer` now takes in an `Input` instead of a `boolean` +- `net.minecraft.client.player.LocalPlayer` now takes in the last sent `Input` instead of a `boolean` for the shift key + - `getLastSentInput` - Gets the last sent input from the server. +- `net.minecraft.client.quickplay.QuickPlay#connect` now takes in a `GameConfig$QuickPlayVariant` instead of a `GameConfig$QuickPlayData` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects` no longer takes in the current cloud level and whether there is a ground + - `LightTexture#getTarget` -> `getTexture` +- `net.minecraft.client.renderer.blockentity.BlockEntityRenderer#shouldRenderOffscreen` no longer takes in the `BlockEntity` +- `net.minecraft.client.resources` + - `AbstractSoundInstance#sound` is now `Nullable` + - `SoundInstance#getSound` is now `Nullable` +- `net.minecraft.client.sounds` + - `SimpleSoundInstance#forMusic` now also takes in the `float` volume + - `SoundEngine` now takes in the `MusicManager` + - `pause` -> `pauseAllExcept`, not one-to-one + - `play` now returns a `$PlayResult` + - `SoundManager` now takes in the `MusicManager` + - `pause` -> `pauseAllExcept`, not one-to-one + - `play` now returns a `SoundEngine$PlayResult` +- `net.minecraft.commands.arguments` + - `ResourceOrIdArgument` now takes in an arbitrary codec rather than a `Holder`-wrapped value + - `ERROR_INVALID` -> `ERROR_NO_SUCH_ELEMENT`, now public, not one-to-one + - `VALUE_PARSER` -> `OPS`, now public, not one-toe + - `ResourceSelectorArgument#getSelectedResources` no longer takes in the `ResourceKey` +- `net.minecraft.commands.functions.StringTemplate` + - `fromString` no longer takes in the line number + - `isValidVariableName` is now public +- `net.minecraft.data.recipes.RecipeProvider#colorBlockWithDye` -> `colorItemWithDye`, now takes in the `RecipeCategory` +- `net.minecraft.gametest.framework.GameTestInfo#prepareTestStructure` is now nullable +- `net.minecraft.network` + - `Connection#send` now takes in a `ChannelFutureListener` instead of a `PacketSendListener` + - `FriendlyByteBuf#readJsonWithCodec` -> `readLenientJsonWithCodec` + - `PacketSendListener` is now a class whose methods return `ChannelFutureListener`s instead of `PacketSendListener`s + - `onSuccess`, `onFailure` are removed +- `net.minecraft.network.codec` + - `ByteBufCodecs#fromCodec` now has an overload that takes in some ops and a codec + - `StreamCodec#composite` now has an overload that takes in ten parameters +- `net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket` is now a record +- `net.minecraft.network.protocol.game` + - `ClientboundChangeDifficultyPacket` is now a record + - `ClientboundCommandsPacket` now takes in a `$NodeInspector` + - `getRoot` is now generic, taking in a `$NodeBuilder` + - `$NodeBuilder` - A builder for a given command. + - `$NodeInspector` - An agent that checks the information of a given command node. + - `ServerboundChangeDifficultyPacket` is now a record +- `net.minecraft.server.ReloadableServerRegistries$Holder#lookup` returns a `HolderLookup$Provider` +- `net.minecraft.server.network.ServerCommonPacketListenerImpl#send` now takes in a `ChannelFutureListener` instead of a `PacketSendListener` +- `net.minecraft.sounds.Music` is now a record +- `net.minecraft.stats.RecipeBookSettings` + - `getSettings` is now public + - `$TypeSettings` is now public +- `net.minecraft.world.entity` + - `AreaEffectCloud#setParticle` -> `setCustomParticle` + - `Entity` + - `checkSlowFallDistance` -> `checkFallDistanceAccumulation` + - `collidedWithFluid`, `collidedWithShapeMovingFrom` are now public + - `canBeCollidedWith` now takes the entity its colliding with + - `spawnAtLocation` now has an overload that takes in a `Vec3` for the offset position + - `removeLatestMovementRecordingBatch` -> `removeLatestMovementRecording` + - `EntityReference` is now final + - `ExperienceOrb` now has an overload that takes in two vectors for the position and movement + - `FlyingMob` is replaced by calling `LivingEntity#travelFlying` + - `LivingEntity#canBreatheUnderwater` is no longer `final` + - `Mob` + - `restrictTo` -> `setHomeTo` + - `getRestrictCenter` -> `getHomePosition` + - `getRestrictRadius` -> `getHomeRadius` + - `clearRestriction` -> `clearHome` + - `hasRestriction` -> `hasHome` +- `net.minecraft.world.entity.ai.attributes` + - `AttributeInstance` + - `save` -> `pack`, `$Packed`; not one-to-one + - `load` -> `apply`, not one-to-one + - `AttributeMap` + - `save` -> `pack`; not one-to-one + - `load` -> `apply`, not one-to-one +- `net.minecraft.world.entity.ai.behavior` + - `AnimalPanic` now has overloads that take in a radius or a position getter + - `BabyFollowAdult#create` now returns a `OneShot` and can take in a `boolean` of whether to target the eye position + - `EntityTracker` can now take in a `boolean` of whether to target the eye position + - `FollowTemptation` now has an overload that checks whether the entity needs to track the entity's eye height. +- `net.minecraft.world.entity.ai.goal.TemptGoal` now has an overload that takes in the stop distance + - `mob` is now a `Mob` + - `speedModifier` is now `protected` +- `net.minecraft.world.entity.ai.memory.MemoryModuleType#NEAREST_VISIBLE_ADULT` now holds a `LivingEntity` +- `net.minecraft.world.entity.ai.navigation` + - `FlyingPathNavigation`, `GroundPathNavigation#setCanOpenDoors` -> `PathNavigation#setCanOpenDoors` +- `net.minecraft.world.entity.ai.sensing.AdultSensor` now looks for a `LivingEntity` + - `setNearestVisibleAdult` is now `protected` +- `net.minecraft.world.entity.animal.*Variants#selectVariantToSpawn` -> `entity.variant.VariantUtils#selectVariantToSpawn`, not one-to-one +- `net.minecraft.world.entity.animal.Fox#isJumping` -> `LivingEntity#isJumping` +- `net.minecraft.world.entity.animal.horse.AbstractHorse` + - `isJumping` -> `LivingEntity#isJumping` + - `setStanding` now takes in an `int` instead of a `boolean` for the stand counter + - the `false` logic is moved to `clearStanding` +- `net.minecraft.world.entity.monster` + - `Ghast` now implements `Mob` + - `$GhastLookGoal` is now public, taking in a `Mob` + - `$GhastMoveControl` is now public, taking in whether it should be careful when moving and a supplied boolean of whether the ghast should stop moving + - `$RandomFloatAroundGoal` is now `public`, taking in a `Mob` and a block distance + - `Phantom` now implements `Mob` +- `net.minecraft.world.entity.player` + - `Abilities` + - `addSaveData` -> `pack`, `$Packed`; not one-to-one + - `loadSaveData` -> `apply`, not one-to-one + - `Player` no longer takes in the `BlockPos` and y rotation +- `net.minecraft.world.entity.projectile` + - `AbstractThrownPotion#onHitAsPostion` now takes in a `HitResult` instead of a nullable `Entity` + - `EyeOfEnder#signalTo` now takes in a `Vec3` instead of a `BlockPos` + - `Projectile` + - `ownerUUID`. `cachedOwner` -> `owner`, now protected; not one-to-one + - `setOwner` now has an overload to take in an `EntityReference` + - `ProjectileUtil` + - `DEFAULT_ENTITY_HIT_RESULT_MARGIN` is now public + - `getEntityHitResult` now takes in a `Projectile` instead of an `Entity` +- `net.minecraft.world.item.ItemStack` + - `forEachModifier` now takes in a `TriConsumer` that provides the modifier display + - `hurtAndBreak` now has an overload which gets the `EquipmentSlot` from the `InteractionHand` +- `net.minecraft.world.item.equipment.Equippable` now takes in whether the equipment can be sheared off an entity and the sound to play when doing so +- `net.minecraft.world.level.BlockGetter` + - `forEachBlockIntersectedBetween` now returns a boolean indicating that each block visited in the intersected area can be successfully visited + - `$BlockStepVisitor#visit` now returns whether the location can be successfully moved to +- `net.minecraft.world.level.block.AbstractCauldronBlock#SHAPE` is now protected +- `net.minecraft.world.level.block.entity` + - `BlockEntity#getNameForReporting` is now public + - `SignBlockEntity#executeClickCommandsIfPresent` now takes in a `ServerLevel` instead of the `Level`, parameters are reordered + - `StructureBlockEntity#saveStructure` now takes in a list of blocks to ignore +- `net.minecraft.world.level.block.entity.trialspawner` + - `TrialSpawner` now takes in a `$FullConfig` + - `getConfig` -> `activeConfig` + - `get*Config` -> `*config` + - `getData` -> `getStateData` + - `TrialSpawnerData` -> `TrialSpawnerStateData`, serialized form as `TrialSpawnerStateData$Packed`, not one-to-one +- `net.minecraft.world.level.block.sounds.AmbientDesertBlockSoundsPlayer#playAmbientBlockSounds` has been split into `playAmbientSandSounds`, `playAmbientDryGrassSounds`, `playAmbientDeadBushSounds`, `shouldPlayDesertDryVegetationBlockSounds`; not one-to-one +- `net.minecraft.world.level.dimension.DimensionType` now takes in an optional integer representing the cloud height level +- `net.minecraft.world.level.entity` + - `PersistentEntitySectionManager#processPendingLoads` is now public + - `UUIDLookup#getEntity` can now return null +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate#fillFromWorld` now takes in a list of blocks to ignore rather than a single `Block` +- `net.minecraft.world.level.storage.DataVersion` is now a record +- `net.minecraft.world.phys.shapes.CollisionContext#placementContext` now takes in a `Player` instead of an `Entity` + +#### List of Removals + +- `net.minecraft.client.Minecraft#disconnect(Screen)` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#getCloudHeight`, `hasGround` + - `LevelRenderer#updateGlobalBlockEntities` +- `net.minecraft.client.renderer.texture.AbstractTexture` + - `defaultBlur` + - `setFilter` +- `net.minecraft.network.chat.Component$Serializer`, `$SerializerAdapter` +- `net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket$Action#*_SHIFT_KEY` +- `net.minecraft.server.ReloadableServerRegistries$Holder#getKeys` +- `net.minecraft.server.players.PlayerList#getPlayerForLogin` +- `net.minecraft.stats` + - `RecipeBookSettings#read`, `write` + - `ServerRecipeBook#toNbt`, `fromNbt` +- `net.minecraft.util` + - `GsonHelper#fromNullableJson(..., boolean)`, `fromJson(..., boolean)` + - `LowerCaseEnumTypeAdapterFactory` +- `net.minecraft.world.entity.ai.attributes.AttributeInstance#ID_FIELD`, `TYPE_CODEC` +- `net.minecraft.world.entity.animal.horse.AbstractHorse#setIsJumping` +- `net.minecraft.world.entity.animal.sheep.Sheep#getColor` +- `net.minecraft.world.entity.monster.Drowned#waterNavigation`, `groundNavigation` +- `net.minecraft.world.entity.projectile.Projectile#findOwner`, `setOwnerThroughUUID` +- `net.minecraft.world.level.Level#disconnect()` +- `net.minecraft.world.level.block` + - `AbstractCauldronBlock#isEntityInsideContent` + - `TerracottaBlock` +- `net.minecraft.world.level.block.entity.trialspawner.TrialSpawner` + - `*_CONFIG_TAG_NAME` + - `codec` +- `net.minecraft.world.level.dimension.DimensionType#parseLegacy` + +### Step 5: 1.21.6 -> 1.21.7 + +## Minecraft 1.21.6 -> 1.21.7 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.6 to 1.21.7. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +### 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](https://misode.github.io/versions/?id=1.21.7&tab=changelog). + +### 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. + +#### List of Additions + +- `com.mojang.blaze3d.opengl.DirectStateAccess#copyBufferSubData` - Copies all or part of one buffer object's data store to the data store of another buffer object. +- `com.mojang.blaze3d.pipeline.BlendFunction#INVERT` - Inverts the blend factors of the RGB source and destination. Alpha uses the default one from source and zero from destination. +- `com.mojang.blaze3d.systems.CommandEncoder#copyToBuffer` - Copies the data store of one buffer slice to another buffer slice. +- `net.minecraft.Util#isAarch64` - Returns whether the OS architecture uses aarch64. +- `net.minecraft.client.gui.GuiGraphics#textHighlight` - Adds a highlighted box around the provided bounds. +- `net.minecraft.client.renderer.RenderPipelines#GUI_INVERT` - A render pipeline for drawing a gui element with inverted colors. +- `net.minecraft.client.renderer.item.TrackingItemRenderState` - A render state that tracks the model sources being used to render the item stack. + +#### List of Changes + +- `com.mojang.blaze3d.pipeline.RenderPipeline$Builder#withColorLogic` is now deprecated +- `net.minecraft.client.gui.renderer.GuiRenderer#MIN_GUI_Z` is now private +- `net.minecraft.client.gui.render.state.GuiItemRenderState` now takes in a `TrackingItemRenderState` instead of a `ItemStackRenderState` + - `itemStackRenderState` now returns a `TrackingItemRenderState` +- `net.minecraft.client.renderer.RenderPipelines#GUI_TEXT_HIGHLIGHT` now uses the `ADDITIVE` blend function instead of the `OR_REVERSE` color logic +- `net.minecraft.client.renderer.item.ItemStackRenderState#getModelIdentity` -> `TrackingItemRenderState#getModelIdentity` + +#### List of Removals + +- `net.minecraft.client.renderer.item.ItemStackRenderState#clearModelIdentity` + +### Step 6: 1.21.7 -> 1.21.8 + +## Minecraft 1.21.7 -> 1.21.8 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.7 to 1.21.8. 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](http://creativecommons.org/licenses/by/4.0/), 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. + +### 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](https://misode.github.io/versions/?id=1.21.8&tab=changelog). + +### 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. + +#### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds` - A helper for working around issues with specific graphics hardware. + +### Step 7: 1.21.8 -> 1.21.9 + +## Minecraft 1.21.8 -> 1.21.9 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.8 to 1.21.9. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Soaryn for pointing out some non-recommended rendering usages +- @Deximus-Maximus for some typos + +### 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](https://misode.github.io/versions/?id=1.21.9&tab=changelog). + +### The Debugging Overhaul + +The entirety of the debug system has been completely overhauled, from exposing the internal debugging tools to the debug screen. This documentation aims to provide a high level overview for handling your own debug screen and renderer additions. + +#### Debug Renderers + +Vanilla now allows users to see the debug renderers provided by the internal API by enabling them through the JVM properties via `-DMC_DEBUG_ENABLED` with whatever other desired flags. Users can take advantage of these exposed features to handle their own renderers through the vanilla provided pipeline. This overview will explain via patching the existing renderers and subscribers as needed, but these can generally be set up wherever needed. The benefit vanilla provides is its integration into existing objects (e.g. entities, block entities) and the general synchronization across the network. Of course, you can always use a simple `boolean` instead. After all, although the flags in `SharedConstants` are final, they are still checked every tick. + +##### Subscribe to Debuggers + +In most cases, information that you want to render and debug are stored on the server side. Sometimes, the information in question will be synced on the client, but in most cases it is usually some kind of partial state only necessary for rendering. + +```java +// An example object on the server +public record ExampleObject(Block held, int count) {} + +// An example on the client +// Count is not used for rendering, only for server logic +public class ExampleRenderState { + Block held; +} +``` + +Therefore, if we want to see the additional data from the server, we need some method to not only synchronize it to the client, but also update it whenever the value changes. To do so, vanilla provides `DebugSubscription`s: a class that stores the information required to sync an object if it has changed. The constructor contains two fields: the `StreamCodec` to sync the object across the network, and an optional `int` that, when greater than zero, will purge the synced value from the client if there were no more updates within the specified time. + +To handle the logic associated with synchronization, the server makes use of `TrackingDebugSynchronizer`s to handle player listeners and sync the object when necessary, and `LevelDebugSynchronizers` to handle the general tracking and ticking of the synchronizers. This data is then sent to the `ClientDebugSubscriber` for storage and the `DebugRenderer` for rendering. Note that clients can only see the debug information if they are either the owner of a singleplayer world or is an operator of the server. Additionally, the client can only request subscriptions that are added to the set provided by `ClientDebugSubscriber#requestedSubscriptions`. + +`DebugSubscription`s must be registered to `BuiltInRegistries#DEBUG_SUBSCRIPTION`: + +```java +public static final DebugSubscription EXAMPLE_OBJECt = Registry.register( + BuiltInRegistries.DEBUG_SUBSCRIPTION + ResourceLocation.withNamespaceAndPath("examplemod", "example_object"), + new DebugSubscription<>( + // The stream codec to sync the example object + StreamCodec.composite( + ByteBufCodecs.registry(Registries.BLOCK), ExampleObject::block, + ByteBufCodecs.VAR_INT, ExampleObject::count, + ExampleObject::new + ), + // The maximum number of ticks between updates + // before the data is purged from the client + // Set to zero if it should never expire + 0 + ) +); +``` + +To be able to check for updates properly, the object used must correctly implement `hashCode` and `equals`, not relying on the object identity. + +##### Debug Sources + +So, how do we tell the synchronizer to track and update our `DebugSubscription`? Well, you can extend `TrackingDebugSynchronizer` or use its subclasses and implement the tracking and syncing logic yourself, either by patching `LevelDebugSynchronizers` or creating your own. However, if the data you would like to track is directly attached to a `LevelChunk`, `Entity`, or `BlockEntity` and can be updated from their associated server object, you can make use of the `DebugValueSource`. + +`DebugValueSource` is a way to register `DebugSubscription`s as a `TrackingDebugSynchronizer$SourceSynchronizer`. This will poll and send updates to every player tracking the source with the subscription enabled every tick. Registering a `DebugSubscription` is done via `DebugValueSource#registerDebugValues`, taking in the server level and the `$Registration` interface. The registration is then handled via `$Registration#register` by passing in the subscription and a supplier to construct the subscription value. + +```java +// Assume we have some ExampleObject exampleObject in the below classes + +// For some BlockEntity, Entity, or LevelChunk subclass +@Override +public void registerDebugValues(ServerLevel level, DebugValueSource.Registration registrar) { + super.registerDebugValues(level, registrar); + // Register our subscription + registrar.register( + // The subscription + EXAMPLE_OBJECT, + // The supplied subscription object + () -> this.exampleObject + ); +} +``` + +##### Rendering the Debug Information + +Once the information has been synced to the client and stored within `ClientDebugSubscriber` (assuming you are using the above method), we now need to render that information to the screen. This is typically handled through `DebugRenderer#render`, which checks the enabled debug renderers via `refreshRendererList` before running the associated renderers. Technically, it doesn't particularly matter where as the data can be obtained at any point in the render process, but this will assume you are patching `refreshRendererList` to add your own renderer to either the opaque or translucent renderers. + +All renderers implement `DebugRenderer$SimpleDebugRenderer` to call `render`, which provides the current `PoseStack`, buffer source, camera XYZ, and `Frustum`. In addition, vanilla passes in a `DebugValueAccess` via `Connection#createDebugValueAccess` to get the synched debug information from the `ClientDebugSubscriber`. `DebugRenderer` provides simple methods to render text or boxes in specific locations using `render*`. + +The `DebugValueAccess` contains two types of methods: `get*Value` to obtain the debug object for that specific source (e.g. position, entity); and `forEach*`, which loops through all sources sending out the debug object. Which you use depends on which source you registered your `DebugSubscription` to. + +```java +// We will assume that our example object was registered to an entity +public class ExampleObjectRenderer implements DebugRenderer.SimpleDebugRenderer { + + @Override + public void render(PoseStack poseStack, MultiBufferSource bufferSource, double x, double y, double z, DebugValueAccess access, Frustum frustum) { + // Loop through all blocks with our example object + access.forEachEntity(EXAMPLE_OBJECT, (entity, exampleObject) -> { + // Render the debug info + DebugRenderer.renderTextOverMob( + poseStack, bufferSource, entity, + // Text Y offset (entities display a lot of information) + 100, + // Text to render + "Held Count: " + exampleObject.count(), + // Text color + 0xFFFFFFFF, + // The scale of the text + 1f + ); + }); + } +} +``` + +### Debug Screens + +The debug screens allows for users to to enable, disable, or only show in F3 specific components. This modular system allows for modders to add their own debug entries to the screen. Not all parts of this explanation is accessible without a bit more modding work, so those areas will be specifically pointed out. + +##### `DebugScreenEntry` + +Every debug option has its own entry that either defines what is being displayed (e.g., fps, memory), or no-ops to be handled by a separate implementation (e.g., entity hitboxes, chunk borders). This is known as a `DebugScreenEntry`, which defines three methods. + +First is the `category`. In vanilla, this is almost always `DebugEntryCategory#SCREEN_TEXT`, as all a debug entry does is draw text to the screen. The other available option `RENDERER` is only for no-op as the rendering options always rendered independent from the debug screen. `DebugEntryCategory` is simply a record with a label and some sort of sort key value, so more can be added by calling the constructor. All the category is used for is searching in the debug options screen. + +Next is `isAllowed`. This method determines whether the debug option should render on the screen independent of the entry status. By default, this is true only when the `Minecraft#showOnlyReducedInfo` accessibility option is false. Some debug entries override this method to always return true, or if some other check passes. + +Finally, there is the `display` method. This is responsible for drawing the text to the screen using the `DebugScreenDisplayer`. It also takes in the current `Level`, client chunk, and server chunk. The `DebugScreenDisplayer` has four methods that each draw text to the screen. First, there is the standard `addLine` class, which just adds the string to either the left or right side depending on what element its rendered as. These will always come one right after the other. Then, there is `addPriorityLine`, which will always be added to the top of either the left or the right side. Finally, there is `addToGroup`, which takes an additional key to render the lines as one separate group with an extra new line added at the end. + +```java +public class ExampleDebugEntry implements DebugScreenEntry { + + public static final ResourceLocation GROUP_ONE = ResourceLocation.fromNamespaceAndPath("examplemod", "group_one"); + public static final ResourceLocation GROUP_TWO = ResourceLocation.fromNamespaceAndPath("examplemod", "group_two"); + + + @Override + public void display(DebugScreenDisplayer displayer, @Nullable Level level, @Nullable LevelChunk clientChunk, @Nullable LevelChunk serverChunk) { + // The following will display like so if it is the only entry on the screen: + // First left! First Right! + // + // Hello world! Random text! + // Lorem ipsum. + // I am another group! + // I am one group This will appear after with no line breaks! + // All in a row + // Provided in a list. + // + + displayer.addLine("Hello world!"); + displayer.addLine("Lorem ipsum."); + displayer.addLine("Random text!"); + + // These will be displayed first + displayer.addPriorityLine("First left!"); + displayer.addPriorityLine("First right!"); + + // These will be grouped separately based on the key + displayer.addToGroup(GROUP_ONE, List.of( + "I am one group", + "All in a row", + "Provided in a list." + )); + + displayer.addToGroup(GROUP_TWO, "I am another group!"); + displayer.addToGroup(GROUP_TWO, "This will appear after with no line breaks!"); + } + + @Override + public boolean isAllowed(boolean reducedDebugInfo) { + // Always show regardless of accessibility option + return true; + } +} +``` + +Then, simply register your entry to `DebugScreenEntries` to have it display. It can be toggled on through the debug menu using the provided key + +```java +// This method is private, so its access will need to be widened +DebugScreenEntries.register( + // The id, this will be displayed on the options screen + ResourceLocation.fromNamespaceAndPath("examplemod", "example_entry"), + // The screen entry + new ExampleScreenEntry(); +); +``` + +##### External Toggles and Checks + +What if you want to toggle the active status separately from the options menu? What if you want to check is an entry is enabled to display debug data in-game? This can be done by accessing the `DebugScreenEntryList` through the `Minecraft` instance. + +Toggling the current status can be done via `DebugScreenEntryList#toggleStatus`. How this behaves changes depending on what screen is active. Basically, calling toggle will always flip the debug entry on or off: if it's not currently on screen, it will render on screen and vice versa. If in F3, then toggling on will only render that debug entry when F3 is on. + +The status of the entry can then be checked using `DebugScreenEntryList#isCurrentlyEnabled`. This will only check if the debug screen is in the currently on list and not check `DebugScreenEntry#isAllowed`. + +```java +// Lets create another entry +public static final ResourceLocation EXAMPLE_TOGGLE = DebugScreenEntries.register( + ResourceLocation.fromNamespaceAndPath("examplemod", "example_toggle"), + // We're using noop as nothing is being displayed as text + new DebugEntryNoop(); +); + +// To toggle: +Minecraft.getInstance().debugEntries.toggleStatus(EXAMPLE_TOGGLE); + +// To check if enabled: +if (Minecraft.getInstance().debugEntries.isCurrentlyEnabled(EXAMPLE_TOGGLE)) { + // ... +} +``` + +##### Profiles + +Profiles are defined presets that can be configured to the user's desire. Currently, profiles are hardcoded to either default or performance. To extend the system, you need to be able to dynamically add an entry to the `DebugScreenProfile` enum, make the `DebugScreenEntries#PROFILES` map mutable to add your profile and preset, and modify the debug option screen with your profile button. + +- `net.minecraft.SharedConstants` + - `DEBUG_SHUFFLE_MODELS` - A flag that likely shuffles the model loading order. + - `DEBUG_FLAG_PREFIX` - A prefix put in front of every debug flag. + - `USE_DEBUG_FEATURES` -> `DEBUG_ENABLED` + - `DEBUG_RENDER` is removed + - `DEBUG_WORLDGENATTEMPT` is removed + - `debugGenerateStripedTerrainWithoutNoise` is removed + - `DEBUG_RESOURCE_GENERATION_OVERRIDE` is removed + - `DEBUG_POI` - Enables the POI debug renderer. + - `DEBUG_PANORAMA_SCREENSHOT` - When enabled, allows the user to take a panorama screenshot. + - `DEBUG_CHASE_COMMAND` - When enabled, adds the chase command. + - `FAKE_MS_LATENCY` -> `DEBUG_FAKE_LATENCY_MS` + - `FAKE_MS_JITTER` -> `DEBUG_FAKE_JITTER_MS` + - `DEBUG_VERBOSE_COMMAND_ERRORS` - When enabled, outputs verbose errors through the chat box. + - `DEBUG_DEV_COMMANDS` - When enabled, adds the commands used for debugging the game. +- `net.minecraft.client.Minecraft` + - `debugEntries` - Returns a list of debug features and what should be shown on screen. + - `fpsString`, `sectionPath`, `sectionVisibility` are removed + - `debugRenderer` -> `LevelRenderer#debugRenderer` +- `net.minecraft.client.gui.Gui` + - `renderDebugOverlay` is now public + - `shouldRenderDebugCrosshair` is removed +- `net.minecraft.client.gui.components.DebugScreenOverlay` + - `drawGameInformation`, `drawSystemInformation` are removed + - `getGameInformation`, `getSystemInformation` are removed + - `toggleOverlay` is removed +- `net.minecraft.client.gui.components.debug` + - `DebugEntryBiome` - A debug entry displaying the biome the camera entity is within. + - `DebugEntryCategory` - A category that describes how a debug entry is displayed. + - `DebugEntryChunkGeneration` - A debug entry displaying the current chunk generation info. + - `DebugEntryChunkRenderStats` - A debug entry displaying the current section statistics. + - `DebugEntryChunkSourceStats` - A debug entry displaying the general metadata of the chunk sources. + - `DebugEntryEntityRenderStats` - A debug entry displaying the general metadata of the entity storage. + - `DebugEntryFps` - A debug entry displaying the frames per second and vsync info. + - `DebugEntryGpuUtilization` - A debug entry displaying the GPU utilization. + - `DebugEntryHeightmap` - A debug entry displaying the height maps at the current position. + - `DebugEntryLight` - A debug entry displaying the client light information. + - `DebugEntryLocalDifficulty` - A debug entry displaying the current world difficulty and time. + - `DebugEntryLookingAtBlock` - A debug entry displaying the block the camera is currently looking at. + - `DebugEntryLookingAtEntity` - A debug entry displaying the entity the camera is currently looking at. + - `DebugEntryLookingAtFluid` - A debug entry displaying the fluid the camera is currently looking at. + - `DebugEntryMemory` - A debug entry displaying the memory allocated and used by the game. + - `DebugEntryNoop` - A debug entry displaying nothing. + - `DebugEntryParticleRenderState` - A debug entry displaying the number of particles being rendered. + - `DebugEntryPosition` - A debug entry displaying the current position and rotation of the camera entity. + - `DebugEntryPostEffect` - A debug entry displaying the currently applied post effect. + - `DebugEntrySectionPosition` - A debug entry displaying the current section position. + - `DebugEntrySimplePerformanceImpactors` - A debug entry displaying the graphics mod, cloud status, and biome blend radius. + - `DebugEntrySoundMood` - A debug entry displaying the current sound played and player mood. + - `DebugEntrySpawnCounts` - A debug entry displaying the entity spawn counts per mob category. + - `DebugEntrySystemSpecs` - A debug entry displaying the specs of the running machine. + - `DebugEntryTps` - A debug entry displaying the general ticks per second. + - `DebugEntryVersion` - A debug entry displaying the current Minecraft version. + - `DebugScreenDisplayer` - An interface that the debug entries use to display elements to the screen. + - `DebugScreenEntries` - The debug entries registered by Minecraft. + - `DebugScreenEntry` - An element that shows up, if enabled, when the debug overlay is enabled. + - `DebugScreenEntryList` - The options information for what debug elements are displayed on screen. + - `DebugScreenEntryStatus` - The status of when a debug entry should be displayed. + - `DebugScreenProfile` - An enum denoting the profiles that the debug screen can set when deciding what entries to show. +- `net.minecraft.client.gui.screen.debug.DebugOptionsScreen` - A screen that allows the user to change the displayed debug entries for a profile. +- `net.minecraft.client.renderer.LevelRenderer` + - `getSectionStatistics` is now nullable + - `getEntityStatistics` is now nullable + - `gameTestBlockHighlightRenderer` - The renderer for the block highlight within a game test. +- `net.minecraft.client.renderer.debug.DebugRenderer` + - `switchRenderChunkborder` -> `DebugScreenEntries#CHUNK_BORDERS`, not one-to-one + - `toggleRenderOctree` -> `DebugScreenEntries#CHUNK_SECTION_OCTREE`, not one-to-one +- `net.minecraft.client.multiplayer` + - `DebugSampleSubscriber` -> `ClientDebugSubscriber`, not one-to-one + - `ClientPacketListener#createDebugValueAccess` - Creates the access to get the current debug values. +- `net.minecraft.client.renderer.debug` + - `BeeDebugRenderer#addOrUpdateHiveInfo`, `addOrUpdateBeeInfo`, `removeBeeInfo` are removed + - `BrainDebugRenderer` + - `addPoi`, `removePoi`, `$PoiInfo` are removed + - `setFreeTicketCount` is removed + - `addOrUpdateBrainDump`, `removeBrainDump` are removed + - `BreezeDebugRenderer` now implements `DebugRenderer$SimpleDebugRenderer` + - `render` now takes in a `DebugValueAccess` + - `clear`, `add` are removed + - `DebugRenderer` no longer takes in the `Minecraft` instance + - All field renderers have been removed from public access, instead being store in on of the `*Renderers` lists + - `worldGenAttemptRenderer` is removed + - `renderTextOverBlock` - Renders the given stream above the provided block position. + - `renderTextOverMob` - Renders the given string over the provided entity. + - `refreshRendererList` - Populates the renderer lists with the enabled debug renderers. + - `render`, `renderAfterTranslucents` have been merged into `render`, where a `boolean` determines whether to render the translucent or opaque renderers + - `$SimpleDebugRenderer` + - `render` now takes in a `DebugValueAccess` and `Frustum` + - `clear` is removed + - `EntityBlockIntersectionDebugRenderer` - A debug renderer for displaying the blocks the entity is intersecting with. + - `GameEventListenerRenderer` no longer takes in the `Minecraft` instance + - `trackGameEvent`, `trackListener` are removed + - `GameTestDebugRenderer` -> `GameTestBlockHighlightRenderer`, not one-to-one + - `addMarker` -> `highlightPos`, not one-to-one + - `GoalSelectorDebugRenderer#addGoalSelector`, `removeGoalSelector` are removed + - `NeighborsUpdateRenderer` no longer takes in the `Minecraft` instance + - `addUpdate` is removed + - `OctreeDebugRenderer` now implements `DebugRenderer$SimpleDebugRenderer` + - `PathfindingRenderer#addPath` is removed + - `PoiDebugRenderer` - A debug renderer for displaying the point of interests. + - `RaidDebugRenderer#setRaidCenters` is removed + - `RedstoneWireOrientationsRenderer` no longer takes in the `Minecraft` instance + - `addWireOrientation` is removed + - `StructureRenderer` no longer takes in the `Minecraft` instance + - `addBoundingBox` is removed + - `VillagerSectionsDebugRenderer#setVillageSection`, `setNotVillageSection` are removed + - `WorldGenAttemptRenderer` class is removed +- `net.minecraft.core.registries.BuiltInRegistries`, `Registries#DEBUG_SUBSCRIPTION` - A registry for subscriptions to debug handlers. +- `net.minecraft.gametest.framework` + - `GameTestAssertPosException#getMessageToShowAtBlock` now returns a `Component` + - `GameTestRunner#clearMarkers` is removed +- `net.minecraft.network.protocol.common.custom` + - All classes have been moved to `net.minecraft.util.debug` + - They are no longer payloads, instead just records containing the object info and an associated stream codec + - If the payload class had an associated object inner class, then that class was moved and the payload class removed + - Otherwise the payload class was added without the `*Payload` suffix, most of the time with an `*Info` suffix +- `net.minecraft.network.protocol.game` + - `ClientboundDebugBlockValuePacket` - A packet sent to the client about a debug value change on a block position. + - `ClientboundDebugChunkValuePacket` - A packet sent to the client about a debug value change on a chunk position. + - `ClientboundDebugEntityValuePacket` - A packet sent to the client about a debug value change on an entity. + - `ClientboundDebugEventPacket` - A packet sent to the client about the debug event fired. + - `ClientboundGameTestHighlightPosPacket` - A packet sent to the client about the game test position to highlight. + - `ClientGamePacketListener` + - `handleDebugChunkValue` - Handles the debug chunk position packet. + - `handleDebugBlockValue` - Handles the debug block position packet. + - `handleDebugEntityValue` - Handles the debug entity packet. + - `handleDebugEvent` - Handles the firing debug event. + - `handleGameTestHighlightPos` - Handles the provided position being highlighted. + - `DebugPackets` class is removed + - `ServerboundDebugSampleSubscriptionPacket` -> `ServerboundDebugSubscriptionRequestPacket`, not one-to-one + - `ServerGamePacketListener#handleDebugSampleSubscription` -> `handleDebugSubscriptionRequest`, not one-to-one +- `net.minecraft.server.MinecraftServer` + - `subscribeToDebugSample` is removed + - `debugSubscribers` - Returns a map of the tracked subscriptions to the list of players that have it enabled. +- `net.minecraft.server.level` + - `ChunkMap` + - `isChunkTracked` is now public + - `getChunks` is removed + - `ServerLevel#debugSynchronizers` - Returns the debugger handler and synchronizer for the level. + - `ServerPlayer` + - `requestDebugSubscriptions` - Sets the debuggers that the player is listening for. + - `debugSubscriptions` - Returns the debuggers that the player is listening for. +- `net.minecraft.util.debug` + - `DebugSubscription` - A tracked data point that can be listened or subscribed to. + - `DebugSubscriptions` - Vanilla debug subscriptions. + - `DebugValueAccess` - Accesses the values tracked by the debug subscription, used on the client for the debug renderers. + - `DebugValueSource` - Defines a source object that provides debug values to track, such as an entity. + - `LevelDebugSynchronizers` - Handles sending the subscription data across the network to the tracking clients. + - `ServerDebugSubscribers` - Handles the global state of players subscribed to the currently enabled subscriptions. + - `TrackingDebugSynchronizer` - Handles the list of players subscribed to a subscription. +- `net.minecraft.util.debugchart` + - `DebugSampleSubscriptionTracker` class is removed + - `RemoteDebugSampleType` now takes in a `DebugSubscription` + - `subscription` - Returns the subscription reported by the sample type. + - `RemoteSampleLogger` now takes in `ServerDebugSubscribers` instead of `DebugSampleSubscriptionTracker` +- `net.minecraft.world.entity` + - `Entity` now implements `DebugValueSource` + - `Mob#sendDebugPackets` is removed +- `net.minecraft.world.entity.ai.village.poi` + - `PoiManager#getFreeTickets` -> `getDebugPoiInfo`, not one-to-one + - `PoiSection#getDebugPoiInfo` - Returns the debug poi info for the given position. +- `net.minecraft.world.level.block.entity` + - `BlockEntity` now implements `DebugValueSource` + - `TestInstanceBlockEntity#markError`, `clearErrorMarkers`, `getErrorMarkers`, `$ErrorMarker` - Handles the error markers set by the test instance. +- `net.minecraft.world.level.chunk.LevelChunk` now implements `DebugValueSource` +- `net.minecraft.world.level.pathfinder.PathFinder#setCaptureDebug` - Sets whether the path should be captured for debugging. +- `net.minecraft.world.level.redstone.CollectingNeighborUpdater#setDebugListener` - Sets the listener for block location changes for debugging. + +### Feature Submissions: The Movie + +The entirety of the rendering pipeline, from entities to block entities to particles, has been reworked into a submission / render phase system known as features. This guide will go over the basics of the feature system itself followed by how each major type are implemented using it. + +#### Submission and Rendering + +The feature system, like GUIs, is broken into two phases: submission and rendering. The submission phase is handled by the `SubmitNodeCollector`, which basically collects the data required to abstractly render an object to the screen. This is all done through the `submit*` methods, which generally take a `PoseStack` to place the object in 3D space, and any other required data such as the model, state, render type, etc. + +Here is a quick overview of what each method takes in: + +Method | Parameters +:---------------------:|:---------- +`submitHitbox` | A pose stack, render state of the entity, and the hitboxes render state +`submitShadow` | A pose stack, the shadow radius, and the shadow pieces +`submitNameTag` | A pose stack, an optional position, the Y offset, the text component, if the text should be seethrough (like when sneaking), light coordinates, and the camera render state +`submitText` | A pose stack, the XY offset, the text sequence, whether to add a drop shadow, the font display mode, light coordinates, color, background color, and outline color +`submitFlame` | A pose stack, render state of the entity, and a rotation quaternion +`submitLeash` | A pose stack and the leash state +`submitModel` | A pose stack, entity model, render state, render type, light coordinates, overlay coordinates, tint color, an optional texture, outline color, and an optional crumbling overlay +`submitModelPart` | A pose stack, model part, render type, light coordinates, overlay coordinates, an optional texture, whether to use item glint over entity glint if render type is not transparent, whether to render the glint overlay, tint color, an optional crumbling overlay, and an outline color +`submitBlock` | A pose stack, block state, light coordinates, overlay coordinates, and outline color +`submitMovingBlock` | A pose stack and the moving block render state +`submitBlockModel` | A pose stack, the render type, block state model, RGB floats, light coordinates, overlay coordinates, and outline color +`submitItem` | A pose stack, item display context, light coordinates, overlay coordinates, outline color, tint layers, quads, render type, and foil type +`submitCustomGeometry` | A pose stack, render type, and a function that takes in the current pose and `VertexConsumer` to create the mesh +`submitParticleGroup` | A `SubmitNodeCollector$ParticleGroupRenderer` + +Technically, the `submit*` methods are provided by the `OrderedSubmitNodeCollector`, of which the `SubmitNodeCollector` extends. This is because features can be submitted to different orders, which function similarly to strata in GUIs. By default, all submit calls are pushed onto order 0. Using `SubmitNodeCollector#order` with some integer and then calling the `submit*` method, you can have an object render before or after all features on a given order. This is stored as an AVL tree, where each order's data is stored in a `SubmitNodeCollection`. With the current default feature rendering order, this is only used in very specific circumstances, such as rendering a slime's outer body or equipment layers. + +```java +// Assume we have access to the `SubmitNodeCollector` collector + +// This will render in order 0 +collector.submitModel(...); + +// This will render before the `submitModel` call +collector.order(-1).submitShadow(...); + +// This will render after the `submitModel` call +collector.order(1).submitNameTag(...); +``` + +The render phase is handled through the `FeatureRenderDispatcher`, which renders the object using their submitted feature renderers. What are feature renderers? Quite literally an arbitrary method that loops through the node contents its going to push to the buffer. Currently, for a given order, the features push their vertices like so: shadows, models, model parts, flame animations, entity name tags, arbitrary text, hitboxes, leashes, items, blocks, custom render pipelines, and finally particles. Each order, starting from the smallest number to the largest, will rerun all of the feature renders until it reaches the end of the tree. All submissions are then cleared for next use. + +Most of the feature dispatchers are simply run a loop over its collection. Those that store the render type batch the render calls into one buffer. `ModelFeatureRenderer`, meanwhile, goes one step further, sorting its translucent models by distance from the camera and sends them to the buffer after all opaque models. + +#### Entity Models + +So, how does this affect entities? Let's start with the root `Model` that makes up all entity models. `Model` now has a generic which is used to pass in the state of the backing object to `setupAnim`, which has also been moved to `Model`. This means that the base model class is rarely passed around, instead opting for some subtype, like `Model$Simple` for signs. Given that most `EntityModel`s already require a generic of `EntityRenderState`, this does not affect anything. + +The main change comes from how model part visibility work, such as armors and capes. Every single individual part (e.g. helmet, chestplate) now has their own separate model, meaning that the general part visibility system has been completely removed. You can still provide visibility through the mutable model part in `setupAnim`, but the general movement is to simply have parts that should be separate models as separate models. + +To facilitate this, `PartDefinition`s now has methods to selectively keep certain parts of models and remove the others. This is done through the `clear*` and `retain*` methods. Basically, all of these methods are doing are keeping the part pose while removing any cubes associated with the children queries. `retain*` allows for certain parts and potentially subparts to keep their cubes. This addition provides a twofold benefit: model layers can deterministically use `setupAnim` to setup the parts similarly to the base model, and the model texture will only need to contain the retained elements. + +Here is an example for creating the armor models for a creeper: + +```java +// Deformations for humanoid armor +private static final CubeDeformation OUTER_ARMOR_DEFORMATION = new CubeDeformation(1.0F); +private static final CubeDeformation INNER_ARMOR_DEFORMATION = new CubeDeformation(0.5F); + +// Creeper has the following parts: +// - head +// - body +// - right_hind_leg, left_hind_leg +// - right_front_leg, left_front_leg + +// We use separate meshes as we are basically isolating the parts we want to keep in each + +public static ArmorModelSet createCreeperArmor() { + // Helmet + + // Create mesh + MeshDefinition helmetMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + // Note that body and the legs still exist, they simply have no cubes + helmetMesh.getRoot().retainExactParts(Set.of("head")); + + // Chestplate + + // Create mesh + var chestplateMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + chestplateMesh.getRoot().retainExactParts(Set.of("body")); + + // Leggings + + // Create mesh + var leggingsMesh = CreeperModel.createBodyLayer(INNER_ARMOR_DEFORMATION); + // Only retain the desired parts + leggingsMesh.getRoot().retainExactParts(Set.of("right_hind_leg", "left_hind_leg", "right_front_leg", "left_front_leg")); + + // Boots + + // Create mesh + var bootsMesh = CreeperModel.createBodyLayer(OUTER_ARMOR_DEFORMATION); + // Only retain the desired parts + bootsMesh.getRoot().retainExactParts(Set.of("right_hind_leg", "left_hind_leg", "right_front_leg", "left_front_leg")); + + // Store this all in an ArmorModelSet, which is basically just object holder and mapper + return new ArmorModelSet<>( + helmetMesh, + chestplateMesh, + leggingsMesh, + bootsMesh + ); +} + +// To register the layer definitions, basically the same process of using the ArmorModelSet +public static final ArmorModelSet CREEPER_ARMOR = new ArmorModelSet<>( + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "helmet"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "chestplate"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "leggings"), + new ModelLayerLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "creeper"), "boots") +); + +// In some method where you have access to the Map builder +ArmorModelSet creeperArmorLayers = createCreeperArmor().map(mesh -> LayerDefinition.create(mesh, 64, 32)); +CREEPER_ARMOR.putFrom(creeperArmorLayers, builder); +``` + +#### Entity Renderer + +With the change to submission, the `EntityRenderer` and its associated `RenderLayer`s have also changed. Basically, you can assume almost every method that has the word `render` has been changed to `submit`, and `MultiBufferSource` and light coordinates integer have generally been replaced by `SubmitNodeCollector` and the associated entity render state. + +The new `submit` method that replaces `render` in `EntityRenderer` now takes in the render state of the entity, the `PoseStack`, the `SubmitNodeCollector`, and the `CameraRenderState`. When submitting any element, the location in 3D space is taken by getting the last pose on the `PoseStack` and storing that for future use. + +```java +// A basic entity renderer + +// We will assume all the classes listed exist +public class ExampleEntityRenderer extends MobRenderer { + + public ExampleEntityRenderer(EntityRendererProvider.Context ctx) { + super(ctx, ctx.bakeLayer(EXAMPLE_MODEL_LAYER), 0.5f); + } + + @Override + public void submit(ExampleEntityRenderState renderState, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState cameraState) { + super.submit(renderState, poseStack, collector, cameraState); + + // An example of submitting something + collector.submitCustomGeometry( + poseStack, // The current pose + RenderType.solid(), // The render type to use + ExampleEntityRenderer::addVertices // The method to write the geometry data + ); + } + + private static void addVertices(PoseStack.Pose pose, VertexConsumer consumer) { + // Add custom geometry + } +} + +// A render layer + +public class CreeperArmorLayer extends RenderLayer { + + private final ArmorModelSet modelSet; + private final EquipmentLayerRenderer equipment; + + public CreeperArmorLayer(RenderLayerParent parent, ArmorModelSet modelSet, EquipmentLayerRenderer equipment) { + super(parent); + this.modelSet = modelSet; + this.equipment = equipment; + } + + // We will assume we added headEquipment, chestEquipment, legsEquipment, feetEquipment to the CreeperRenderState somehow + @Override + public void submit(PoseStack poseStack, SubmitNodeCollector collector, int lightCoords, CreeperRenderState renderState, float yRot, float xRot) { + this.renderArmorPiece(poseStack, collector, renderState.chestEquipment, EquipmentSlot.CHEST, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.legsEquipment, EquipmentSlot.LEGS, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.feetEquipment, EquipmentSlot.FEET, lightCoords, renderState); + this.renderArmorPiece(poseStack, collector, renderState.headEquipment, EquipmentSlot.HEAD, lightCoords, renderState); + } + + // Taken from humanoid armor layer + private void renderArmorPiece(PoseStack poseStack, SubmitNodeCollector collector, ItemStack stack, EquipmentSlot slot, int lightCoords, CreeperRenderState renderState) { + Equippable equippable = stack.get(DataComponents.EQUIPPABLE); + if (equippable != null && equippable.assetId().isPresent() && equippable.slot() == slot) { + CreeperModel model = this.modelSet.get(slot); + EquipmentClientInfo.LayerType layer = slot == EquipmentSlot.LEGS + ? EquipmentClientInfo.LayerType.HUMANOID_LEGGINGS + : EquipmentClientInfo.LayerType.HUMANOID; + this.equipmentRenderer.renderLayers( + layer, // The equipment layer to use + equippable.assetId().orElseThrow(), // The equipment asset to pull + model, // The armor model + renderState, // The entity render state + stack, // The armor stack + poseStack, // The pose stack + collector, // The collector to add the model data to + lightCoords, // The light coordinates + renderState.outlineColor // The outline color of the entity + ); + } + } +} + +// Then, to add it to the creeper renderer constructor +public CreeperRenderer(EntityRendererProvider.Context ctx) { + // ... + this.addLayer(new CreeperArmorLayer( + this, // The parent is the renderer itself + ArmorModelSet.bake( // Baking the model set + CREEPER_ARMOR, // The model layer locations + ctx.getModelSet(), // The model set to map the models from the layer locations + CreeperModel::new // The mapper for the root part to the model + ), + ctx.getEquipmentRenderer() // The renderer for the equipment + )); +} +``` + +#### Block Entity Renderer + +`BlockEntityRenderer`s also use the new submission method, replacing almost every `render*` with `submit`. They have taken a play from entities, now having their own `BlockEntityRenderState` which is extracted from the `BlockEntity`. As such, `BlockEntityRenderer` now has a new generic `S` for the `BlockEntityRenderState`. + +The `BlockEntityRenderState`, by default, contains information about its position, block state, type, light coordinates, and the current break progress as a `ModelFeatureRenderer$CrumblingOverlay`. These are all populated through `BlockEntityRenderState#extractBase`, which is called in `BlockEntityRenderer#extractRenderState`. Like entities, the render state is first constructed via `BlockEntityRenderer#createRenderState` before the values are extracted from the block entity. `extractRenderState` does contain the partial tick and camera position, but this is not passed to the `BlockEntityRenderState` by default. + +As such, the `submit` method that takes over the `render` method takes in the render state, a `PoseStack` for the location in 3D space, the `SubmitNodeCollector` for pushing the elements to render, and the `CameraRenderState`. + +```java +// We will assume all the classes not specified here exist + +// A simple render state +public class ExampleRenderState extends BlockEntityRenderState { + public float partialTick; +} + +// A basic block entity renderer +public class ExampleBlockEntityRenderer implements BlockEntityRenderer { + + public ExampleBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) { + // Get anything you need from the context + } + + @Override + public ExampleRenderState createRenderState() { + // Create the render state used to submit the block entity to the feature renderer + return new ExampleRenderState(); + } + + @Override + public void extractRenderState(ExampleBlockEntity blockEntity, ExampleRenderState renderState, float partialTick, Vec3 cameraPos, @Nullable ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) { + // Extract the necessary rendering values from the block entity to the render state + // Always call super or BlockEntityRenderState#extractBase + super.extractRenderState(blockEntity, renderState, partialTick, cameraPos, crumblingOverlay); + + // Populate any desired values + renderState.partialTick = partialTick; + } + + + @Override + public void submit(ExampleRenderState renderState, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState cameraState) { + // An example of submitting something + collector.submitModel(..., renderState.breakProgress); + } +} +``` + +#### Special Item Models + +Since special item models also make use of custom rendering, they have been updated to with the `submit` change, only replacing `MultiBufferSource` with the `SubmitNodeCollector`. + +```java +// A basic special item model + +// We will assume all the classes listed exist +public class ExampleSpecialModelRenderer implements NoDataSpecialModelRenderer { + + public ExampleSpecialModelRenderer() {} + + @Override + public void submit(ItemDisplayContext displayContext, PoseStack poseStack, SubmitNodeCollector collector, int lightCoords, int overlayCoords, boolean hasFoil, int outlineColor) { + // An example of submitting something + collector.submitModelPart(...); + } + + @Override + public void getExtents(Set extents) {} +} +``` + +#### Particles + +Particles have been added to the submission process; however, there are multiple paths depending on how complicated your particle is. A few classes and general names have been reused for an additional purpose as well, sometimes making it difficult to understand how each part works. As such, this document will go over two methods of creating a particle: one more familiar with the old system, and one that explains the underlying nuances from the ground up. + +##### The Separation of Engines and Resources + +Before we discuss the two methods, first, let's go with the overarching changes. `ParticleEngine` has been functionally split up into two classes: `ParticleEngine`, which handle the actual ticking and extraction, not submission, of the render state; and `ParticleResources`, which is the reload listener that registers the `ParticleProvider` and optionally `ParticleResources$SpriteParticleRegistration` and reloads the `SpriteSet` from its `ParticleDescription`. This underlying behavior hasn't change (besides the whole extract and submission process), the methods have simply been moved. + +`ParticleProvider#createParticle` also now provides a `RandomSource`, which can be used as needed. + +As for the actual submission and rendering process, this is handled outside of `ParticleEngine`. More specifically, the `LevelRenderer` extracts all the particles to submit in `ParticlesRenderState` via `ParticleEngine#extract`. Then, in `LevelRenderer#addParticlesPass`, the resource handles are set to the particle `FramePass`, to which on execution the particles are submitted via `ParticlesRenderState#submit` and then rendered through the feature dispatcher via `ParticleFeatureRenderer`. + +##### A Single Quad + +Many particles in the old system were simply made up of a single quad with a texture(s) slapped on it. These particles are `SingleQuadParticle`s, which merges both the previous `SingleQuadParticle` and `TextureSheetParticle` into one. The `SingleQuadParticle` now takes in an initial `TextureAtlasSprite` to set the first texture, which can then be updated by overriding `Particle#tick` and calling `SingleQuadParticle#setSpriteFromAge` for a `SpriteSet` or directly with `setSprite`. The tint can also be modified in the tick using `setColor` and `setAlpha`. Some also set these directly in `SingleQuadParticle#extract`, but which to use depends on if you need to override the entire tick or not. + +To determine the `RenderType` that is used to render the quad, `SingleQuadParticle#getLayer` must be set to the desired `$Layer`. A `$Layer` is basically a record defining whether the quad can have translucency, what texture atlas it pulls from, and the render pipeline to use. Vanilla provides `TERRAIN`, `OPAQUE`, and `TRANSLUCENT` similar to the old `Particle#getRenderType` which it replaces. `TERRAIN` and `TRANSLUCENT` both allow transparency, and `OPAQUE` and `TRANSLUCENT` pull from the particle atlas while `TERRAIN` uses the block atlas. A custom `$Layer` can be created using the constructor. + +```java +public static final SingleQuadParticle.Layer EXAMPLE_LAYER = new SingleQuadParticle.Layer(true, TextureAtlas.LOCATION_PARTICLES, RenderPipelines.WEATHER_DEPTH_WRITE); +``` + +In addition to all this, you can also set how the particle is rotated by overriding `SingleQuadParticle#getFacingCameraMode`. `$FacingCameraMode` is a functional interface that sets the rotation of the particle whenever it is extracted. By default, this means that the texture will always face the camera. Any other method changes and additions are in the list below. + +From there, everything else is the same to create the `ParticleProvider` and register it. + +```java +// We will assume we have some SimpleParticleType EXAMPLE_QUAD for our particle +// Additionally, we will assume there is some particle description with our textures to use +public class ExampleQuadParticle extends SingleQuadParticle { + + private final SpriteSet spriteSet; + + // This can be package-private, protected, or public + // public should be used if the particle will be constructed outside of the provider + ExampleQuadParticle(ClientLevel level, double x, double y, double z, SpriteSet spriteSet) { + // We use first to set the initial particle texture + super(level, x, y, z, spriteSet.first()); + } + + @Override + public void tick() { + super.tick(); + // Update the particle image + this.setSpriteFromAge(spriteSet); + } + + @Override + public SingleQuadParticle.Layer getLayer() { + return EXAMPLE_LAYER; + } + + // Create the provider + public static class Provider implements ParticleProvider { + + private final SpriteSet spriteSet; + + public Provider(SpriteSet spriteSet) { + this.spriteSet = spriteSet; + } + + @Override + public Particle createParticle(SimpleParticleType options, ClientLevel level, double x, double y, double z, double xd, double yd, double zd, RandomSource random) { + // Create the particle + return new ExampleQuadParticle(level, x, y, z, this.spriteSet); + } + } +} + +// Register the provider to `ParticleResources#register` +// Assume access to ParticleResources resources and register has been made public +resources.register(EXAMPLE_QUAD, ExampleQuadParticle.Provider::new); +``` + +##### From the Ground Up + +What about rendering some more complex or custom? Well, in those instances, we need to take a deeper dive into how particles are extracted by the `ParticleEngine`. The `Particle` class, by itself actually does no extraction, submission, or rendering itself. It simply handles the physics update every tick. The actual extraction logic is handled through a `ParticleGroup`, while the submission is handled by a `ParticleGroupRenderState`. + +So, what is a `ParticleGroup`? Well, as the name implies, a particle group holds a group of particles and is responsible for keeping track of, ticking, and extracting the render state of its particles. The generic represents the type of `Particle` it can keep track of up to the maximum of 16,384 per group (though individual particles can set their own subgroup limit via `Particle#getParticleLimit`). All `SingleQuadParticle`s are part of the `QuadParticleGroup`. To extract the render state, the `ParticleEngine` calls `ParticleGroup#extractRenderState`, which takes in the current frustum, camera, and partial tick to return a `ParticleGroupRenderState`. + +`ParticleGroupRenderState` is sort of a mix between a render state, submission handler, and cache. It contains two methods: `submit`, which takes in the `SubmitNodeCollector` and submits the group; and `clear`, which clears all previous cached particle states. Technically, anything can be submitted using the collector, but particles have `SubmitNodeCollector$ParticleGroupRenderer`: an additional utility to help with caching and rendering. The group renderer contains two methods: `prepare`, to write the mesh data to a ring buffer; and `render`, which typically uses the cached buffer to write the data to the shared sequential buffer using the provided `RenderPass` and draw it to the screen. Only `QuadParticleRenderState` makes use of the cache and `ParticleGroupRenderer` as the render states are currently cleared immediately after rendering. + +To link the `ParticleGroup` to a `Particle` for use, we must set the `ParticleRenderType` using `Particle#getGroup`. `ParticleRenderType`, unlike the previous version, is simply a key for a `ParticleGroup`. This key is mapped to the group via `ParticleEngine#createParticleGroup`, and the submission/render order is determined by `ParticleEngine#RENDER_ORDER`. Both the method and the list must be patched for the particle to be properly managed by your group and extracted for submission. + +```java +// We will assume we have some SimpleParticleType EXAMPLE_ONE, EXAMPLE_TWO for our particles +// This example with construct two particles with the same base type to show how the group works + +// Create the particle type +public static final ParticleRenderType EXAMPLE_TYPE = new ParticleRenderType("examplemod:example_type"); + +// Create our particles +public abstract class ExampleParticle extends Particle { + + // You can handle passing to the particle group however you want + // Making the fields accessible or having a dedicated method + public final Model model; + + protected ExampleParticle(ClientLevel level, double x, double y, double z, Function> modelFactory) { + super(level, x, y, z); + this.model = modelFactory.apply(Minecraft.getInstance().getEntityModels()); + } + + @Override + public ParticleRenderType getGroup() { + // Set the particle type to our group + return EXAMPLE_TYPE; + } + + @FunctionalInterface + public interface ExampleParticleFactory

{ + + P create(ClientLevel level, double x, double y, double z); + } + + protected static

ParticleProvider createProvider(ExampleParticleFactory

factory) { + return (options, level, x, y, z, xd, yd, zd, random) -> factory.create(level, x, y, z); + } +} + +public class ExampleOneParticle extends ExampleParticle { + + ExampleOneParticle(ClientLevel level, double x, double y, double z) { + super(level, x, y, z, modelSet -> new Model.Simple(new ModelPart(Collections.emptyList(), Collections.emptyMap()), RenderType::entityCutoutNoCull)); + } + + public static ParticleProvider provider() { + return ExampleParticle.createProvider(ExampleOneParticle::new); + } +} + +public class ExampleTwoParticle extends ExampleParticle { + + private static final ParticleLimit LIMIT = new ParticleLimit(5); + + ExampleTwoParticle(ClientLevel level, double x, double y, double z) { + super(level, x, y, z, modelSet -> new Model.Simple(new ModelPart(Collections.emptyList(), Collections.emptyMap()), RenderType::entityCutoutNoCull)); + } + + @Override + public Optional getParticleLimit() { + // Limits the number of particles using the LIMIT subgroup to 5 + // Note that since ParticleLimit is a record, any with the same limit will be considered as the same key + return Optional.of(LIMIT); + } + + public static ParticleProvider provider() { + return ExampleParticle.createProvider(ExampleTwoParticle::new); + } +} + +// Register the providers to `ParticleResources#register` +// Assume access to ParticleResources resources and register has been made public +resources.register(EXAMPLE_ONE, ExampleOneParticle.provider()); +resources.register(EXAMPLE_TWO, ExampleTwoParticle.provider()); + +// Create the render state to submit all particles in the group +// Store whatever you need to submit to the node collector +public record ExampleGroupRenderState(List> models) implements ParticleGroupRenderState { + + @Override + public void submit(SubmitNodeCollector collector) { + // Submit every particle + for (var model : this.models) { + collector.submitModel(model, ...); + } + } +} + +// Create the particle group to keep track of the particles and create the render state +// Both EXAMPLE_ONE and EXAMPLE_TWO will be added to this group +public class ExampleParticleGroup extends ParticleGroup { + + public ExampleParticleGroup(ParticleEngine engine) { + super(engine); + } + + @Override + public ParticleGroupRenderState extractRenderState(Frustum frustum, Camera camera, float partialTick) { + // Create the particle group to submit the particles + return new ExampleGroupRenderState( + this.particles.stream().map(particle -> particle.model).toList() + ); + } +} + +// Link the ParticleRenderType to its ParticleGroup +// Assume we have access to ParticleEngine engine +// Assume that ParticleEngine#RENDER_ORDER is made mutable and public +// Assume we can patch ParticleEngine#createParticleGroup +engine.RENDER_ORDER.add(EXAMPLE_TYPE); + +// In ParticleEngine +private ParticleGroup createParticleGroup(ParticleRenderType renderType) { + if (renderType == EXAMPLE_TYPE) { + // this is referring to the ParticleEngine + return new ExampleParticleGroup(this); + } + // ... +} +``` + +#### Atlas Handler Consolidation + +The atlas handler has had some of its logic modified to consolidate other sprites and change how to obtain a `TextureAtlasSprite`. + +First, map decorations, paintings, and GUI sprites are now proper atlases with their own sheets: `Sheets#MAP_DECORATIONS_SHEET`, `PAINTINGS_SHEET`, and `GUI_SHEET` respectively. + +Obtaining the `TextureAtlasSprite` from said sheets are now completely routed through the `MaterialSet`: a functional interface that takes in a `Material` (basically a sheet location and texture location), and returns the associated `TextureAtlasSprite`. The `MaterialSet` handles texture grabs for item models, block entity renderers, and entity renderers: + +```java +// Here is an example material to grab the apple texture from the appropriate sheet +public static final Material APPLE = new Material( + TextureAtlas.LOCATION_BLOCKS, // The sheet where the item textures are stored + ResourceLocation.fromNamespaceAndPath("minecraft", "item/apple") // The texture name according to the sprite contents +); +// You can also do the same using Sheets.ITEMS_MAPPER.defaultNamespaceApply("apple") + +// For some item model +public class ExampleUnbakedItemModel implements ItemModel.Unbaked { + + // ... + + @Override + public ItemModel bake(ItemModel.BakingContext ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } +} + +// For some special item model +public class ExampleUnbakedSpecialModel implements SpecialModelRenderer.Unbaked { + + // ... + + @Override + @Nullable + public SpecialModelRenderer bake(SpecialModelRenderer.BakingContext ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } +} + +// For some block entity renderer +public class ExampleBlockEntityRenderer implements BlockEntityRenderer { + + public ExampleBlockEntityRenderer(BlockEntityRendererProvider.Context ctx) { + TextureAtlasSprite appleTexture = ctx.materials().get(APPLE); + // ... + } + + // ... +} + + +// For some entity renderer +public class ExampleEntityRenderer implements EntityRenderer { + + public ExampleEntityRenderer(EntityRendererProvider.Context ctx) { + TextureAtlasSprite appleTexture = ctx.getMaterials().get(APPLE); + // ... + } + + // ... +} +``` + +- `assets/minecraft/shaders/core` + - `blit_screen.json` -> `screenquad.json`, using no-format triangles instead of positioned quads + - `position_color_lightmap.*` are removed + - `position_color_tex_lightmap.*` are removed +- `com.mojang.blaze3d.vertex` + - `CompactVectorArray` - An holder that smashes a list of float vectors into a single sequential array. + - `MeshData$SortState#centroids` now returns a `CompactVectorArray` + - `VertexSorting` + - `byDistance` now takes in a `Vector3fc` instead of a `Vector3f` + - `sort` now takes in a `CompactVectorArray` instead of a `Vector3f[]` +- `net.minecraft.client.Minecraft` + - `getTextureAtlas` -> `AtlasManager#getAtlasOrThrow`, not one-to-one + - `getPaintingTextures`, `getMapDecorationTextures`, `getGuiSprites` -> `getAtlasManager`, not one-to-one +- `net.minecraft.client.animation.Keyframe` now has an overload that takes in the `preTarget` and `postTarget` instead of one simple `target`, taking in a `Vector3fc` instead of a `Vector3f` +- `net.minecraft.client.entity` + - `ClientAvatarEntity` - The client data of the avatar. + - `ClientAvatarState` - The movement state of the avatar. + - `ClientMannequin` - The client version of the `Mannequin` entity. +- `net.minecraft.client.gui` + - `GuiGraphics` + - `renderOutline` -> `submitOutline` + - `renderDeferredTooltip` -> `renderDeferredElements`, not one-to-one + - `submitBannerPatternRenderState` now takes in a `BannerFlagModel` instead of a `ModelPart` + `GuiSpriteManager` class is removed +- `net.minecraft.client.gui.render.GuiRenderer` now takes in the `SubmitNodeCollector` and `FeatureRenderDispatcher` + - `MIN_GUI_Z` is now public +- `net.minecraft.client.gui.render.pip` + - `GuiBannerResultRenderer` now takes in a `MaterialSet` + - `GuiSignRenderer` now takes in a `MaterialSet` +- `net.minecraft.client.gui.render.state.TiledBlitRenderState` - A render state for building a sprite using tiling, usually for tile or nine slice textures. +- `net.minecraft.client.gui.render.state.pip.GuiBannerResultRenderState` now takes in a `BannerFlagModel` instead of a `ModelPart` +- `net.minecraft.client.model` + - `AbstractPiglinModel#createArmorMeshSet` - Creates the model meshes for each of the humanoid armor slots. + - `ArmedModel` now has a generic of the `EntityRenderState` + - `translateToHand` now takes in the entity render state + - `ArmorStandArmorModel#createBodyLayer` -> `createArmorLayerSet`, not one-to-one + - `BellModel$State` - Represents the state of the backing object. + - `BookModel$State` - Represents the state of the backing object. + - `BreezeModel` + - `createBodyLayer` -> `createBaseMesh`, now private + - Replaced by `createBodyLayer`, `createWindLayer`, `createEyesLayer` + - `CopperGolemModel` - A model for the copper golem entity. + - `CopperGolemStatueModel` - A model for the coper golem statue. + - `CreakingModel` + - `NO_PARTS`, `getHeadModelParts` are removed + - `createEyesLayer` - Creates the eyes of the model. + - `EntityModel#setupAnim` -> `Model#setupAnim` + - `GuardianParticleModel` - The particle spawned from a guardian. + - `HeadedModel#translateToHead` - Transforms the pose stack to the head's position and rotation. + - `HumanoidArmorModel` -> `HumanoidModel#createArmorMeshSet`, not one-to-one + - `HumanoidModel#copyPropertiesTo` is removed + - `Model` now takes in a generic representing the render state + - `PlayerCapeModel` now extends `PlayerModel` + - `PlayerEarsModel` now extends `PlayerModel` + - `PlayerModel` render state has been broadened to `AvatarRenderState` + - Static fields are now `protected` + - `createArmorMeshSet` - Creates the model meshes for each of the humanoid armor slots. + - `SkullModelBase$State` - Represents the state of the backing object. + - `SpinAttackEffectModel` generic has been broadened to `AvatarRenderState` + - `VillagerLikeModel` now takes in a generic for the render state + - `hatVisible` is removed + - Replaced by `VillagerModel#createNoHatModel` + - `translateToArms` now takes in the render state + - `WardenModel` + - `createTendrilsLayer`, `createHeartLayer`, `createBioluminescentLayer`, `createPulsatingSpotsLayer` - Creates the layers used by the warden's `RenderLayer`s. + - `getTendrilsLayerModelParts`, `getHeartLayerModelParts`, `getBioluminescentLayerModelParts`, `getPulsatingSpotsLayerModelParts` are removed + - `ZombieVillagerModel` + - `createArmorLayer` -> `createArmorLayerSet`, not one-to-one + - `createNoHatLayer` - Creates the model without the hat layer. +- `net.minecraft.client.model.geom.ModelPart` + - `copyFrom` is removed + - `$Polygon#normal` is now a `Vector3fc` instead of a `Vector3f` + - `$Vertex` + - `pos` -> `x`, `y`, `z` + - `worldX`, `worldY`, `worldZ` - Returns the coordinates scaled down by a factor of 16. +- `net.minecraft.client.model.geom.builders.PartDefinition` + - `clearRecursively` - Clears all children parts and its sub-children. + - `retainPartsAndChildren` - Retains the specified parts from its root and any sub-children. + - `retainExactParts` - Retains only the top level part, clearing out all others and sub-children. +- `net.minecraft.client.particle` + - `AttackSweepParticle` now extends `SingleQuadParticle` + - `BaseAshSmokeParticle` now extends `SingleQuadParticle` and is `abstract` + - `BlockMarker` now extends `SingleQuadParticle` + - `BreakingItemParticle` now extends `SingleQuadParticle` + - The constructor takes in a `TextureAtlasSprite` instead of the `ItemStackRenderState` + - `$ItemParticleProvider#calculateState` -> `getSprite`, not one-to-one + - `BubbleColumnUpParticle` now extends `SingleQuadParticle` + - `BubbleParticle` now extends `SingleQuadParticle` + - `BubblePopParticle` now extends `SingleQuadParticle` + - `CampfireSmokeParticle` now extends `SingleQuadParticle` + - `CritParticle` now extends `SingleQuadParticle` + - `DragonBreathParticle` now extends `SingleQuadParticle` + - `$Provider` generic now uses a `PowerParticleOption` + - `DripParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `create*Particle` methods -> `$*Provider` classes + - `DustParticleBase` now extends `SingleQuadParticle` + - `ElderGuardianParticleGroup` - The particle group responsible for setting up and submitting the elder guardian particle. + - `ExplodeParticle` now extends `SingleQuadParticle` + - `FallingDustParticle` now extends `SingleQuadParticle` + - `FallingLeavesParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` instead of a `SpriteSet` + - `FireflyParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FireworkParticles` + - `$FlashProvider` generic now uses `ColorParticleOption` + - `$OverlayParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FlameParticle` now takes in a `TextureAtlasSprite` + - `FlyStraightTowardsParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `FlyTowardsPositionParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `GlowParticle` now extends `SingleQuadParticle` + - `GustParticle` now extends `SingleQuadParticle` + - `HeartParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `HugeExplosionParticle` now extends `SingleQuadParticle` + - `ItemPickupParticle` now takes in the `EntityRenderState` instead of the `EntityRenderDispatcher` + - Fields are now all `protected` aside from the target entity + - `ItemPickupParticleGroup` - The particle group responsible for setting up and submitting the item pickup particle. + - `LavaParticle` now extends `SingleQuadParticle` + - `MobAppearanceParticle` -> `ElderGuardianParticle` + - `NoRenderParticleGroup` - The particle group that does nothing. + - `NoteParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `Particle` + - `rCol`, `gCol`, `bCol`, `alpha` -> `SingleQuadParticle#rCol`, `gCol`, `bCol`, `alpha` + - `roll`, `oRoll` -> `SingleQuadParticle#roll`, `oRoll` + - `setColor`, `setAlpha` -> `SingleQuadParticle#setColor`, `setAlpha` + - `render`, `renderCustom` -> `ParticleGroupRenderState#submit`, not one-to-one + - `getRenderType` -> `getGroup` + - The original purpose of this method has been moved to `SingleQuadParticle#getLayer` + - `getParticleGroup` -> `getParticleLimit`, not one-to-one + - `ParticleEngine` no longer implements `PreparableReloadListener` + - The constructor now takes in the `ParticleResources` instead of the `TextureManager` + - `close` is removed + - `updateCount` is now `protected` + - `render` -> `extract`, not one-to-one + - `destroy` -> `ClientLevel#addDestroyBlockEffect` + - `crack` -> `ClientLevel#addBreakingBlockEffect` + - `clearParticles` is now `public` + - `$MutableSpriteSet` -> `ParticleResources$MutableSpriteSet` + - `$SpriteParticleRegistration` -> `ParticleResources$SpriteParticleRegistration` + - `ParticleGroup` - A holder of particles for a specific `ParticleRenderType`, responsible for ticking and extracting the general render state. + - `ParticleProvider` + - `createParticle` now takes in the `RandomSource` + - `$Sprite#createParticle` now takes in the `RandomSource` and returns a `SingleQuadParticle` instead of a `TextureSheetParticle` + - `ParticleRenderType` no longer takes in the `RenderType` + - This record has been repurposed to represent a key for the particle groups + - `TERRAIN_SHEET` -> `SingleQuadParticle$Layer#TERRAIN` + - `PARTICLE_SHEET_OPAQUE` -> `SingleQuadParticle$Layer#OPAQUE` + - `PARTICLE_SHEET_TRANSLUCENT` -> `SingleQuadParticle$Layer#TRANSLUCENT` + - `CUSTOM` is replaced by a particle group that is not for `ParticleRenderType#SINGLE_QUADS` + - `ParticleResources` - Loads the particle providers, any necessary descriptions, and computes them into their desired sprite set. + - `PlayerCloudParticle` now extends `SingleQuadParticle` + - `PortalParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `QuadParticleGroup` - The particle group responsible for setting up and submitting single quad particles. + - `ReversePortalParticle` now takes in a `TextureAtlasSprite` + - `RisingParticle` now extends `SingleQuadParticle` + - `SculkChargeParticle` now extends `SingleQuadParticle` + - `SculkChargePopParticle` now extends `SingleQuadParticle` + - `SculkChargePopParticle` now extends `SingleQuadParticle` + - `ShriekParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `SimpleAnimatedParticle` now extends `SingleQuadParticle` and is `abstract` + - `SingleQuadParticle` now takes in a `TextureAtlasSprite` + - `sprite` - The texture of the particle. + - `render` -> `extract`, not one-to-one, now taking in the `QuadParticleRenderState` instead of a `VertexConsumer` + - `renderRotatedQuad` -> `extractRotatedQuad`, not one-to-one, now taking in the `QuadParticleRenderState` instead of a `VertexConsumer` + - `getU0`, `getU1`, `getV0`, `getV1` are no longer abstract + - `getLayer` - Sets the render layer of the single quad. + - `$Layer` - The layer the single quad should render in. + - `SnowflakeParticle` now extends `SingleQuadParticle` + - `SpellParticle` now extends `SingleQuadParticle` + - `InstantProvider` generic now uses `SpellParticleOption` + - `SplashParticle` now takes in a `TextureAtlasSprite` + - `SpriteSet#first` - Returns the first texture in the sprite set. + - `SuspendedParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `SuspendedTownParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `TerrainParticle` now extends `SingleQuadParticle` + - `TextureSheetParticle` class is removed, use `SingleQuadParticle` instead + - `TrailParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `TrialSpawnerDetectionParticle` now extends `SingleQuadParticle` + - `VibrationSignalParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `WakeParticle` now extends `SingleQuadParticle` + - `WaterCurrentDownParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` + - `WaterDropParticle` now extends `SingleQuadParticle` and takes in a `TextureAtlasSprite` +- `net.minecraft.client.player.AbstractClientPlayer` fields are now stored within `ClientAvatarState` + - `elytraRot*` -> `*Cloak` + - `clientLevel` is removed + - `getDeltaMovementLerped` -> `addWalkedDistance`, not one-to-one + - `updateBob` - Updates the bobbing motion of the camera. +- `net.minecraft.client.renderer` + - `EndFlashState` - The render state of the end flashes. + - `GameRenderer` now takes in the `BlockRenderDispatcher` + - `getSubmitNodeStorage` - Gets the node submission for feature-like objects. + - `getFeatureRenderDispatcher` - Gets the dispatcher for rendering feature-like objects. + - `getLevelRenderState` - Gets the render state of dynamic features in a level. + - `ItemInHandRenderer` + - `renderItem` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `renderHandsWithItems` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource$BufferSource` + - `LevelRenderer` now takes in the `LevelRenderState` and `FeatureRenderDispatcher` + - `getSectionRenderDispatcher` is now nullable + - `tickParticles` is removed + - `addParticle` is removed + - `MapRenderer` now takes in an `AtlasManager` instead of a `MapDecorationTextureManager` + - `render` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `OrderedSubmitNodeCollector` - A submission handler for holding elements to be drawn in a given order to the screen whenever the features are dispatched. + - `OutlineBufferSource` no longer takes in any parameters + - `setColor` now takes in a single integer + - `ParticleGroupRenderState` - The render state for a group of particles. + - `ParticlesRenderState` - The render state for all particles. + - `QuadParticleRenderState` - The render group state for all single quad particles. + - `RenderPipelines` + - `GUI_TEXT` - The pipeline for text in a gui. + - `GUI_TEXT_INTENSITY` - The pipeline for text intensity when not colored in a gui. + - `RenderStateShard#TRANSLUCENT_TARGET`, `PARTICLES_TARGET` are removed + - `RenderType` + - `pipeline` - The `RenderPipeline` the type uses. + - `opaqueParticle`, `translucentParticle` are removed + - `sunriseSunset`, `celestial` are removed + - `ScreenEffectRenderer` now takes in a `MaterialSet` + - `renderScreenEffect` now takes in a `SubmitNodeCollector` + - `ShapeRenderer` + - `renderLineBox` now takes in a `PoseStack$Pose` instead of a `PoseStack` + - `renderFace` now takes in a `Matrix4f` instead of a `PoseStack` + - `Sheets` + - `GUI_SHEET`, `MAP_DECORATIONS_SHEET`, `PAINTINGS_SHEET` - Atlas textures. + - `BLOCK_ENTITIES_MAPPER` - A mapper for block textures onto block entities. + - `*COPPER*` - Materials for copper chests. + - `chooseMaterial` now takes in a `ChestRenderState$ChestMaterialType` instead of a `BlockEntity` and `boolean` + - `SkyRenderer` + - `END_SKY_LOCATION` is now private + - `renderSunMoonAndStars` no longer takes in the buffer source + - `renderEndFlash` no longer takes in the buffer source + - `renderSunriseAndSunset` no longer takes in the buffer source + - `SpecialBlockModelRenderer` + - `vanilla` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `renderByBlock` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource`, and an outline color + - `SubmitNodeCollection` - An implementation of `OrderedSubmitNodeCollector` that holds the submitted features in separate lists. + - `SubmitNodeCollector` - An `OrderedSubmitNodeCollector` that provides a method to change the current order that an element will be rendered in. + - `SubmitNodeStorage` - A storage of collections held by some order. + - `SkyRenderer` + - `renderEndFlash` - Renders the end flashes. + - `initTextures` - Gets the texture for the used elements. + - `extractRenderState` - Extracts the `SkyRenderState` from the current level. + - `WeatherEffectRenderer` + - `render` now takes in the `WeatherRenderState` instead of an `int`, `float`, and `Level` + - Those fields have moved to `extractRenderState` + - `extractRenderState` - Extracts the `WeatherRenderState` from the current level. + - `$ColumnInstance` is now public + - `WorldBorderRenderer` + - `render` now takes in the `WorldBorderRenderState` instead of the `WorldBorder` + - `extract` - Extracts the `WorldBorderRenderState` from the current world border. +- `net.minecraft.client.renderer.block` + - `BlockRenderDispatcher` now takes in a `MaterialSet` + - `MovingBlockRenderState` - A render state for a moving block that implements `BlockAndTintGetter`. + - `LiquidBlockRenderer#setupSprites` now take in the `BlockModelShaper` and `MaterialSet` +- `net.minecraft.client.renderer.blockentity` + - Most methods here that take in the `MultiBufferSource` have been replaced by a `SubmitNodeCollector`, and a `ModelFeatureRenderer$CrumblingOverlay` if the method is not used for item rendering + - Most methods change their name from `render*` to `submit*`, with the main submit method now using a `BlockEntityRenderState` + - All `BlockEntityRenderer`s now have a `BlockEntityRenderState` generic + - `AbstractEndPortalRenderer` - A block entity renderer for the end portal. + - `AbstractSignRenderer` + - `getSignModel` now returns a `Model$Simple` + - `renderSign` -> `submitSign`, now takes in a `Model$Simple` and no longer takes in a tint color + - `BannerRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `renderPatterns` -> `submitPatterns` now takes in the `MaterialSet` and `ModelFeatureRenderer$CrumblingOverlay`, the `ModelPart` has been replaced with the `Model` and its render state, a `boolean` for whether to use the entity glint, and an outline color + - The overload with two additional `boolean`s has been removed + - `renderSpecial` -> `submitSpecial`, now takes in the outline color + - `BeaconRenderer#renderBeaconBeam` -> `submitBeaconBeam`, no longer takes in the game time `long` + - `BedRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `renderSpecial` -> `submitSpecial`, now takes in the outline color + - `BlockEntityRenderDispatcher` now takes in the `MaterialSet` and `PlayerSkinRenderCache` + - `render` -> `submit`, now takes in the `BlockEntityRenderState` instead of a `BlockEntity`, no longer takes in the partial tick `float`, and takes in the `CameraRenderState` + - `getRenderer` now has an overload that can get the renderer from its `BlockEntityRenderState` + - `tryExtractRenderState` - Gets the `BlockEntityRenderState` from its `BlockEntity` + - `level`, `camera`, `cameraHitResult` is removed + - `prepare` now only takes in the `Camera` + - `setLevel` is removed + - `BlockEntityRenderer` now has another generic `S` representing the `BlockEntityRenderState` + - `render` -> `submit`, taking in the `BlockEntityRenderState`, the `PoseStack`, the `SubmitNodeCollector`, and the `CameraRenderState` + - `createRenderState` - Creates the render state object. + - `extractRenderState` - Extracts the render state from the block entity. + - `BlockEntityRendererProvider$Context` is now a record, taking in a `MaterialSet` and `PlayerSkinRenderCache` + - It now has another generic `S` representing the `BlockEntityRenderState` + - `CopperGolemStatueBlockRenderer` - A block entity renderer for the copper golem statue. + - `DecoratedPotRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `render` overload -> `submit`, now takes in the outline color + - `HangingSignRenderer` + - `createSignModel` now returns a `Model$Simple` + - `renderInHand` now takes in a `MaterialSet` + - `ShelfRenderer` - A block entity renderer for a shelf. + - `ShulkerBoxRenderer` has an overload that takes in a `SpecialModelRenderer$BakingContext` + - The `EntityModelSet` constructor now takes in the `MaterialSet` + - `render` overload -> `submit`, now takes in the outline color + - `SignRenderer` + - `createSignModel` now returns a `Model$Simple` + - `renderInHand` now takes in a `MaterialSet` + - `SkullBlockRenderer#submitSkull` - Submits the skull model to the collector. + - `SpawnerRenderer#renderEntityInSpawner` -> `submitEntityInSpawner`, now takes in the `CameraRenderState` + - `TestInstanceREnderer` now takes in the `BlockEntityRendererProvider$Context` +- `net.minecraft.client.renderer.blockentity.state` + - `BannerRenderState` - The render state for the banner block entity. + - `BeaconRenderState` - The render state for the beacon block entity. + - `BedRenderState` - The render state for the bed block entity. + - `BellRenderState` - The render state for the bell block entity. + - `BlockEntityRenderState` - The base render state for all block entities. + - `BlockEntityWithBoundingBoxRenderState` - The render state for a block entity with a custom bounding box. + - `BrushableBlockRenderState` - The render state for a brushable block entity. + - `CampfireRenderState` - The render state for the campfire block entity. + - `ChestRenderState` - The render state for the chest block entity. + - `CondiutRenderState` - The render state for the conduit block entity. + - `CopperGolemStatueRenderState` - The render state for the copper golem block entity. + - `DecoratedPotRenderState` - The render state for the decorated pot block entity. + - `EnchantTableRenderState` - The render state for the enchantment table block entity. + - `EndGatewayRenderState` - The render state for the end gateway block entity. + - `EndPortalRenderState` - The render state for the end portal block entity. + - `LecternRenderState` - The render state for the lectern block entity. + - `PistonHeadRenderState` - The render state for the piston head block entity. + - `ShelfRenderState` - The render state for the shelf block entity. + - `ShulkerBoxRenderState` - The render state for the shulker box block entity. + - `SignRenderState` - The render state for the sign block entity. + - `SkullBlockRenderState` - The render state for the skull block entity. + - `SpawnerRenderState` - The render state for the spawner block entity. + - `TestInstanceRenderState` - The render state for the test instance block entity. + - `VaultRenderState` - The render state for the vault block entity. +- `net.minecraft.client.renderer.culling.Frustum` + - `offset` - Offsets the position. + - `pointInFrustum` - Checks whether the provided coordinate is within the frustum. +- `net.minecraft.client.renderer.entity` + - Most methods here that take in the `MultiBufferSource` and light coordinates integer have been replaced by `SubmitNodeCollector` and a render state param + - Most methods change their name from `render*` to `submit*` + - `AbstractBoatRenderer#renderTypeAdditions` -> `submitTypeAdditions` + - `AbstractMinecartRenderer#renderMinecartContents` -> `submitMinecartContents` + - `AbstractSkeletonRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `AbstractZombieRenderer` takes in a `ArmorModelSet` instead of a model + - `ArmorModelSet` - A holder that maps some object to each humanoid armor slot. Typically holds the layer definitions, which are then baked into their associated models. + - `BreezeRenderer#enable` is removed + - `CopperGolemRenderer` - The renderer for the copper golem entity. + - `DisplayRenderer#renderInner` -> `submitInner` + - `EnderDragonRenderer#renderCrystalBeams` -> `submitCrystalBeams` + - `EntityRenderDispatcher` now takes in the `AtlasManager` + - `prepare` no longer takes in the `Level` + - `setRenderShadow`, `setRenderHitBoxes`, `shouldRenderHitBoxes` are removed + - `extractEntity` - Creates the render state from the entity and the partial tick. + - `render` -> `submit`, now takes in the `CameraRenderState` + - `setLevel` -> `resetCamera`, not one-to-one + - `getPlayerRenderer` - Gets the `AvatarRenderer` from the given client player. + - `overrideCameraOrientation`, `distanceToSqr`, `cameraOrientation` are removed + - `EntityRenderer` + - `NAMETAG_SCALE` is now public + - `render(S, PoseStack, MultiBufferSource, int)` -> `submit(S, PoseStack, SubmitNodeCollector, CameraRenderState)` + - `renderNameTag` -> `submitNameTag`, now takes in a `CameraRenderState` + - `finalizeRenderState` - Extracts the information of the render state as a last step after `extractRenderState`, such as shadows. + - `EntityRendererProvider$Context` now takes in the `PlayerSkinRenderCache` and `AtlasManager` + - `getModelManager` is removed + - `getMaterials` - Returns a mapper of material to atlas sprite. + - `getPlayerSkinRenderCache` - Gets the render cache of player skins. + - `getAtlas` - Returns the atlas for that location. + - `EntityRenderers#createPlayerRenderers` now returns a map of `PlayerModelType`s to `AvatarRenderer`s + - `ItemEntityRenderer` + - `renderMultipleFromCount` -> `submitMultipleFromCount` + - `renderMultipleFromCount(PoseStack, MultiBufferSource, int, ItemClusterRenderState, RandomSource)` -> `renderMultipleFromCount(PoseStack, SubmitNodeCollector, int, ItemClusterRenderState, RandomSource)` + - `ItemRenderer` no longer takes in the `ItemModelResolver` + - `getArmorFoilBuffer` -> `getFoilRenderTypes`, not one-to-one + - `renderStatic` methods are removed + - `MobRenderer#checkMagicName` - Returns whether the custom name matches the given string. + - `PiglinRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `TntMinecartRenderer#renderWhiteSolidBlock` -> `submitWhiteSolidBlock`, now takes in an outline color + - `ZombieRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` + - `ZombifiedPiglinPiglinRenderer` takes in a `ArmorModelSet` instead of a `ModelLayerLocation` +- `net.minecraft.client.renderer.entity.layers` + - `ArrowLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `BeeStingerLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `BlockDecorationLayer` - A layer that handles a block model transformed by an entity. + - `BreezeWindLayer` now takes in the `EntityModelSet` instead of the `EntityRendererProvider$Context` + - `CapeLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `CustomHeadLayer` now takes in the `PlayerSkinRenderCache` + - `Deadmau5EarsLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `EquipmentLayerRenderer#renderLayers` now takes in the render state, `SubmitNodeCollector`, outline color, and an initial order instead of a `MultiBufferSource` + - `HumanoidArmorLayer` now takes in `ArmorModelSet`s instead of models + - `setPartVisibility` is removed + - `ItemInHandLayer#renderArmWithItem` -> `submitArmWithItem` + - `LivingEntityEmissiveLayer` now takes in a function for the texture instead of a `ResourceLocation` and a model instead of the `$DrawSelector` + - `$DrawSelector` is removed + - `ParrotOnShoulderLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `PlayerItemInHandLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `RenderLayer` + - `renderColoredCutoutModel`, `coloredCutoutModelCopyLayerRender` now takes in a `Model` instead of an `EntityModel`, a `SubmitNodeCollector` instead of a `MultiBufferSource`, and an integer representing the order layer for rendering + - `render` -> `submit`, taking in a `SubmitNodeCollector` instead of a `MultiBufferSource` + - `SimpleEquipmentLayer` now takes in an order integer + - `SpinAttackEffectLayer` now deals with `AvatarRenderState` instead of `PlayerRenderState` + - `StuckInBodyLayer` now has an additional generic for the render state, also taking in the render state in the constructor + - `numStuck` now takes in an `AvatarRenderState` instead of the `PlayerRenderState` + - `VillagerProfessionLayer` now takes in two models +- `net.minecraft.client.renderer.entity.player.PlayerRenderer` -> `AvatarRenderer` + - `render*Hand` now takes in a `SubmitNodeCollector` instead of a `MultiBufferSource` +- `net.minecraft.client.renderer.entity.state` + - `CopperGolemRenderState` - The render state for the copper golem entity. + - `DisplayEntityRenderState#cameraYRot`, `cameraXRot` - The rotation of the camera. + - `EntityRenderState` + - `NO_OUTLINE` - A constant that represents the color for no outline. + - `outlineColor` - The outline color of the entity. + - `lightCoords` - The packed light coordinates used to light the entity. + - `shadowPieces`, `$ShadowPiece` - Represents the relative coordinates of the shadow(s) the entity is casting. + - `FallingBlockRenderState` fields and implementations have all been moved to `MovingBlockRenderState` + - `LivingEntityRenderState` + - `appearsGlowing` -> `EntityRenderState#appearsGlowing`, now a method + - `customName` is removed + - `PaintingRenderState#lightCoords` -> `lightCoordsPerBlock` + - `PlayerRenderState` -> `AvatarRenderState` + - `useItemRemainingTicks`, `swinging` are removed + - `showDeadMouseEars` -> `showExtraEars` + - `SheepRenderState` + - `id` is removed + - `isJebSheep` is now a field instead of a method + - `WitherSkullRenderState#xRot`, `yRot` -> `modeState`, not one-to-one +- `net.minecraft.client.renderer.feature` + - `BlockFeatureRenderer` - Renders the submitted blocks, block models, or falling blocks. + - `CustomFeatureRenderer` - Renders the submitted geometry via a passed function. + - `FeatureRenderDispatcher` - Dispatches all features to render from the submitted node collector objects. + - `FlameFeatureRenderer` - Renders the submitted entity on fire animation. + - `HitboxFeatureRenderer` - Renders the submitted entity hitbox. + - `ItemFeatureRenderer` - Renders the submitted items. + - `LeashFeatureRenderer` - Renders the submitted leash attached to entities. + - `ModelFeatureRenderer` - Renders the submitted `Model`s. + - `ModelPartFeatureRenderer` - Renders the submitted `ModelPart`s. + - `NameTagFeatureRenderer` - Renders the submitted name tags. + - `ParticleFeatureRenderer` - Renders the submitted particles. + - `ShadowFeatureRenderer` - Render the submitted entity shadow. + - `TextFeatureRenderer` - Renders the submitted text. +- `net.minecraft.client.renderer.item` + - `ItemModel$BakingContext` now takes in a `MaterialSet` and `PlayerSkinRenderCache`, and implements `SpecialModelRenderer$BakingContext` + - `ItemStackRenderState#render` -> `submit`, taking in a `SubmitNodeCollector` instead of a `MultiBufferSource` and an outline color +- `net.minecraft.client.renderer.special` + - Most methods here that take in the `MultiBufferSource` have been replaced by `SubmitNodeCollector` + - `ChestSpecialRenderer` now takes in a `MaterialSet` + - `*COPPER*` - Textures for the copper chest. + - `ConduitSpecialRenderer` now takes in a `MaterialSet` + - `CopperGolemStatueSpecialRenderer` - A special renderer for the copper golem statue as an item. + - `HangingSignSpecialRenderer` now takes in a `MaterialSet` and a `Model$Simple` instead of a `Model` + - `NoDataSpecialModelRenderer#render` -> `submit`, now takes in an outline color + - `PlayerHeadSpecialRenderer` now takes in the `PlayerSkinRenderCache` + - `ShieldSpecialRenderer` now takes in a `MaterialSet` + - `SpecialModelRenderer` + - `render` -> `submit`, now takes in an outline color + - `$BakingContext` - The context used to bake a special item model. + - `$Unbaked#bake` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `SpecialModelRenderers#createBlockRenderers` now takes in a `SpecialModelRenderer$BakingContext` instead of an `EntityModelSet` + - `StandingSignSpecialRenderer` now takes in a `MaterialSet` and a `Model$Simple` instead of a `Model` +- `net.minecraft.client.renderer.state` + - `BlockBreakingRenderState` - The render state for how far the current block has been broken. + - `BlockOutlineRenderState` - The render state for the outline of a block via its `VoxelShape`s. + - `CameraRenderState` - The render state of the camera. + - `LevelRenderState` - The render state of the dynamic features in a level. + - `ParticleGroupRenderState` - The render state for a group of particles. + - `ParticlesRenderState` - The render state for all particles. + - `QuadParticleRenderState` - The render group state for all single quad particles. + - `SkyRenderState` - The render state of the sky, including the moon and stars. + - `WeatherRenderState` - The render state of the current weather. + - `WorldBorderRenderState` - The render state of the world border. +- `net.minecraft.client.renderer.texture` + - `SkinTextureDownloader` is now an instance class rather than a static method holder, taking in a `Proxy`, `TextureManager`, and the main thread `Executor` + - Most methods that were previously static are now instance methods + - `SpriteContents` now takes in an optional `AnimationMetadataSection` and `MetadataSectionType$WithValue` list instead of a `ResourceMetadata` + - `metadata` -> `getAdditionalMetadata`, not one-to-one + - `SpriteLoader` + - `DEFAULT_METADATA_SECTIONS` is removed + - `stitch` is now private + - `runSpriteSuppliers` is now private + - `loadAndStitch(ResourceManager, ResourceLocation, int, Executor)` isn removed + - `loadAndStitch` now takes a set of `MetadataSectionType`s instead of a collection + - `$Preparations` + - `waitForUpload` is removed + - `getSprite` - Returns the atlas sprite for a given resource location. + - `TextureAtlasSprite#isAnimated` -> `SpriteContents#isAnimated` +- `net.minecraft.client.renderer.texture.atlas.SpriteResourceLoader#create` now takes a set of `MetadataSectionType`s instead of a collection +- `net.minecraft.client.resources` + - `MapDecorationTextureManager` class is removed + - `PaintingTextureManager` class is removed + - `PlayerSkin$Model` -> `PlayerModelType`, not one-to-one + - The constructor not takes in the legacy service name + - `byName` -> `byLegacyServicesName` + - `SkinManager` now takes in `Services` instead of a `MinecraftSessionService`, and a `SkinTextureDownloader` + - `lookupInsecure` -> `createLookup`, now taking in a boolean of whether to check for insecure skins + - `getOrLoad` -> `get` + - `TextureAtlasHolder` class is removed +- `net.minecraft.client.resources.model` + - `AtlasIds` -> `net.minecraft.data.AtlasIds` + - `AtlasSet` -> `AtlasManager`, not one-to-one + - `forEach` - Iterates through each of the atlas sheets. + - `Material` + - `sprite` -> `MaterialSet#get` + - `buffer` now takes in a `MaterialSet` + - `MaterialSet` - A map of material to its atlas sprite. + - `ModelBakery` now takes in a `MaterialSet` and `PlayerSkinRenderCache` + - `ModelManager` is no longer `AutoCloseable` + - The constructor takes in the `PlayerSkinRenderCache`, `AtlasManager` instead of the `TextureManager`, and the max mipmap levels integer + - `getAtlas` -> `MaterialSet#get` + - `updateMaxMipLevel` -> `AtlasManager#updateMaxMipLevel` +- `net.minecraft.core.particles` + - `ParticleGroup` -> `ParticleLimit` + - `ParticleTypes` + - `DRAGON_BREATH` now uses a `PowerParticleOption` + - `EFFECT` now uses a `SpellParticleOption` + - `FLASH` now uses a `ColorParticleOption` + - `INSTANT_EFFECT` now uses a `SpellParticleOption` + - `PowerParticleOption` - A particle option for the dragon's breath. + - `SpellParticleOption` - A particle option for potion effects. + +### The Font Glyph Pipeline + +Glyphs have been partially reworked in the backend to both unify both characters and their effects to a single renderable and add a baking flow, albeit delayed. This will provide a brief overview of this new flow. + +Let's start from the top when the assets are reloaded, causing the `FontManager` to run. The font definitions are loaded and passed to their appropriate `GlyphProviderDefinition`, which for this example with immediately unpack into a `GlyphProvider$Loader`. The loader reads whatever information it needs (most likely a texture) and maps it to an associated codepoint as an `UnbakedGlyph`. An `UnbakedGlyph` represents a single character containing its `GlyphInfo` with the position metadata and a `bake` method to write it to a texture. `bake` takes in a `UnbakedGlyph$Stitcher`, which itself takes in a `GlyphBitmap` to correctly position and upload the glyph along with the `GlyphInfo` for any offset adjustments. Then, after and resolving and finalizing, the `FontSet`s are created using `FontSet#reload`. This resets the textures and cache and calls `FontSet#selectProviders` to store the active list of `GlyphProvider`s and populates the `glyphsByWidth` by mapping the character advance to a list of matching codepoints. At this point, all of the loading has been done. While the glyphs are stored in their unbaked format, they are not baked and cached until that specific character is rendered. + +Now, let's move onto the `FontDescription`. A `FontDescription` provides a one-to-one map to a `GlyphSource`, which is responsible for obtaining the glyphs. Vanilla provides three `FontDescription`s: `$Resource` for mapping to the `FontSet` (the font JSON name) as mentioned above, `$AtlasSprite` to interpret an atlas as a bunch of glyphs, and `$PlayerSprite` for rendering the player head and hat. For a given `Component`, the `FontDescription` used can be set as its `Style` via `Style#withFont`. + +So, let's assume you are drawing text to the screen using `FontDescription#DEFAULT`, which uses the defined `assets/minecraft/font/default.json`. Eventually, this will either call `Font#drawInBatch` or `drawInBatch8xOutline`. Then, whether through the `StringSplitter` or directly, the `GlyphSource` is obtained from the `FontDescription`. Then, `GlyphSource#getGlyph` is called. For the `FontDescription$AtlasSprite` and `$PlayerSprite`, this just returns a wrapper around the texture in question. For the `$Resource` though, this internally calls `FontSet#getGlyph`, which stores the `UnbakedGlyph` as part of a `FontSet$DelayedBake`, which it then immediately resolves to the `BakedGlyph` by calling `UnbakedGlyph#bake` to write the glyph to some texture. + +A `BakedGlyph` contains two methods: the `GlyphInfo` for the position metadata like before, and a method called `createGlyph`, which returns a `TextRenderable`: a renderer to draw the glyph to the screen. `TextRenderable` also has a subinterface called `PlainTextRenderable` for help with texture sprites. Internally, all resource `BakedGlyph`s are `BakedSheetGlyph`s, as the `UnbakedGlyph$Stitcher#stitch` called just wraps around `GlyphStitcher#stitch`. You can think of the `BakedSheetGlyph` as a view onto a 256x256 `FontTexture`s, where if there is not enough space on one `FontTexture`, then a new `FontTexture` is created. + +`BakedSheetGlyph` also implements `EffectGlyph`, which is likely supposed to render some sort of effect on the text. This functionality, while it is currently implemented as just another object, is only used for the white glyph, which goes unused. + +#### Object Info + +`ObjectInfo`s are the server side implementations to construct the `FontDescription` used to render an arbitrary object through the glyph pipeline. Each info takes in the `FontDescription` and a regular `String` to display a simple description. Additionally, it takes in a `MapCodec` to encode and decode from the object contents. + +Note that for custom `FontDescription`s to map to a source properly, you will need to somehow modify `FontManager$CachedFontProvider#getGlyphSource` or implement a custom `Font$Provider`. + +```java +// A basic font description +public static record BlockDescription(Block block) implements FontDescription {} + +// A simple object info +public record BlockInfo(Block block) implements ObjectInfo { + // The codec to send the information over the network + public static final MapCodec MAP_CODEC = BuiltInRegistries.BLOCK.byNameCodec().fieldOf("block"); + + @Override + public FontDescription fontDescription() { + // The font description to render + return new BlockDescription(this.block); + } + + @Override + public String description() { + // Just a text description of the object + return Objects.toString(BuiltInRegistries.BLOCK.getKey(this.block)); + } + + @Override + public MapCodec codec() { + return MAP_CODEC; + } +} + +// Create the `GlyphSource` and `PlainTextRenderable` used to render the object +public record BlockRenderable(...) implements PlainTextRenderable { + // ... +} + +public static GlyphSource create(Block block) { + return new SingleSpriteSource(...); +} +``` + +The `ObjectInfo` also needs to be rendered to `ObjectInfos#ID_MAPPER`: + +```java +// Assumes the the mapper has been made public +ObjectInfos.ID_MAPPER.put("examplemod:block", BlockInfo.MAP_CODEC); +``` + +#### Component Contents + +Component contents also now use an id mapper instead of holding the id on the type. This means that creating a custom component is done by somehow hooking into `ComponentSerialization#bootstrap` and registering the map codec of your `ComponentContents` implementation to the mapper. + +#### Data Sources + +Data sources has received a similar treatment to component contents, now using an id mapper instead of holding the id on the type. The data source is then registered by registering to `DataSources#ID_MAPPER` the map codec of your `DataSource`. Note that the mapper field is private, so you will probably need to use an available workaround. + +- `com.mojang.blaze3d.font` + - `GlyphInfo` + - `bake` -> `UnbakedGlyph#bake`, now takes in a `UnbakedGlyph$Stitcher` instead of a function + - The function behavior is replaced by `UnbakedGlyph$Stitcher#stitch` + - `$SpaceGlyphInfo` -> `GlyphInfo#simple` and `EmptyGlyph`, not one-to-one + - `$Stitched` -> `UnbakedGlyph`, not one-to-one + - `GlyphProvider#getGlyph` now returns an `UnbakedGlyph` + - `SheetGlyphInfo` -> `GlyphBitmap` +- `net.minecraft.client.gui` + - `Font` no longer takes in a function and boolean, instead a `Font$Provider` + - `random` is now private + - `$GlyphVisitor` + - `acceptGlyph` now takes in a `TextRenderable` instead of a `BakedGlyph$GlyphInstance` + - `acceptEffect` now only takes in a `TextRenderable` + - `$PreparedTextBuilder#accept` now has an override that takes in a `BakedGlyph` instead of its codepoint + - `$Provider` - A simple interface for providing the glyph source based on its description, along with the empty glyph. + - `GlyphSource` - An interface that holds the baked glyphs based on its codepoint. +- `net.minecraft.client.gui.font` + - `AtlasGlyphProvider` - A glyph provider based off a texture atlas. + - `FontManager` now takes in the `AtlasManager` and `PlayerSkinRenderCache` + - `FontSet` now takes in a `GlyphStitcher` instead of a `TextureManager` and no longer takes in the name + - `name` is removed + - `source` - Returns the glyph source depending given whether only non-fishy glyphs should be seen. + - `getGlyphInfo`, `getGlyph` -> `getGlyph`, now package-private, not one-to-one + - `getRandomGlyph` now takes in a `RandomSource` and a codepoint instead of the `GlyphInfo`, returning a `BakedGlyph` + - `whiteGlyph` now returns an `EffectGlyph` + - `$GlyphSource` - A source that can get the glyphs to bake. + - `FontTexture#add` now takes in a `GlyphInfo` and `GlyphBitmap`, returning a `BakedSheetGlyph` + - `GlyphStitcher` - A class that creates `BakedGlyph`s from its glyph information. + - `PlainTextRenderable` - An implementation of `TextRenderable` that determines how a sprite is rendered. + - `PlayerGlyphProvider` - A glyph provider for rendering the player head and hat. + - `SingleSpriteSource` - A glyph source that only contains one glyph, such as a texture. + - `TextRenderable` - Represents how a text representation, like a glyph in a font, is rendered. +- `net.minecraft.client.gui.font.glyphs` + - `BakedGlyph` is now an interface that creates the renderable object + - It original purpose has been moved to `BakedSheetGlyph` + - `EffectGlyph` - An interface that creates the renderable effect of some glyph. + - `EmptyGlyph` now implements `UnbakedGlyph` instead of extending `BakedGlyph` + - The constructor takes in the text advance of the glyph. + - `SpecialGlyphs#bake` now returns a `BakedSheetGlyph` + - This method is technically new. +- `net.minecraft.client.gui.font.providers` + - `BitmapProvider$Glyph` now implements `UnbakedGlyph` instead of `GlyphInfo$Stitched` + - `UnihexProvider$Glyph` now implements `UnbakedGlyph` instead of `GlyphInfo$Stitched` +- `net.minecraft.client.gui.render.state` + - `GlyphEffectRenderState` is removed + - Use `GlyphRenderState` + - `GlyphRenderState` now takes in a `TextRenderable` instead of a `BakedGlyph$Instance` +- `net.minecraft.network.chat` + - `Component#object` - Creates a mutable component with object contents. + - `ComponentContents#type` -> `codec`, dropping the string id + - `$Type` is removed + - `ComponentSerialization` + - `createLegacyComponentMatcher` no longer requires a `StringRepresentable` generic, instead taking in a id mapper using `String` keys + - `$FuzzyCodec` now takes in a collection of map codecs instead of a list + - `FontDescription` - An identifier that describes a font, typically as a location or sprite. + - `Style` is now final + - `getFont` now returns a `FontDescription` + - `withFont` now takes in a `FontDescription` instead of a `ResourceLocation` + - `DEFAULT_FONT` is removed +- `net.minecraft.network.chat.contents` + - `BlockDataSource` -> `.data.BlockDataSource` + - `DataSource` -> `.data.DataSource` + - `type` -> `codec`, dropping the string id + - `EntityDataSource` -> `.data.EntityDataSource` + - `*Contents` + - `CODEC` -> `MAP_CODEC` + - `TYPE` is removed + - `ObjectContents` - An arbitrary piece of content that can be written as part of a component, like a sprite. + - `StorageDataSource` -> `.data.StorageDataSource` +- `net.minecraft.network.chat.contents.data.DataSources` - All vanilla-registered data sources. +- `net.minecraft.network.chat.contents.objects` + - `AtlasSprite` - An object info for a sprite in a texture atlas. + - `ObjectInfo` - Information relating the references for an arbitrary object through the glyph pipeline. + - `ObjectInfos` - All vanilla object infos. + - `PlayerSprite` - An object info for a player head and hat texture. + +### The JSON-RPC Management Servers + +Minecraft has introduced support for remotely managing dedicated servers through a JSON-RPC websocket. This can be enabled through the `management-server-enabled` property, which listens for a server on `localhost:25585` by default. The entire system handles not only constructing the network requests sent via `JsonElement`s, but also the schemas each request uses. These schemas can then be generated through the `JsonRpcApiSchema` data provider. + +There are two types of RPC methods supported by the system: `IncomingRpcMethod`s for requests from the management server, and `OutgoingRpcMethod`s to either notify or request information from the management server. Both of these are static registry objects, but rather than implementing the interfaces, they are typically constructed and registered through their associated builders. + +#### Schemas + +`Schema`s, as the name implies, are the specification of the JSON objects. They are constructed in a similar fashion `JsonElement`s. Most are constructed as `Schema#record`s, with their field and types being populated via `withField`, before being stored in a `SchemaComponent`, which maps a reference name to the schema. Then the `Schema`s can be obtained via `asRef` or `asArray` to get the object or array implementation, respectively. The `SchemaComponent`s themselves and registered to the list `Schema#SCHEMA_REGISTRY` for reference resolving. + +```json5 +// An example json for changing the weather: +{ + "weather": "clear|rain|thunder", + "duration": -1, +} +``` + +Here is what the associated schema component would look like: + +```java +public static final SchemaComponent WEATHER_SCHEMA = new SchemaComponent( + // The reference name + // While we can use colon, it would need to be percent encoded as defined by RFC 3986 + "examplemod_weather", + // The schema to use + Schema.record() + .withField("weather", Schema.ofEnum(List.of("clear", "rain", "thunder"))) + .withField("duration", Schema.INT_SCHEMA) +); + +// Register the schema to the registry +Schema.getSchemaRegistry().add(WEATHER_SCHEMA); +``` + +Note that schemas currently cannot specify whether an individual property is optional or not. + +#### `IncomingRpcMethod` + +`IncomingRpcMethod`s are constructed and registered through the `method` builder. These methods take in the handler function to update the minecraft server, a codec for the result, and an optional codec for the parameters sent from the management server. From there, the builder contains methods towards the discovery service and how to execute the method. `$IncomingRpcMethodBuilder#response` and `param` define the parameters and response sent by the management server. `description` is used by the discovery service for the schemas. `undiscoverable` hides the route by default. Finally, `notOnMainThread` tells the method that it can run off the main thread. Once the desired methods are called, then either `build` or `register` can be used to construct the object, taking in the route endpoint as a namespace and path. + +The methods passed in take in the `MinecraftApi` for communicating with the dedicated server through specified 'services', and the current `ClientInfo` connection. It also takes in the parameter object if it exists. + +```java +// Construct the dto object +public record WeatherDto(String weather, int duration) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.STRING.fieldOf("weather").forGetter(WeatherDto::weather), + Codec.INT.fieldOf("duration").forGetter(WeatherDto::duration), + ) + .apply(instance, WeatherDto::new) + ); + + // Create the incoming method handler + public static WeatherDto handleWeather(MinecraftApi api, WeatherDto params, ClientInfo info) { + // Note that the api makes the server private since it expects the + // logic to be handled through one of the middle layer services. + // We will assume the `server` field was made public somehow. + if (params.weather().equals("clear")) { + api.server.overworld().setWeatherParameters(params.duration(), 0, false, false); + } else if (params.weather().equals("rain")) { + api.server.overworld().setWeatherParameters(0, params.duration(), true, false); + } else if (params.weather().equals("thunder")) { + api.server.overworld().setWeatherParameters(0, params.duration(), true, true); + } + + return params; + } +} + +// Construct and register the method endpoint +IncomingRpcMethod.method( + // The handler method + WeatherDto::handleWeather, + // The codec for the parameters + WeatherDto.CODEC, + // The codec for the result + WeatherDto.CODEC +) + // Sets the description of the route + .description("Sets the weather") + // The parameters + .param(new ParamInfo( + // The name of the object + "weather", + // The schema + WEATHER_SCHEMA.asRef() + )) + // The response + .response(new ResultInfo( + // The name of the object + "weather", + // The schema + WEATHER_SCHEMA.asRef() + )) + // Build and register the route + .register( + BuiltInRegistries.INCOMING_RPC_METHOD, + // The endpoint namespace + "examplemod", + // The endpoint path + "weather/update" + ); +``` + +#### `OutgoingRpcMethod` + +`OutgoingRpcMethod`s are constructed and registered through the `notification` or `request` builder. Notifications typically only send parameters with no returned result, while requests provide a result as well. In either case, they just take in codecs for the params or result when present. `$OutgoingRpcMethod#response` and `param` define the parameters and response sent by the minecraft server. `description` is used by the discovery service for the schemas. Once the desired methods are called, then `register` can be used to construct the object, taking in the route endpoint as a namespace and path and wrapping it in a `Holder$Reference`. + +Currently, vanilla only broadcasts notifications through the `NotificationService`: a remote logger for specific method actions, like player join or changing game rule. While there are results, they must be read via `Connection#sendRequest` and handled asynchronously. + +```java +// Construct the outgoing method +// Since the minecraft server will be sending these, we need to hold the object +public static final Holder.Reference SOMETHING_HAPPENED = OutgoingRpcMethod.notification() + .description("Something happened!") + .register("examplemod", "something"); + +// Send notification, assume we have access to the `ManagementServer` managementServer +managementServer.forEachConnection(connection -> connection.sendNotification(SOMETHING_HAPPENED)); +``` + +- `net.minecraft.SharedConstants#RPC_MANAGEMENT_SERVER_API_VERSION` - The API version for JSON RPC server management. +- `net.minecraft.core.registries` + - `BuiltInRegistries`, `Registries` + - `INCOMING_RPC_METHOD` - Registry for queries to the RPC service. + - `OUTGOING_RPC_METHOD` - Registry for broadcasts from the RPC service. +- `net.minecraft.server` + - `MinecraftServer` + - `notificationManager` - Returns the current notification manager. + - `onGameRuleChanged` - Handles what happens when the game rule of the current server changes. + - `getOperatorUserPermissionLevel` -> `operatorUserPermissionLevel` + - `isLevelEnabled` -> `isAllowedToEnterPortal`, not one-to-one + - `setPvpAllowed` replaced by `GameRules#RULE_PVP` + - `setFlightAllowed` replaced by `DedicatedServerProperties#allowFlight` + - `isCommandBlockEnabled` is no longer abstract + - `isSpawnerBlockEnabled` - Returns whether spawner blocks can spawn entities. + - `getPlayerIdleTimeout` -> `playerIdleTimeout` + - `kickUnlistedPlayers` no longer takes in the `CommandSourceStack` + - `pauseWhileEmptySeconds` -> `pauseWhenEmptySeconds` + - `getSpawnProtectionRadius` -> `DedicatedServer#spawnProtectionRadius` + - `isUsingWhiteList` - Handles enabling whitelist users for the server. + - `setAutoSave`, `isAutoSave` - Handles whether the server should auto save every so often. +- `net.minecraft.server.dedicated` + - `DedicatedServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` + - `setAllowFlight` - Sets whether the players can fly in the server. + - `setDifficulty` - Sets the game difficulty of the server. + - `viewDistance`, `setViewDistance` - Handles the view distance of the server (renderable chunks). + - `simulationDistance`, `setSimulationDistance` - Handles the simulation distance of the server (logic running chunks). + - `setMaxPlayers` - Sets the maximum number of players that can join the server. + - `setSpawnProtectionRadius` - Sets the radius of chunks that should be under spawn protection. + - `setRepliesToStatus` - Sets whether the game uses the legacy query handler. + - `setHidesOnlinePlayers` - Sets whether online players should be hidden from other players. + - `setOperatorUserPermissionLevel` - Sets the permission level of operator users. + - `statusHeartbeatInterval`, `setStatusHeartbeatInterval` - Handles the interval that the management server will check the minecraft server is still alive. + - `entityBroadcastRangePercentage`, `setEntityBroadcastRangePercentage` - Handles the broadcast range scalar for entity tracking. + - `forceGameMode`, `setForceGameMode` - Handles forcing all game modes for the users. + - `gameMode`, `setGameMode` - Sets the default game mode of the server. + - `setAcceptsTransfers` - Sets whether the server accepts client transfers from other servers. + - `setPauseWhenEmptySeconds` - Sets the number of seconds that the server should wait until it stops ticking when there are no players. + - `DedicatedServerProperties` + - `pvp` replaced by `GameRules#RULE_PVP` + - `allowFlight`, `motd`, `forceGameMode`, `enforceWhitelist`, `difficulty`, `gameMode`, `spawnProtection`, `opPermissionLevel`, `viewDistance`, `simulationDistance`, `enableStatus`, `hideOnlinePlayers`, `entityBroadcastRangePercentage`, `pauseWhenEmptySeconds`, `acceptsTransfers` are now mutable properties + - `allowNether` replaced by `GameRules#RULE_ALLOW_NETHER` + - `spawnMonsters` replaced by `GameRules#RULE_SPAWN_MONSTERS` + - `enabledCommandBlock` replaced by `GameRules#RULE_COMMAND_BLOCKS_ENABLED` + - `managementServerEnabled` - Returns whether a management server is enabled. + - `managementServerHost` - Returns the host the management server is communicating on. + - `managementServerPort` - Returns the port the management server is communicating on. + - `statusHeartbeatInterval` - Returns the heartbeat interval the management server sends to make sure the minecraft server is still alive. + - `MANAGEMENT_SERVER_TLS_ENABLED_KEY`, `MANAGEMENT_SERVER_TLS_KEYSTORE_KEY`, `MANAGEMENT_SERVER_TLS_KEYSTORE_PASSWORD_KEY` - TLS keystore setup for communication with the management server. + - `managementServerSecret` - The authorization token secret. + - `managementServerTlsEnabled` - If TLS should be used as the communication protocol. + - `managementServerTlsKeystore` - Specifies the filepath used for the TLS keystore. + - `managementServerTlsKeystorePassword` - Specifies the password for the keystore file. + - `Settings#getMutable` - Gets a mutable property for the settings key and default. +- `net.minecraft.server.jsonrpc` + - `Connection` - The inbound handler for json elements sent by the management server. + - `IncomingRpcMethod` - A definition and handler for the incoming message sent by the management server. + - `IncomingRpcMethods` - All vanilla incoming RPC handlers. + - `JsonRPCErrors` - An enum of errors that can be thrown when attempting to read, parse, or execute the method. + - `JsonRpcLogger` - A general logger for things performed by the minecraft server, whether communication or logic. + - `JsonRpcNotificationService` - A notification service that broadcasts to all connected minecraft servers. + - `JsonRPCUtils` - A utility for request objects and errors. + - `ManagementServer` - A basic websocket comms for the minecraft server to communicate with the management server. + - `OutgoingRpcMethod` - A definition and handler for outgoing requests to the management server. + - `OutgoingRpcMethods` - All vanilla outgoing RPC handlers. + - `PendingRpcRequest` - A pending request made by the minecraft server to the management server. +- `net.minecraft.server.jsonrpc.api` + - `MethodInfo` - Defines a method that is handled by the management server, either inbound or outbound. + - `ParamInfo` - Defines the parameters a specific method takes in. + - `PlayerDto` - A data transfer object representing the player. + - `ReferenceUtil` - A utility for creating a local reference URI. + - `ResultInfo` - Defines the response a specific method returns. + - `Schema` - An implementation of the json schema used the discovery service, parameters, and results. + - `SchemaComponent` - A reference definition of some component within a schema. +- `net.minecraft.server.jsonrpc.dataprovider.JsonRpcApiSchema` - A data provider that generates the json schema from the discovery service. +- `net.minecraft.server.jsonrpc.internalapi` + - `GameRules` - An api that gets the current game rule value. + - `MinecraftAllowListService` - A minecraft middle layer that handles communication from the management server about the allow list. + - `MinecraftAllowListServiceImpl` - The allow list implementation. + - `MinecraftApi` - A minecraft api that handles all the services that communicate with the management server. + - `MinecraftBanListService` - A minecraft middle layer that handles communication from the management server about the ban list. + - `MinecraftBanListServiceImpl` - The ban list implementation. + - `MinecraftExecutorService` - A minecraft middle layer that submits an arbitrary runnable or supplier to execute on the server. + - `MinecraftExecutorServiceImpl` - The executor implementation. + - `MinecraftGameRuleService` - A minecraft middle layer that handles communication from the management server about the game rules. + - `MinecraftExecutorServiceImpl` - The executor implementation. + - `MinecraftOperatorListService` - A minecraft middle layer that handles communication from the management server about the operator commands. + - `MinecraftOperatorListServiceImpl` - The operator list implementation. + - `MinecraftPlayerListService` - A minecraft middle layer that handles communication from the management server about the player list. + - `MinecraftPlayerListServiceImpl` - The player list implementation. + - `MinecraftServerSettingsService` - A minecraft middle layer that handles communication from the management server about the server settings. + - `MinecraftServerSettingsServiceImpl` - The server settings implementation. + - `MinecraftServerStateService` - A minecraft middle layer that handles communication from the management server about the current server state and send messages. + - `MinecraftServerStateServiceImpl` - The server state implementation. +- `net.minecraft.server.jsonrpc.methods` + - `AllowlistService` - A service that handles communication from the management server about the allow list. + - `BanlistService` - A service that handles communication from the management server about the player ban list. + - `ClientInfo` - An identifier for the current minecraft server connection to the management server. + - `DiscoveryService` - A service that displays the schemas of all services supported by the management server. + - `EncodeJsonRpcException` - An exception thrown when attempting to encode the json packet. + - `GameRulesService` - A service that handles communication from the management server about the game rules. + - `IllegalMethodDefinitionException` - An exception thrown when the method definition provided is illegal. + - `InvalidParameterJsonRpcException` - An exception thrown when the parameters to the method are invalid. + - `InvalidRequestJsonRpcException` - An exception thrown when the request is invalid. + - `IpBanlistService` - A service that handles communication from the management server about the ip ban list. + - `Message` - A data transfer object representing a literal or translatable component. + - `MethodNotFoundJsonRpcException` - An exception thrown when a 404 error occurs, indicating that the method doesn't exist. + - `OperatorService` - A service that handles communication from the management server about the operator commands. + - `PlayerService` - A service that handles communication from the management server about the player list. + - `RemoteRpcErrorException` - An exception thrown when something goes wrong on the management server. + - `ServerSettingsService` - A service that handles communication from the management server about the server settings. + - `ServerStateService` - A service that handles communication from the management server about the current server state and send messages. +- `net.minecraft.server.jsonrpc.security` + - `AuthenticationHandler` - Handles the validation of the authentication token bearer in the request. + - `JsonRpcSslContextProvider` - Provides the keystore context for the TLS communication. + - `SecurityConfig` - Handles the secret key, from checking basic validaty to generating a new one. +- `net.minecraft.server.jsonrpc.websocket` + - `JsonToWebSocketEncoder` - A message to message encoder for a json. + - `WebSocketToJsonCodec` - A message to message decoder for a json. +- `net.minecraft.server.notifications` + - `EmptyNotificationService` - A notification service that does nothing. + - `NotificationManager` - A manager for handling multiple notification services. + - `NotificationService` - A service that defines prospective actions taken by a listener, like a management server. +- `net.minecraft.server.players` + - `BanListEntry` + - `getReason` can now be `null` + - `getReasonMessage` - Returns the translatable component of the ban reason. + - `IpBanList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `PlayerList` now takes in the `NotificationService` instead of the max players + - `maxPlayers` is removed + - `op` now has an override for the permission level and bypass limit boolean + - `setUsingWhiteList` -> `MinecraftServer#setUsingWhiteList` + - `getPlayer` - Gets a player by their name. + - `ServerOpList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `StoredUserEntry#getUser` is now public + - `StoredUserList` now takes in the `NotificationService` + - `add`, `remove` now return a boolean if successful + - `remove(StoredUserEntry)` is removed + - `clear` - Clears all stored users. + - `UserBanList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + - `UserWhiteList` now takes in the `NotificationService` + - `add`, `remove` - Handles entries on the list. + +### Input Handling Consolidation + +Input handling has previously passed around the raw values, each in their own separate argument, provided by GLFW. However, a good bit of the handling logic is redundant, as specific keys are commonly checked, or all values are passed around in a game of hot potato from one method to the next. With this in mind, the input handlers in `GuiEventListener` and other calls, are now handled through event objects. These objects still contain the info GLFW passed through; however, now they have a lot of common checks through the super `InputWithModifiers` interface. + +There are two types of events: `KeyEvent`s for key presses, and `MouseButtonEvent`s for mouse presses. Key, scancode, and modifiers are wrapped into the `KeyEvent`. Button, modifiers, and the XY screen position are wrapped into the `MouseButtonEvent`. As such, it is generally a drag-and-drop replacement of just removing any of the parameters mentioned above and replacing them with their appropriate event. + +#### Key Mapping Categories + +Key mappings have changed slightly, no longer taking in a raw string for its category, and instead using a `KeyMapping$Category` record, which is essentially a namspaced string. Categories can be created using `KeyMapping$Category#register`; otherwise, an error will be thrown whenever the mapping is used as part of a comparator. + +```java +public static final KeyMapping.Category EXAMPLE = KeyMapping.Category.register(ResourceLocation.withNamespaceAndPath("examplemod", "example")); +``` + +#### Double-Click Expansion + +`GuiEventListener#mouseClicked` now takes in whether the click was in fact a double-click as a boolean. + +```java +// For some Screen subclass (or AbstractWidget or any GUI object rendering) + +@Override +public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { + // ... + return false; +} +``` + +- `com.mojang.blaze3d.platform.InputConstants` + - `MOD_SHIFT`, `MOD_ALT`, `MOD_SUPER`, `MOD_CAPS_LOCK`, `MOD_NUM_LOCK` - Modifier keys to transform a key input. + - `KEY_LWIN`, `KEY_RWIN` -> `KEY_LSUPER`, `KEY_RSUPER` + - `getKey` now takes in a `KeyEvent` instead of the key and scancode `int`s + - `isKeyDown`, `setupKeyboardCallbacks`, `setupMouseCallbacks`, `grabOrReleaseMouse`, `updateRawMouseInput` now take in a `Window` instead of the `long` handle +- `net.minecraft.client` + - `KeyboardHandler` + - `keyPress` is now private + - `setup` now takes in a `Window` instead of the `long` handle + - `KeyMapping` now takes in a `$Category` instead of a `String` + - `shouldSetOnIngameFocus` - Returns whether the key is mapped to some value on the keyboard. + - `restoreToggleStatesOnScreenClosed` - Restores the toggled keys to its state during in-game actions. + - `key` is now protected + - `release` is now protected + - `CATEGORY_*` -> `$Category#*` + - Key can be obtained via `$Category#id` + - Component is available through `$Category#label` + - `getCategory` now returns a `$Category` instead of a `String` + - `matches` now takes in a `KeyEvent` instead of the key and scancode `int`s + - `matchesMouse` now takes in a `MouseButtonEvent` instead of the button `int` + - `Minecraft#ON_OSX` -> `InputQuirks#ON_OSX` + - `MouseHandler#setup` now takes in a `Window` instead of the `long` handle + - `ToggleKeyMapping` now has an overload that takes in an input type + - The constructor now takes in a `KeyMapping$Category` instead of a `String`, and a `boolean` that represents if the previous state of the key binding should be restored +- `net.minecraft.client.gui.components` + - `AbstractButton#onPress` now takes in an `InputWithModifiers` + - `AbstractScrollArea#updateScrolling` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `AbstractWidget` + - `onClick` now takes in a `MouseButtonEvent` instead of the XY positions and whether the button was double-clicked + - `onRelease` now takes in a `MouseButtonEvent` instead of the XY positions + - `onDrag` now takes in a `MouseButtonEvent` instead of the XY positions + - `isValidClickButton` now takes in the `MouseButtonInfo` instead of the button `int` + - `CommandSuggestions` + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `$SuggestionsList` + - `mouseClicked` no longer takes in the button `int` + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `MultilineTextField#keyPressed` now takes in a `KeyEvent` instead of the key `int` +- `net.minecraft.client.gui.components.events.GuiEventListener` + - `DOUBLE_CLICK_THRESHOLD_MS` -> `MouseHandler#DOUBLE_CLICK_THRESHOLD_MS` + - `mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions, and whether the button was double-clicked + - `mouseReleased` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `mouseDragged` now takes in a `MouseButtonEvent` instead of the button info and XY positions + - `keyPressed` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `keyReleased` now takes in a `KeyEvent` instead of the key, scancode, modifiers `int` + - `charTyped` now takes in a `CharacterEvent` instead of the codepoint `char` and modifiers `int` +- `net.minecraft.client.gui.font.TextFieldHelper` + - `charTyped` now takes in a `CharacterEvent` instead of the codepoint `char` + - `keyPressed` now takes in a `KeyEvent` instead of the key `int` +- `net.minecraft.client.gui.navigation.CommonInputs` class is removed + - `selected` -> `InputWithModifiers#isSelection` + - `confirm` -> `InputWithModifiers#isConfirmation` +- `net.minecraft.client.gui.screens.Screen` + - `hasControlDown` -> `Minecraft#hasControlDown`, `InputWithModifiers#hasControlDown` + - `hasShiftDown` -> `Minecraft#hasShiftDown`, `InputWithModifiers#hasShiftDown` + - `hasAltDown` -> `Minecraft#hasAltDown`, `InputWithModifiers#hasAltDown` + - `isCut` -> `InputWithModifiers#isCut` + - `isPaste` -> `InputWithModifiers#isPaste` + - `isCopy` -> `InputWithModifiers#isCopy` + - `isSelectAll` -> `InputWithModifiers#isSelectAll` +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen` + - `hasClickedOutside` no longer takes in the button `int` + - `checkHotbarKeyPressed` now takes in a `KeyEvent` instead of the key and modifiers `int` +- `net.minecraft.client.gui.screens.options.controls.KeyBindsList$CategoryEntry` now takes in a `KeyMapping$Category` instead of the `Component` +- `net.minecraft.client.gui.screens.recipebook` + - `hasClickedOutside` no longer takes in the button `int` + - `RecipeBookPage#mouseClicked` now takes in a `MouseButtonEvent` instead of the button info and XY positions, and whether the button was double-clicked +- `net.minecraft.client.input` + - `CharacterEvent` - Some kind of input interaction generates a codepoint with the currently active modifiers. + - `InputQuirks` - A utility for quirks between operating systems when handling inputs. + - `InputWithModifiers` - Defines an input with the currently active modifiers, along with some common input checks. + - `KeyEvent` - Some kind of input interaction generates a key by the scancode with the currently active modifiers. + - `MouseButtonEvent` - Some kind of input interaction generates a button at the XY position. + - `MouseButtonInfo` - Some kind of input interaction generates a button with the currently active modifiers. + +### `Level#isClientSide` now private + +The `Level#isClientSide` field is now private, so all queries must be made to the method version: + +```java +// For some Level level +level.isClientSide(); +``` + +- `net.minecraft.world.level.Level#isClientSide` field is now private + +### 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. + +#### Item Owner + +Minecraft has further abstracted the holder of an item in item models to its own interface: `ItemOwner`. An `ItemOwner` is defined by three things: the `level` the owner is in, the `position` of the owner, and the Y rotation (in degrees) of the owner to indicate the facing direction. `ItemOwner`s are implemented on every `Entity`; however, their position can be offset by using `ItemOwner#offsetFromOwner` or creating a `ItemOwner$OffsetFromOwner`. + +Currently, only the new shelf block uses the offset owner so that compasses are not randomly spinning when placed. + +- `net.minecraft.client.renderer.entity.ItemRenderer#renderStatic` now takes in an optional `ItemOwner` instead of a `LivingEntity` +- `net.minecraft.client.renderer.item` + - `ItemModel#update` now takes in an `ItemOwner` instead of a `LivingEntity` + - `ItemModelResolver#updateForTopItem`, `appendItemLayers` now takes in an `ItemOwner` instead of a `LivingEntity` +- `net.minecraft.client.renderer.item.properties.numeric` + - `NeedleDirectionHelper#get`, `calculate` now takes in an `ItemOwner` instead of a `LivingEntity` + - `RangeSelectItemModelProperty#get` now takes in an `ItemOwner` instead of a `LivingEntity` + - `Time$TimeSource#get` now takes in an `ItemOwner` instead of a `Entity` +- `net.minecraft.world.entity` + - `Entity` now implements `ItemOwner` + - `ItemOwner` - Represents the owner of the item being rendered. + +#### Container User + +As this new version of Minecraft introduces the copper golem (a vanilla mob that can interact with inventories), the concept of an entity that can use a container has been abstracted into its own interface: `ContainerUser`. `ContainerUser`s are expected to be implemented on some `LivingEntity` subclass. Since the actual inventory logic is handled elsewhere, `ContainerUser` only has two methods: `hasContainerOpen`, which checks whether the living entity is currently opening some container (e.g., barrel, chest); and `getContainerInteractionRange`, which determines the radius in blocks that the entity can interact with some container. + +- `net.minecraft.world.Container` + - `startOpen`, `stopOpen` now take in a `ContainerUser` instead of a `Player` + - `getEntitiesWithContainerOpen` - Returns the list of `ContainerUser`s that are interacting with this container. +- `net.minecraft.world.entity.ContainerUser` - Typically an entity that can interact with and open a container. +- `net.minecraft.world.entity.player.Player` now implements `ContainerUser` +- `net.minecraft.world.level.block.entity.EnderChestBlockEntity#startOpen`, `stopOpen` now take in a `ContainerUser` instead of a `Player` + +#### Name And Id + +Unless a `GameProfile` is needed, Minecraft now passes around a `NameAndId` for every player instead. As the name implies, `NameAndId` contains the UUID and name of the player, as that is usually all that's necessary for most logic involving a player entity. + +- `net.minecraft.commands.arguments.GameProfileArgument` + - `getGameProfiles` now return a collections of `NameAndId`s + - `$Result#getNames` now return a collections of `NameAndId`s +- `net.minecraft.network.codec.ByteBufCodecs#PLAYER_NAME` - A 16 byte string stream codec of the player name. +- `net.minecraft.network.protocol.status.ServerStatus$Players#Sample` now is a list of `NameAndId`s rather than `GameProfile`s +- `net.minecraft.server` + - `MinecraftServer` + - `getProfilePermissions` now takes in a `NameAndId` instead of a `GameProfile` + - `isSingleplayerOwner` now takes in a `NameAndId` instead of a `GameProfile` + - `ANONYMOUS_PLAYER_PROFILE` is now a `NameAndId` + - `Services` now takes in a `UserNameToIdResolver` instead of a `GameProfileCache`, and a `ProfileResolver` +- `net.minecraft.server.players` + - `GameProfileCache` -> `UserNameToIdResolver`, `CachedUserNameToIdResolver`; not one-to-one + - `getAsync` is removed + - `add(GameProfile)` is removed + - `NameAndId` - An object that holds the UUID and name of a profile. + - `PlayerList` + - `load` -> `loadPlayerData`, not one-to-one + - `canPlayerLogin` now takes in a `NameAndId` instead of a `GameProfile` + - `disconnectAllPlayersWithProfile` now takes in a `UUID` instead of a `GameProfile` + - `op`, `deop` now take in a `NameAndId` instead of a `GameProfile` + - `isWhiteListed`, `isOp` now take in a `NameAndId` instead of a `GameProfile` + - `canBypassPlayerLimit` now takes in a `NameAndId` instead of a `GameProfile` + - `ServerOpList` now takes in `NameAndId` as its first generic + - `canBypassPlayerLimit` now takes in a `NameAndId` instead of a `GameProfile` + - `ServerOpListEntry` now takes in `NameAndId` as its generic and for the constructor + - `UserBanList` now takes in `NameAndId` as its first generic + - `isBanned` now takes in a `NameAndId` instead of a `GameProfile` + - `UserBanListEntry` now takes in `NameAndId` as its generic and for the constructor + - `UserWhiteList` now takes in `NameAndId` as its first generic + - `isWhiteListed` now takes in a `NameAndId` instead of a `GameProfile` + - `UserWhiteListEntry` now takes in `NameAndId` as its generic and for the constructor +- `net.minecraft.world.entity.player.Player#nameAndId` - Returns the name and id of the player. +- `net.minecraft.world.level.storage.PlayerDataStorage#load(Player, ProblemReporter)` -> `load(NameAndId)`, returns an `Optional` + +#### Typed Entity Data + +Data components for storing block and entity data have been changed from using `CustomData` to the type safe variant `TypedEntityData`. `TypedEntityData` is pretty much the same as `CustomData`, storing a `CompoundTag`, except that it is represented by some `IdType` generic like `EntityType` or `BlockEntityType`. All of the methods within `CustomData` relating to block entities and entities have moved to `TypedEntityData`. + +Spawn eggs use the `TypedEntityData` to store the `EntityType` that it will spawn. The logic of spawning is still tied to the `SpawnEggItem` subclass. + +- `net.minecraft.core.component.DataComponents#ENTITY_DATA`, `BLOCK_ENTITY_DATA` are now `TypeEntityData` with `EntityType` and `BlockEntityType` ids, respectively +- `net.minecraft.world.entity.EntityType#updateCustomEntityTag` now takes in a `TypedEntityData` instead of `CustomData` +- `net.minecraft.world.item.Item$Properties#spawnEgg` - Adds the `ENTITY_DATA` component with the entity type. +- `net.minecraft.world.item.component` + - `CustomData` + - `CODEC_WITH_ID` is removed + - `COMPOUND_TAG_CODEC` - A codec for a flattened compound tag. + - `parseEntityId`, `parseEntityType` are removed + - `loadInto` -> `TypedEntityData#loadInto` + - `update`, `read`, `size` are removed + - `contains` -> `TypedEntityData#contains` + - `getUnsafe` -> `TypedEntityData#getUnsafe` + - `TypedEntityData` - A custom data that provides a type-safe identifier. +- `net.minecraft.world.level.Spawner#appendHoverText`, `getSpawnEntityDisplayName` now take in a `TypedEntityData` instead of a `CustomData` +- `net.minecraft.world.level.block.entity.BeehiveBlockEntity$Occupant#entityData` is now a `TypedEntityData` + +#### Reload Listener Shared State + +`PreparableReloadListener` now have an option to share their data between other reload listeners through the use of the `PreparableReloadListener#prepareSharedState`. `prepareSharedState` is ran on the main thread before `reload` is called, which can store arbitrary values to some `$SharedKey` as basically a dictionary lookup. Then, once `reload` is called, the stored data can be obtained and used via the key. Normally, the shared values used are some kind of `CompletableFuture` and joined within. + +```java +public class FirstExampleListener implements PreparableReloadListener { + + // Create the key to write the shared data to + public static final PreparableReloadListener.StateKey> EXAMPLE = new PreparableReloadListener.StateKey<>(); + + @Override + public void prepareSharedState(PreparableReloadListener.SharedState state) { + // Add the data to the shared state + state.set(EXAMPLE, CompletableFuture.allOf()); + } + + @Override + public CompletableFuture reload(PreparableReloadListener.SharedState state, Executor tasksExecutor, PreparableReloadListener.PreparationBarrier barrier, Executor reloadExecutor) { + // Use the shared state + var example = state.get(EXAMPLE); + } +} + + +public class SecondExampleListener implements PreparableReloadListener { + + @Override + public CompletableFuture reload(PreparableReloadListener.SharedState state, Executor tasksExecutor, PreparableReloadListener.PreparationBarrier barrier, Executor reloadExecutor) { + // Use the shared state in a different listener + var example = state.get(FirstExampleListener.EXAMPLE); + } +} +``` + +- `net.minecraft.server.packs.resources` + - `PreparableReloadListener` + - `reload` now takes in a `PreparableReloadListener$SharedState` instead of a `ResourceManager` + - `prepareSharedState` - A method called before the reload listener is reloaded to share data between reloading listeners. + - `$SharedState` - A general dictionary that can provide resources between reload listeners, though they should typically be in the form of `CompletableFuture`s. + - `$StateKey` - A key into the shared state. + - `SimpleReloadInstance$StateFactory#create` now takes in a `PreparableReloadListener$SharedState` instead of a `ResourceManager` + +#### Ticket Flags + +`TicketType` has been updated to take a bit flag representing the flag's properties rather than a boolean and enum. + +```java +// This needs to be registered to BuiltInRegistries#TICKET_TYPE +public static final TicketType EXAMPLE = new TicketType( + 20L, // The number of ticks before the ticket is timed out and removed, set to 0 if the ticket should never time out + // The bit flags to set, see below for replacements and explanations of the new flags + TicketType.FLAG_SIMULATION | TicketType.FLAG_LOADING +); +``` + +- `net.minecraft.server.level.TicketType` now takes in a bitmask of flags rather than a boolean and ticket use + - `FLAG_PERSIST`, `persist` replace the boolean + - `FLAG_LOADING` replaces `$TicketUse#LOADING` + - `FLAG_SIMULATION` replaces `$TicketUse#SIMULATION` + - `FLAG_KEEP_DIMENSION_ACTIVE`, `shouldKeepDimensionActive` - When set, prevents the level from unloading. + - `FLAG_CAN_EXPIRE_IF_UNLOADED`, `canExpireIfUnloaded` - When set, the ticket expires if the chunk is unloaded. + - `START` -> `PLAYER_SPAWN`, `SPAWN_SEARCH` + - `$TicketUse` class is removed +- `net.minecraft.world.level.TicketStorage` + - `shouldKeepDimensionActive` - Checks if the dimension active flag is set on any tickets in the storage. + - `removeTicketIf` now takes a `$TicketPredicate` instead of a `BiPredicate` + - `$TicketPredicate` - Tests the ticket at a given chunk position. + +#### Respawn Data + +The respawn logic has been consolidated into a single object known as `LevelData$RespawnData`. The respawn data holds the global position (a level key and block position) and the rotation of the entity. All calls to the original angle and position methods have been replaced by `Level#setRespawnData` or `getRespawnData`, which delegates to the `MinecraftServer` and eventually the level data. + +- `net.minecraft.client.multiplayer.ClientLevel#setDefaultSpawnPos` -> `Level#setRespawnData` +- `net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket` is now a record + - The parameters have been replaced with a `LevelData$RespawnData` object +- `net.minecraft.server.MinecraftServer` + - `findRespawnDimension` - Gets the default `ServerLevel` that the player should respawn in. + - `setRespawnData` - Sets the default spawn position. + - `getRespawnData` - Gets the default spawn position. +- `net.minecraft.server.level` + - `ServerLevel#setDefaultSpawnPos` -> `Level#setRespawnData` + - `ServerPlayer$RespawnConfig` now takes in a `LevelData$RespawnData` instead of the dimension, position, and angle + - Fields are still accessible from the respawn data +- `net.minecraft.world.level.Level#getSharedSpawnPos`, `getSharedSpawnAngle` -> `getRespawnData`, `getWorldBorderAdjustedRespawnData`, not one-to-one +- `net.minecraft.world.level.storage` + - `LevelData` + - `getSpawnPos`, `getSpawnAngle` -> `getRespawnData`, not one-to-one + - `$RespawnData` - Defines the global position, yaw, and pitch of where to respawn the players by default. + - `WritableLevelData#setSpawn` now only takes in the `LevelData$RespawnData` + +#### The 'On Shelf' Transform + +Models now have a new transform for determining how an item sits on a shelf called `on_shelf`. + +- `net.minecraft.client.renderer.block.model.ItemTransforms#fixedFromBottom` - A transform that expects the item to be sitting on some fixed bottom, like a shelf. +- `net.minecraft.world.item.ItemDisplayContext#ON_SHELF` - When an item is placed on a shelf. + +#### Client Asset Split + +`ClientAsset` has been reworked to better specify what the asset is referencing. Currently, vanilla adds `ClientAsset$Texture` to specify that the asset is a texture, which further subclasses to `$DownloadedTexture` for textures downloaded from the internet, and `$ResourceTexture` for textures accessible from some existing resource on the disk. + +- `net.minecraft.advancements.DisplayInfo` now takes in an optional `ClientAsset$ResourceTexture` for the background instead of a `ClientAsset` +- `net.miencraft.client.renderer.texture.SkinTextureDownloader#downloadAndRegisterSkin` now returns a future for the `ClientAsset$Texture` instead of a `ResourceLocation` +- `net.minecraft.client.resources` + - `PlayerSkin` -> `net.minecraft.world.entity.player.PlayerSkin` + - The constructor now takes in `ClientAsset$Texture`s instead of `ResourceLocation` and `String`s + - `texture`, `textureUrl` -> `body` + - `capeTexture` -> `cape` + - `elytraTexture` -> `elytra` + - `insecure` - Constructs a `PlayerSkin` with `insecure` set to false. + - `with` - Builds a `PlayerSkin` from its `$Patch`. + - `$Patch` - A packed object representing the skin in other files or when sending across the network. + - `SkinManager$TextureCache#getOrLoad` now returns a future for the `ClientAsset$Texture` instead of a `ResourceLocation` +- `net.minecraft.core.ClientAsset` is now an interface instead of a record + - Original implementation moved to `$ResourceTexture` + - `id` still exists as a method + - `texturePath` -> `$Texture#texturePath` + - `CODEC`, `DEFAULT_FIELD_CODEC`, `STREAM_CODEC` -> `$ResourceTexture#*` + - `$DownloadedTexture` - A texture downloaded from the internet. + - `$Texture` - A client asset which defines a texture. +- `net.minecraft.world.entity.animal.CatVariant#assetInfo` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.animal.frog.FrogVariant#assetInfo` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.animal.wolf.WolfVariant$AssetInfo#*` now take in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` +- `net.minecraft.world.entity.variant.ModelAndTexture#asset` now takes in a `ClientAsset$ResourceTexture` instead of a `ClientAsset` + +#### Cursor Types + +The current cursor on screen can now change to a native `CursorType`, via `GLFW#glfwCreateStandardCursor` in a GUI via `GuiGraphics#requestCursor`, or `Window#selectCursor` anywhere else. Note that `Window#setAllowCursorChanges` must be true, which can be set through the options menu. + +- `com.mojang.blaze3d.platform.Window` + - `setAllowCursorChanges` - Sets whether the cursor can be changed to a different standard shape. + - `selectCursor` - Sets the current cursor to the specified type. +- `com.mojang.blaze3d.platform.cursor` + - `CursorType` - A definition of a GLFW standard cursor shape. + - `createStandardCursor` - Creates a standard cursor from its shape, name, and fallback. + - `CursorTypes` - Blaze3d's cursor types. +- `net.minecraft.client.Options#allowCursorChanges` - Sets whether the cursor can be changed to a different standard shape. +- `net.minecraft.client.gui.GuiGraphics` + - `requestCursor` - Requests the cursor to submit to be rendered. + - `applyCursor` - Applies the cursor change for rendering. + +#### New Tags + +- `minecraft:block` + - `wooden_shelves` + - `copper_chests` + - `lightning_rods` + - `copper` + - `copper_golem_statues` + - `incorrect_for_copper_tool` + - `chains` + - `lanterns` + - `bars` +- `minecraft:entity_types` + - `cannot_be_pushed_onto_boats` + - `accepts_iron_golem_gift` + - `candidate_for_iron_golem_gift` +- `minecraft:item` + - `wooden_shelves` + - `copper_chests` + - `lightning_rods` + - `copper` + - `copper_golem_statues` + - `copper_tool_materials` + - `repairs_copper_armor` + - `chains` + - `lanterns` + - `bars` + - `shearable_from_copper_golem` + +#### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds#isGlOnDx12` - Returns whether the renderer is using DirectX 12. +- `com.mojang.blaze3d.opengl.GlStateManager#incrementTrackedBuffers` - Increments the number of buffers used by the game. +- `com.mojang.blaze3d.systems.TimerQuery#isRecording` - Returns whether there is a query that's currently active. +- `net.minecraft.SharedConstants#RESOURCE_PACK_FORMAT_MINOR`, `DATA_PACK_FORMAT_MINOR` - The minor component of the pack version. +- `net.minecraft.advancements.critereon.MinMaxBounds` + - `bounds` - Returns the bounds of the value. + - `$FloatDegrees` - A bounds for a float representing the degree of some angle. +- `net.minecraft.client` + - `Minecraft` + - `isOfflineDevelopedMode` - Returns whether the game is in offline developer mode. + - `canSwitchGameMode` - Whether the player entity exists and has a game mode. + - `playerSkinRenderCache` - Returns the cache holding the player's render texture. + - `canInterruptScreen` - Whether the current screen can be closed by another screen. + - `packetProcessor` - Returns the processor that schedules and handles packets. + - `Options` + - `invertMouseX` - When true, inverts the X mouse movement. + - `toggleAttack` - When true, sets the attack key to be toggleable. + - `toggleUse` - When true, sets the use key to be toggleable. + - `sprintWindow` - Time window in ticks where double-tapping the forward key activates sprint. + - `saveChatDrafts` - Returns whether the message being typed in chat should be retained if the box is closed. + - `keySpectatorHotbar` - A key that pulls up the spectator hotbar menu. + - `ToggleKeyMapping#shouldRestoreStateOnScreenClosed` - Whether the previous toggle state should be restored after screen close. +- `net.minecraft.client.animation.definitions.CopperGolemAnimation` - The animations for the copper golem. +- `net.minecraft.client.data.models.BlockModelGenerators` + - `and` - ANDs the given conditions together. + - `createShelf` - Creates a shelf block state from a base and a particle texture. + - `addShelfPart` - Adds a variant for a model for all the shelf's states. + - `forEachHorizontalDirection` - Performs an operation for a pair of directions and rotations. + - `shelfCondition` - Constructs a condition based on the state of the shelf. + - `createCopperGolemStatues` - Creates all copper golem statues. + - `createCopperGolemStatue` - Creates a copper golem statue for the provided block, copper block, and weathered state. + - `createCopperChests` - Creates all copper chests. + - `createCopperLantern` - Creates a lantern and hanging lantern. + - `createCopperChain` - Creates a chain. + - `createCopperChainItem` - Creates a chain item model. +- `net.minecraft.client.data.models.model` + - `ModelTemplate` + - `SHELF_*` - Model templates for constructing a shelf into a multipart. + - `LIGHTNING_ROD` - Model template for a lightning rod. + - `CHAIN` - Model template for a chain. + - `BARS_*` - Model templates for constructing a bars-like block. + - `TexturedModel#CHAIN` - A model provider for a chain. + - `TextureMapping#bars` - A texture mapping for a bars-like block. + - `TextureSlot#BARS` - A reference to the `#bars` texture. +- `net.minecraft.client.gui` + - `Gui#renderDeferredSubtitles` - Renders the subtitles on screen. + - `GuiGraphics#getSprite` - Gets a `TextureAtlasSprite` from its material. +- `net.minecraft.client.gui.components` + - `AbstractScrollArea#isOverScrollbar` - Returns whether the current cursor position is over the scroll bar. + - `AbstractSelectionList` + - `sort` - Sorts the entries within the list. + - `swap` - Swaps the position of two entries in the list + - `clearEntriesExcept` - Removes all entries that don't match the provided element. + - `getNextY` - Returns the Y component to render the scrolled component. + - `entriesCanBeSelected` - Whether the entries in the list can be selected. + - `scrollToEntry` - Scrolls the bar such that the selected entry is on screen. + - `removeEntries` - Removes all entries that are in the provided list. + - `$Entry` + - `set*` - Sets the component size. + - `getContent*` - Get the content size and positions. + - `ChatComponent` + - `saveAsDraft`, `discardDraft` - Handles the draft message in the chat box. + - `createScreen`, `openScreen`, `preserveCurrentChatScreen`, `restoreChatScreen` - Handles screen behavior depending on the draft chat option. + - `$ChatMethod` - Defines what type of message is the chat. + - `$Draft` - Defines a draft message in the chat box. + - `EditBox` + - `DEFAULT_HINT_STYLE` - The style of the default hints. + - `SEARCH_HINT_STYLE` - The style of the searchable hints, such as in a recipe book. + - `$TextFormatter` - An interface used to format the string in the box. + - `FittingMultiLineTextWidget#minimizeHeight` - Sets the height of the widget to the inner height and padding. + - `FocusableTextWidget$BackgroundFill` - An enum that represents when the background should be filled. + - `ItemDisplayWidget#renderTooltip` - Submits the tooltip to render. + - `MultiLineLabel$Align` - Handles the alignment of the label. + - `MultilineTextField#selectWordAtCursor` - Selects the word whether the cursor is currently located. + - `SpriteIconButton$Builder#withTooltip` - Sets the tooltip to display the message. + - `StringWidget` + - `setMaxWidth` - Sets the max width of the string and how to handle the extra width. + - `$TextOverflow` - What to do if the text is longer than the max width. +- `net.minecraft.client.gui.components.events.GuiEventListener#shouldTakeFocusAfterInteraction` - When true, sets the element as focused when clicked. +- `net.minecraft.client.gui.screens` + - `ChatScreen` + - `isDraft` - Whether there is a message that hasn't been sent in the box. + - `exitReason` - The reason the chat screen was closed. + - `shouldDiscardDraft` - Whether the current draft message should be discarded. + - `$ChatConstructor` - A constructor for the chat screen based on the draft state. + - `$ExitReason` - The reason the chat screen was closed. + - `FaviconTexture#isClosed` - Returns whether the texture has been closed. + - `LevelLoadingScreen` + - `update` - Updates the current load tracker and reason. + - `$Reason` - The reason for changing the level loading screen. + - `Overlay#tick` - Ticks the overlay. + - `Screen` + - `panoramaShouldSpin` - Returns whether the rendered panorama should spin its camera. + - `setNarrationSuppressTime` - Sets until when the narration should be suppressed for. + - `isInGameUi` - Returns whether the screen is opened while playing the game, not the pause menu. + - `isAllowedInPortal` - Whether this screen can be open during the portal transition effect. + - `canInterruptWithAnotherScreen` - Whether this screen can be closed by another screen, defaults to 'close on escape' screens. +- `net.minecraft.client.gui.screens.inventory.AbstractCommandBlockScreen#addExtraControls` - Adds any extra widgets to the command block screen. +- `net.minecraft.client.gui.screens.multiplayer` + - `CodeOfConductScreen` - A screens that displays the code of conduct text for a server. + - `ServerSelectionList$Entry` + - `matches` - Returns whether the provided entry matches this one. + - `join` - Handles how the client joins to the server entry. +- `net.minecraft.client.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#ITEM_HEIGHT` - The height of each entry in the list. +- `net.minecraft.client.gui.screens.worldselection.WorldSelectionList` + - `returnToScreen` - Returns to the previous screen after reloading the world list. + - `$Builder` - Creates a new `WorldSelectionList`. + - `$Entry#getLevelSummary` - Returns the summary of the selected world. + - `$EntryType` - A enum representing what type of world the entry is. + - `$NoWorldsEntry` - An entry where there are no worlds to select from. +- `net.minecraft.client.main.GameConfig$GameData#offlineDeveloperMode` - Whether the game is offline and is ran for development. +- `net.minecraft.client.multiplayer` + - `ClientCommonPacketListenerImpl` + - `seenPlayers` - All players that have been seen, regardless of if they are currently online, by this player. + - `seenInsecureChatWarning` - If the player has seen the insecure chat warning. + - `$CommonDialogAccess` - A dialog access used by the client network. + - `ClientConfigurationPacketListenerImpl#DISCONNECTED_MESSAGE` - The message to display on disconnect because of not accepting the code of conduct. + - `ClientExplosionTracker` - Tracks the explosions made on the client, specifically to handle particles. + - `ClientLevel` + - `endFlashState` - Handles the state of the flashes of light that appear in the end. + - `trackExplosionEffects` - Tracks an explosion to handle its particles. + - `ClientPacketListener` + - `getSeenPlayers` - Returns all players seen by this player. + - `getPlayerInfoIgnoreCase` - Gets the player info for the provided profile name. +- `net.minecraft.client.player.LocalPlayerResolver` - A profile resolver for the local player. +- `net.minecraft.client.resources.WaypointStyle#ICON_LOCATION_PREFIX` - The prefix for waypoint icons. +- `net.minecraft.client.server.IntegratedServer#MAX_PLAYERS` - The maximum number of players allowed in an locally hosted server. +- `net.minecraft.client.sounds` + - `DirectionalSoundInstance` - A sound that changes position based on the direction of the camera. + - `SoundEngineExecutor#startUp` - Creates the thread to run the engine on. + - `SoundPreviewHandler` - A utility for previewing how some event would sound like with the given settings. +- `net.minecraft.core` + - `BlockPos#betweenCornersInDirection` - An iterable that iterates through the provided bounds in the direction provided by the vector. + - `Direction#axisStepOrder` - Returns a list of directions that the given vector should be checked in. +- `net.minecraft.core.particles.ExplosionParticleInfo` - The particle that used as part of an explosion. +- `net.minecraft.data.loot.BlockLootSubProvider#createCopperGolemStatueBlock` - The loot table for a copper golem statue. +- `net.minecraft.data.loot.packs` + - `VanillaBlockInteractLoot` - A sub provider for vanilla block loot from entity interaction. + - `VanillaChargedCreeperExplosionLoot` - A sub provider for vanilla entity loot from charged creeper explosions. + - `VanillaEntityInteractLoot` - A sub provider for vanilla entity loot from entity interaction. +- `net.minecraft.data.recipes.RecipeProvider#shelf` - Constructs a shelf recipe from one item. +- `net.minecraft.data.worldgen.BiomeDefaultFeatures#addNearWaterVegetation` - Adds the vegetation when near a body of water. +- `net.minecraft.gametest.framework.GameTestHelper#getTestDirection` - Gets the direction that the test is facing. +- `net.minecraft.network` + - `FriendlyByteBuf#readLpVec3`, `writeLpVec3` - Handles syncing a compressed `Vec3`. + - `LpVec3` - A vec3 network handler that compresses and decompresses a vector into at most two bytes and two integers. + - `PacketProcessor` - A processor for packets to be scheduled and handled. +- `net.minecraft.network.chat.CommonComponents#GUI_COPY_TO_CLIPBOARD` - The message to display when copying a chat to the clipboard. +- `net.minecraft.network.protocol.configuration` + - `ClientboundCodeOfConductPacket` - A packet the sends the code of conduct of a server to the joining client. + - `ClientConfigurationPacketListener#handleCodeOfConduct` - Handles the code of conduct sent from the server. + - `ServerboundAcceptCodeOfConductPacket` - A packet that sends the acceptance response of a client reading the code of conduct from a server. + - `ServerConfigurationPacketListener#handleAcceptCodeOfConduct` - Handles the acceptance of the code of conduct from the client. +- `net.minecraft.network.syncher.EntityDataSerializers` + - `WEATHERING_COPPER_STATE` - The weather state of the copper on the golem. + - `COPPER_GOLEM_STATE` - The logic state of the copper golem. + - `RESOLVABLE_PROFILE` - The resovlable profile of an entity. +- `net.minecraft.server.MinecraftServer` + - `selectLevelLoadFocusPos` - Returns the loading center position of the server, usually the shared spawn position. + - `getLevelLoadListener` - Returns the listener used to track level loading. + - `getCodeOfConducts` - Returns a map of file names to their code of conduct text. + - `enforceGameTypeForPlayers` - Sets the game type of all players. + - `packetProcessor` - Returns the packet processor for the server. +- `net.minecraft.server.commands.FetchProfileCommand` - Fetches the profile of a given user. +- `net.minecraft.server.dedicated.DedicatedServerProperties#codeOfConduct` - Whether the server has a code of conduct. +- `net.minecraft.server.level` + - `ChunkLoadCounter` - Keeps track of chunk loading when a level is loading or the player spawns. + - `ChunkMap` + - `getLatestStatus` - Returns the latest status for the given chunk position. + - `isTrackedByAnyPlayer` - Checks whether the entity is tracked by any player. + - `forEachEntityTrackedBy` - Loops through each entity tracked by the given player. + - `forEachReadyToSendChunk` - Loops through each chunk that is ready to be sent to the client. + - `ServerChunkCache` + - `hasActiveTickets` - Checks whether the current level has any active tickets keeping it loaded. + - `addTicketAndLoadWithRadius` - Adds a ticket to some location and loads the chunk and radius around that location. + - `ServerEntity$Synchronizer` - Handles sending packets to tracking entities. + - `ServerLevel#isSpawningMonsters` - Returns whether the server can spawn monsters. + - `ServerPlayer$SavedPosition` - Holds the current position of the player on disk. +- `net.minecraft.server.level.progress.ChunkLoadStatusView` - A status view for the loading chunks. +- `net.minecraft.server.network.ConfigurationTask#tick` - Calls the task every tick until it returns true, then finishes the task. +- `net.minecraft.server.network.config` + - `PrepareSpawnTask` - A configuration task that finds the spawn of the player. + - `ServerCodeOfConductConfigurationTask` - A configuration task that sends the code of conduct to the client. +- `net.minecraft.server.packs.OverlayMetadataSection` + - `codecForPackType` - Constructs a codec for the section given the pack type. + - `forPackType` - Gets the metadata section type from the pack type. +- `net.minecraft.server.packs.metadata.MetadataSectionType#withValue`, `$WithValue` - Holds a metadata section along with its provided value. +- `net.minecraft.server.packs.metadata.pack` + - `PackFormat` - Represents the major and minor revision of a pack. + - `PackMetadataSection#forPackType` - Gets the metadata section type from the pack type. +- `net.minecraft.server.packs.repository.PackCompatibility#UNKNOWN` - The compatibility of the pack with the game is unknown as the major version is set to the max integer value. +- `net.minecraft.server.packs.resources.ResourceMetadata#getTypedSection`, `getTypedSections` - Gets the metadata sections for the provided types. +- `net.minecraft.server.players.ProfileResolver` - Resolves a game profile from its name or UUID. +- `net.minecraft.util` + - `ExtraCodecs` + - `gameProfileCodec` - Creates a codec for a `GameProfile` given the UUID codec. + - `$LateBoundIdMapper#values` - Returns a set of values within the mapper. + - `InclusiveRange#map` - Maps a range from one generic to another. + - `Mth#ceilLong` - Returns the double rounded up to the nearest long. +- `net.minecraft.util.random` + - `Weighted#streamCodec` - Constructs a stream codec for the weighted entry. + - `WeightedList#streamCodec` - Constructs a stream codec for the weighted list. +- `net.minecraft.util.thread.BlockableEventLoop#shouldRunAllTasks` - Returns if there are any blocked tasks. +- `net.minecraft.world.Nameable#getPlainTextName` - Returns the string of the name component. +- `net.minecraft.world.entity` + - `Avatar` - An entity that makes up the base of a player. + - `EntityReference` + - `getEntity` - Returns the entity given the type class and the level. + - Static `getEntity`, `getLivingEntity`, `getPlayer` - Returns the entity given its `EntityReference` and level. + - `EntityType` + - `MANNEQUIN` - The mannequin entity type. + - `STREAM_CODEC` - The stream codec for an entity type. + - `$Builder#notInPeaceful` - Sets the entity to not spawn in peaceful mode. + - `Entity` + - `canInteractWithLevel` - Whether the entity can interact with the current level. + - `isInShallowWater` - Returns whether the player is in water but not underwater. + - `getAvailableSpaceBelow` - Returns the amount of space in the Y direction between the entity and the collider, offset by the given value. + - `collectAllColliders` - Returns all entity collisions. + - `InsideBlockEffectType#CLEAR_FREEZE` - A in-block effect that clears the frozen ticks. + - `LivingEntity` + - `dropFromEntityInteractLootTable` - Drops loot from a table from an entity interaction. + - `shouldTakeDrowningDamage` - Whether the entity should take damage from drowning. + - `Mob#WEARING_ARMOR_UPGRADE_MATERIAL_CHANCE`, `WEARING_ARMOR_UPGRADE_MATERIAL_ATTEMPTS` - Constants for the armor material upgrade. + - `PositionMoveRotation#withRotation` - Creates a new object with the provided XY rotation. + - `Relative` + - `rotation` - Gets the set of relative rotations from the XY booleans. + - `position` - Gets the set of relative positions from the XYZ booleans. + - `direction` - Gets the set of relative deltas from the XYZ booleans. +- `net.minecraft.world.entity.ai.Brain#isBrainDead` - Returns whether the brain does not have any memories, snesors, or behaviors. +- `net.minecraft.world.entity.ai.behavior.TransportItemsBetweenContainers` - A behavior where an entity will move items between visited containers. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `VISITED_BLOCK_POSITIONS` - Important block positions visited. + - `TRANSPORT_ITEMS_COOLDOWN_TICKS` - How many ticks to wait before transporting items. + - `UNREACHABLE_TRANSPORT_BLOCK_POSITIONS` - Holds a list of positions that are impossible to get to. +- `net.minecraft.world.entity.ai.navigation.GroundPathNavigation#setCanPathToTargetsBelowSurface` - Sets whether the entity can target other entities that are underneath a non-air block below the starting position. +- `net.minecraft.world.entity.animal.coppergolem` + - `CopperGolem` - The copper golem entity. + - `CopperGolemAi` - The brain logic for the copper golem. + - `CopperGolemOxidationLevel` - A record holding the source events and textures for a given oxidation level. + - `CopperGolemOxidationLevels` - All vanilla oxidation levels. + - `CopperGolemState` - The current logic state the copper golem is in. +- `net.minecraft.world.entity.decoration` + - `HangingEntity#canCoexist` - Whether any other hanging entities are in the same position as this one. By default, makes sure that the entities are not the same entity type and not facing the same direction. + - `Mannequin` - An avatar that does not have a connected player. +- `net.minecraft.world.entity.player` + - `Player` + - `isMobilityRestricted` - Returns whether the player has the blindness effect. + - `handleShoulderEntities` - Handles the entities on the player's shoulders. + - `extractParrotVariant`, `convertParrotVariant`, `*ShoulderParrot*` - Handles the parrot on the player's shoulders. + - `PlayerModelPart#CODEC` - The codec for the model part. +- `net.minecraft.world.entity.raid.Raids#getRaidCentersInChunk` - Returns the number of raid centers in the given chunk. +- `net.minecraft.world.entity.vehicle.MinecartFurnace#addFuel` - Adds fuel to the furnace to push the entity. +- `net.minecraft.world.item` + - `BucketItem#getContent` - Returns the fluid held in the bucket. + - `Item$TooltipContext#isPeaceful` - Returns true if the difficulty is set to peaceful. + - `ToolMaterial#COPPER` - The copper tool material. + - `WeatheringCopperItems` - A record of items that represent each of the weathering copper states. +- `net.minecraft.world.item.equipment` + - `ArmorMaterials#COPPER` - The copper armor material. + - `EquipmentAssets#COPPER` - The key reference to the copper equipment asset. + - `ResolvableProfile` + - `skinPatch` - Returns the player skin reference. + - `$Static` - Uses the already resolved game profile. + - `$Dynamic` - Dynamically resolves the game profile on use. + - `$Partial` - Represents part of the game profile depending on whatever information is provided to the component. +- `net.minecraft.world.level` + - `BaseCommandBlock$CloseableCommandBlockSource` - A command source typically for a command block. + - `ChunkPos#contains` - Whether the given block position is in the chunk. + - `GameRules#RULE_SPAWNER_BLOCKS_ENABLED` - Whether spawner blocks should spawn entities. + - `Level` + - `getEntityInAnyDimension` - Gets the entity by UUID. + - `getPlayerInAnyDimension` - Gets the player by UUID. + - `hasEntities` - Returns whether the provided bounds has entities matching the type and predicate. + - `palettedContainerFactory` - Returns the factory used to create paletted containers. +- `net.minecraft.world.level.border.WorldBorder$Settings#toWorldBorder` - Constructs a world border from the settings. +- `net.minecraft.world.level.block` + - `Block#dropFromBlockInteractLootTable` - Drops the loot when interacting with a block. + - `ChestBlock` + - `chestCanConnectTo` - Returns whether the chest can merge with another block. + - `getConnectedBlockPos` - Gets the connected block position of the chest. + - `getOpenChestSound`, `getCloseChestSound` - Returns the sounds played on chest open / close. + - `getChestType` - Returns the type of the chest based on the surrounding chests. + - `ChiseledBookShelfBlock#FACING`, `SLOT_*_OCCUPIED` - The block state properties of the chiseled bookshelf. + - `CopperChestBlock` - The block for the copper chest. + - `CopperGolemStatueBlock` - The block for the copper golem statue. + - `SelectableSlotContainer` - A container whose slot can be selected based on in-game interaction. + - `ShelfBlock` - A block for the shelf. + - `SideChainPartBlock` - A helper for providing how the chain of a shelf should be displayed. + - `WeatheringCopper$WeatherState` + - `BY_ID` - The mapper of enum ordinal to state. + - `STREAM_CODEC` - The stream codec for the state. + - `next` - Gets the next state in the ordinal. + - `previous` - Gets the previous state in the ordinal. + - `WeatheringCopperBarsBlock` - The block for weathering copper bars. + - `WeatheringCopperBlocks` - A record of blocks that represent each of the weathering copper states. + - `WeatheringCopperChainBlock` - The block for weathering copper chains. + - `WeatheringCopperChestBlock` - The block for the weathering copper chest. + - `WeatheringCopperGolemStatueBlock` - The block for the weathering copper golem statue. + - `WeatheringLanternBlock` - The block for weathering lanterns. + - `WeatheringLightningRodBlock` - The block for the weathering lightning rod. +- `net.minecraft.world.level.block.entity` + - `BaseContainerBlockEntity#isLocked` - Returns whether the block entity has a lock. + - `CopperGolemStatueBlockEntity` - The block entity for the copper golem statue. + - `ListBackedContainer` - A container that is baked by a list of items. + - `ShelfBlockEntity` - The block entity for the shelf. +- `net.minecraft.world.level.block.entity.vault.VaultConfig#playerDetector` - Returns the detector used to detect specific entities. +- `net.minecraft.world.level.block.state.BlockBehaviour#shouldChangedStateKeepBlockEntity`, `$BlockStateBase#shouldChangedStateKeepBlockEntity` - Returns whether the block entity should be kept if the block is changed to a different block. +- `net.minecraft.world.level.block.state.properties.SideChainPart` - The location of where the chain of an object is connected to. +- `net.minecraft.world.level.chunk` + - `Configuration` - Configures what type of pallete should be created. + - `PalettedContainerFactory` - A factory for constructing paletted containers using the provided strategies. + - `PalettedContainerRO#bitsPerEntry` - Returns the number of bits needed to represent an entry. + - `PaletteResize#noResizeExpected` - Returns a resizer that throws an exception. +- `net.minecraft.world.level.levelgen` + - `Beardifier#EMPTY` - An instance with no pieces or junctions. + - `DensityFunction#invert` - Inverts the density output by putting the result one over the value. + - `DensityFunctions#findTopSurface` - Finds the top surface between the two bounds. + - `NoiseChunk#maxPreliminarySurfaceLevel` - Returns the largest preliminary surface level. + - `NoiseRouterData#NOISE_ZERO` - A constant containing the base noise level for layer zero in the overworld. +- `net.minecraft.world.level.levelgen.blending.Blender#isEmpty` - Returns whether there is no blending data present. +- `net.minecraft.world.level.levelgen.structure.BoundingBox` + - `encapsulating` - Returns the smallest box that includes the given boxes. + - `STREAM_CODEC` - The stream codec for the bounding box. +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure$MaxDistance` - The maximum horizontal and vertical distance the jigsaw can expand to. +- `net.minecraft.world.level.pathfinder.Path#STREAM_CODEC` - The stream codec of the path. +- `net.minecraft.world.level.portal.TeleportTransition#createDefault` - Creates the default teleport transition. +- `net.minecraft.world.level.storage.loot.LootContext` + - `$BlockEntityTarget` - Specifies targets when interacting with a block entity. + - `$EntityTarget` + - `TARGET_ENTITY` - The entity being targeted by another, typically the object dropping the loot. + - `INTERACTING_ENTITY` - The entity interacting with the object dropping the loot. + - `$ItemStackTarget` - Specifies targets when interacting or using an item stack. +- `net.minecraft.world.level.storage.loot.parameters` + - `LootContextParams` + - `TARGET_ENTITY` - The entity being targeted by another, typically the object dropping the loot. + - `INTERACTING_ENTITY` - The entity interacting with the object dropping the loot. + - `LootContextParamSets` + - `ENTITY_INTERACT` - An entity being interacted with. + - `BLOCK_INTERACT` - A block being interacted with. +- `net.minecraft.world.phys.Vec3#X_AXIS`, `Y_AXIS`, `Z_AXIS` - The unit vector in the positive direction of each axis. +- `net.minecraft.world.phys.shapes.CollisionContext` + - `alwaysCollideWithFluid` - Whether the collision detector should always collide with a fluid in its path. + - `emptyWithFluidCollisions` - Returns an empty collision context while checking for any fluid collisions. +- `net.minecraft.world.waypoints.PartialTickSupplier` - Gets the partial tick given the provided entity. + +#### List of Changes + +- `com.mojang.blaze3d.buffers.GpuBuffer#size` is now private +- `com.mojang.blaze3d.opengl` + - `DirectStateAccess` + - `bufferSubData`, `mapBufferRange`, `unmapBuffer`, `flushMappedBufferRange` now take in the buffer usage bit mask + - `create` now takes in the `GraphicsWorkarounds` + - `GlStateManager#_texImage2D`, `_texSubImage2D` now takes in a `ByteBuffer` instead of an `IntBuffer` + - `VertexArrayCache#bindVertexArray` can now take in a nullable `GlBuffer` +- `com.mojang.blaze3d.platform` + - `ClipboardManager#getClipboard`, `setClipboard` now take in a `Window` instead of the `long` handle + - `MacosUtil#exitNativeFullscreen`, `clearResizableBit`, `getNsWindow` now take in a `Window` instead of the `long` handle + - `Window#getWindow` -> `handle` +- `com.mojang.blaze3d.systems` + - `CommandEncoder#writeToTexture` now takes in a `ByteBuffer` instead of an `IntBuffer` + - `RenderSystem#flipFrame` now takes in a `Window` instead of the `long` handle + - `TimerQuery#getInstance` now returns the raw instance rather than an optional-wrapped instance +- `com.mojang.blaze3d.vertex` + - `PoseStack$Pose#set` is now public + - `VertexConsumer#addVertexWith2DPose` no longer takes in the z component +- `net.minecraft` + - `CrashReportCategory#formatLocation` now has an overload that doesn't take in the `LevelHeightAccessor` + - `DetectedVersion#createFromConstants` -> `createBuiltIn`, now public, taking in the id, name, and optional stable `boolean` + - `SharedConstants#*_PACK_FORMAT` -> `*_PACK_FORMAT_MAJOR` + - `WorldVersion` + - `packVersion` now returns a `PackFormat` + - `$Simple` now takes in a `PackFormat` for the `resourcePackVersion` and `datapackVersion` +- `net.minecraft.advancements.critereon` + - `MinMaxBounds` now requires its generic to be `Comparable` + - `min`, `max` are now default + - `unwrapPoint` -> `$Bounds#asPoint` + - `fromReader` is now public + - `$Doubles`, `$Ints` now take in `$Bounds` for its values + - `WrappedMinMaxBounds` -> `MinMaxBounds$Bounds`, not one-to-one +- `net.minecraft.client` + - `Minecraft` + - `setLevel` no longer takes in the `ReceivingLevelScreen$Reason` + - `cameraEntity` is now private + - `openChatScreen` is now public, taking in the `ChatComponent$ChatMethod` + - `setCamerEntity` can now take in a null entity + - `forceSetScreen` -> `setScreenAndShow` + - `getMinecraftSessionService` -> `services`, now returning a `Service` instance + - The `MinecraftSessionService` can be obtained via `Service#sessionService` + - `Options#invertYMouse` -> `invertMouseY` + - `User` no longer takes in the user type +- `net.minecraft.client.data.models.BlockModelGenerators` + - `condition` now has an overload that takes in an enum or boolean property + - `createLightningRod` now takes in the regular and waxed blocks + - `createIronBars` -> `createBarsAndItem`, `createBars`; not one-to-one +- `net.minecraft.client.gui.GuiGraphics#submitSignRenderState` now takes in a `Model$Simple` instead of a `Model` +- `net.minecraft.client.gui.components` + - `AbstractScrollArea#renderScrollbar` now takes in the current XY position of the cursor. + - `AbstractSelectionList` no longer takes in the header height + - `itemHeight` -> `defaultEntryHeight` + - `addEntry`, `addEntryToTop` now takes in the height of the element + - `removeEntryFromTop` no longer returns anything + - `updateSizeAndPosition` can now take in an X component + - `renderItem` now takes in the entry instead of five integers + - `renderSelection` now takes in the entry instead of four integers + - `removeEntry` no longer returns anything + - `$Entry` now implements `LayoutElement` + - `render`, `renderBack` -> `renderContent` + - `ContainerObjectSelectionList` no longer takes in the headerh height + - `EditBox#setFormatter` -> `addFormatter`, not one-to-one + - `FocusableTextWidget` now takes in a `$BackgroundFill` instead of a boolean + - `MultiLineLabel` + - `renderCentered`, `renderLeftAligned`, `renderLeftAlignedNoShadow` -> `render`, not one-to-one + - `getStyleAtCentered`, `getStyleAtLeftAligned` -> `getStyle`, not one-to-one + - `ObjectSelectionList` no longer takes in the headerh height + - `SpriteIconButton` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `sprite` is now a `WidgetSprites` + - `$Builder#sprite` now has an overload that takes in a `WidgetSprites` + - `$CenteredIcon` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `$TextAndIcon` now takes in a `WidgetSprites` instead of a `ResourceLocation`, and toolip `Component` + - `WidgetSprites` now has an overload with a single `ResourceLocation` +- `net.minecraft.client.gui.components.spectator.SpectatorGui#onMouseMiddleClick` -> `onHotbarActionKeyPressed` +- `net.minecraft.client.gui.render.state` + - `GuiElementRenderState#buildVertices` no longer takes in the `z` component + - `GuiRenderState#forEachElement` now takes in a `Consumer` instead of a `GuiRenderState$LayeredElementConsumer` +- `net.minecraft.client.gui.render.state.pip.GuiSignRenderState` now takes in a `Model$Simple` instead of a `Model` +- `net.minecraft.client.gui.screens` + - `ChatScreen` now takes in a boolean representing whether the message is a draft + - `initial` is now protected + - `EditServerScreen` -> `ManageServerScreen` + - `InBedChatScreen` now takes in the initial text and whether there is a draft mesage in the box + - `LevelLoadingScreen` now takes in a `LevelLoadTracker` and `LevelLoadingScreen$Reason` + - `PauseScreen#disconnectFromWorld` -> `Minecraft#disconnectFromWorld` + - `ReceivingLevelScreen` has been merged into `LevelLoadingScreen` + - `Screen` + - `renderWithTooltip` -> `renderWithTooltipAndSubtitles` + - `$NarratableSearchResult` is now a record + - `isValidCharacterForName` now takes in a codepoint `int` instead of a `char` +- `net.minecraft.client.gui.screens.achievement.StatsScreen` + - `initLists`, `initButtons` merged into `onStatsUpdated` + - `$ItemRow#getItem` is now protected +- `net.minecraft.client.gui.screens.dialog.DialogScreen$WarningScreen#create` now takes in a `DialogConnectionAccess` +- `net.minecraft.client.gui.screens.inventory.tooltip.ClientActivePlayersTooltip$ActivePlayersTooltip#profiles` now is a list of `PlayerSkinRenderCache$RenderInfo`s instead of `ProfileResult`s +- `net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen` + - `*_BUTTON_WIDTH` are now private + - `join` is now public +- `net.minecraft.client.gui.screens.options.OptionsScreen#CONTROLS` is now public +- `net.minecraft.client.gui.screens.packs` + - `PackSelectionModel` now takes in a `Consumer` instead of a `Runnable` + - `$EntryBase` is now public + - `TransferableSelectionList` now is a list of `$Entry`s instead of `$PackEntry`s + - `$PackEntry` is no longer static and extends `$Entry` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldScreen#openFresh`, `testWorld`, `createFromExisting` now take in a `Runnable` instead of a `Screen` + - `WorldSelectionList` now has a package-private constructor + - `getScreen` now returns a basic `Screen` + - `$WorldListEntry` is now static + - `canJoin` -> `canInteract`, not one-to-one +- `net.minecraft.client.gui.spectator.PlayerMenuItem` now only takes in the `PlayerInfo` +- `net.minecraft.client.main.GameConfig$UserData` no longer takes in the `PropertyMap`s +- `net.minecraft.client.multiplayer` + - `ClientHandshakePacketListenerImpl` now takes in a `LevelLoadTracker` + - `CommonListenerCookie` now takes in a `LevelLoadTracker`, map of seen players, and whether the insecure chat warning has been shown + - `LevelLoadStatusManager` -> `LevelLoadTracker`, not one-to-one + - `CLOSE_DELAY_MS` -> `LEVEL_LOAD_CLOSE_DELAY_MS`, now public + - `TransferState` now takes in a map of seen players and whether the insecure chat warning has been shown +- `net.minecraft.client.multiplayer.chat.ChatListener#clearQueue` -> `flushQueue` +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects#forceBrightLightmap` -> `hasEndFlashes`, not one-to-one + - `LevelEventHandler` now takes in a `ClientLevel` instead of the `Level` and `LevelRenderer` + - `LevelRenderer` + - `prepareCullFrustum` is now private + - `renderLevel` now takes in an additional `Matrix4f` for the frustum +- `net.minecraft.client.resources.WaypointStyle#validate` is now public +- `net.minecraft.client.server.IntegratedServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` +- `net.minecraft.client.sounds` + - `SoundEngine#updateCategoryVolume` no longer takes in the gain + - `SoundEngineExecutor#flush` -> `shutDown`, not one-to-one + - `SoundManager#updateSourceVolume` no longer takes in the gain +- `net.minecraft.commands.arguments.coordinates` + - `LocalCoordinates` is now a record + - `WorldCoordinate` is now a record + - `WorldCoordinates` is now a record +- `net.minecraft.commands.arguments.selector.EntitySelectorParser` + - `getDistance`, `getLevel` can now be `null` + - `*Rot*` methods now return or use `MinMaxBounds$FloatDegrees` + - Return values can be `null` +- `net.minecraft.core.Registry` + - `getRandomElementOf` -> `HolderGetter#getRandomElementOf` + - `registerForHolder` now has an additional generic, making the `Holder$Reference` returned hold the actual object type instead of the registry type +- `net.minecraft.core.component.PatchedDataComponentMap#set` now has an overload that takes in a `TypedDataComponent` +- `net.minecraft.data.worldgen.TerrainProvider` methods now use a `BoundedFloatFunction` generic instead of `ToFloatFunction` +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `spawn` now has overloads that take in some number of entities to spawn + - `setBlock` now has overloads to take in a direction for block facing + - `fail` now has an overload that takes in a string + - `GameTestRunner` now takes in whether the level should be cleared for more space to spawn between batches + - `$Builder#haltOnError` no longer takes in any parameters +- `net.minecraft.nbt.NbtUtils#addDataVersion`, `addCurrentDataVersion` now has an overload that takes in a `Dynamic` instead of a `CompoundTag` or `ValueOutput` +- `net.minecraft.network` + - `FriendlyByteBuf#readSectionPos`, `writeSectionPos` -> `SectionPos#STREAM_CODEC` + - `VarInt#MAX_VARINT_SIZE` is now public +- `net.minecraft.network.protocol.PacketUtils#ensureRunningOnSameThread` now takes in a `PacketProcessor` instead of a `BlockableEventLoop` +- `net.minecraft.network.protocol.game` + - `ClientboundAddEntityPacket#getXa`, `getYa`, `getZa` -> `getMovement` + - `ClientboundExplodePacket` now takes in a radius, block count, and the block particles to display + - `ClientboundPlayerRotationPacket` now takes in whether the XY rotation is relative + - `ClientboundSetEntityMotionPacket#getXa`, `getYa`, `getZa` -> `getMovement` +- `net.minecraft.server` + - `SPAWN_POSITION_SEARCH_RADIUS` is now public + - `MinecraftServer` now takes in a `LevelLoadListener` instead of a `ChunkProgressListenerFactory` + - `createLevels` no longer takes in a `ChunkProgressListener` + - `getSessionService`, `getProfileKeySignatureValidator`, `getProfileRepository`, `getProfileCache` -> `services`, not one-to-one + - `getProfileCache` is now `nameToIdCache`, not one-to-one + - `updateMobSpawningFlags` is now public +- `net.minecraft.server.level` + - `ChunkMap` no longer takes in the `ChunkProgressListener` + - `getTickingGenerated` -> `allChunksWithAtLeastStatus`, not one-to-one + - `broadcast`, `broadcastAndSend` -> `sendToTrackingPlayers`, `sendToTrackingPlayersFiltered`, `sendToTrackingPlayersAndSelf`; not one-to-one + - `PlayerRespawnLogic` -> `PlayerSpawnFinder`, not one-to-one + - `ServerChunkCache` no longer takes in the `ChunkProgressListener` + - `broadcastAndSend` -> `sendToTrackingPlayersAndSelf`, not one-to-one + - `broadcast` -> `sendToTrackingPlayers`, not one-to-one + - `ServerEntity` now takes in a `$Synchronizer` instead of the brodcast method references + - `ServerEntityGetter#getNearestEntity` now has an overload that takes in a `TagKey` of entities instead of a class + - `ServerLevel` no longer takes in the `ChunkProgressListener` + - `waitForChunkAndEntities` -> `waitForEntities`, not one-to-one + - `tickCustomSpawners` no longer takes in the tick friendlies `boplean` +- `net.minecraft.server.level.chunk` + - `ChunkAccess` now takes in a `PalettedContainerFactory` instead of a `Registry` +- `net.minecraft.server.level.progress` + - `ChunkProgressListener` -> `LevelLoadListener`, not one-to-one + - `ChunkProgressListenerFactory` -> `MinecraftServer#createChunkLoadStatusView`, not one-to-one + - `LoggerChunkProgressListener` -> `LoggingLevelLoadListener`, not one-to-one + - `ProcessorChunkProgressListener`, `StoringChunkProgressListener` -> `LevelLoadProgressListener`, not one-to-one +- `net.minecraft.server.packs` + - `AbstractPackResources#getMetadataFromStream` now takes in a `PackLocationInfo` + - `OverlayMetadataSection` + - `TYPE` -> `CLIENT_TYPE`, `SERVER_TYPE` + - `overlaysForVersion` now takes in a `PackFormat` instead of an integer + - `$OverlayEntry` now takes in an `InclusiveRange` instead of an `InclusiveRange` + - `isApplicable` now takes in a `PackFormat` instead of an integer +- `net.minecraft.server.packs.metadata.pack.PackMetadataSection` now takes in an `InclusiveRange` instead of the raw pack format and integer pack. + - `CODEC` -> `FALLBACK_CODEC`, now private + - `TYPE` -> `CLIENT_TYPE`, `SERVER_TYPE`, `FALLBACK_TYPE` +- `net.minecraft.server.packs.repository` + - `Pack#readPackMetadata` now takes in a `PackFormat` and `PackType` instead of an integer + - `PackCompatibility#forVersion` now takes in `PackFormat`s instead of integers +- `net.minecraft.util` + - `CubicSpline` methods and inner classes now use `BoundedFloatFunction` instead of `ToFloatFunction` + - `ExtraCodecs` + - `GAME_PROFILE_WITHOUT_PROPERTIES` -> `AUTHLIB_GAME_PROFILE`, now a `Codec` and public + - `GAME_PROFILE` -> `STORED_GAME_PROFILE`, now a `MapCodec` + - `StringRepresentable#createNameLookup` now can take in an arbitrary object and return a string + - The base overload that takes in the object array uses `getSerializedName` + - `StringUtil#isAllowedChatCharacter` now takes in an `int` codepoint instead of a `char` + - `ToFloatFunction` -> `BoundedFloatFunction` + - This still exists as a standard interface to convert some object to a `float` +- `net.minecraft.world.entity` + - `AgeableMob#finalizeSpawn` is now nullable + - `Entity` + - `startRiding(Entity)` is now final + - `startRiding(Entity, boolean)` now takes in an additional boolean of whether to trigger the game event and criteria triggers + - `killedEntity` now takes in the `DamageSource` + - `moveOrInterpolateTo` now has overloads that take in an XY rotation, a `Vec3` position, or all three as optionals + - `lerpMotion` now takes in a `Vec3` instead of three doubles + - `forceSetRotation` now takes in whether the XY rotation is relative + - `teleportSetPosition` now has an overload that takes in both the starting and end position + - `EntityReference` is now private, constructed using the `of` static constructors + - `getEntity` now takes in a `UUIDLookup` instead of a `UUIDLookup` + - `get` now takes in a `Level` instead of a `UUIDLookup` + - `EntityType` now takes in whether the entity is allowed in peaceful mode + - `create`, `loadEntityRecursive` now has an overload that takes in an `EntityType` + - `LivingEntity` + - `shouldDropLoot` now takes in the `ServerLevel` + - `dropFromLootTable` now has overloads to take in a specific loot table key and how the items should be dispensed + - `getSlotForHand` -> `InteractionHand#asEquipmentSlot` + - `Mob#shouldDespawnInPeaceful` -> `EntityType#isAllowedInPeaceful`, not one-to-one + - `Pose` now implements `StringRepresentable`, has an associated `Codec` +- `net.minecraft.world.entity.ai.village.poi` + - `PoiManager#add` now returns a `PoiRecord` + - `PoiSection#add` now returns a `PoiRecord` +- `net.minecraft.world.entity.animal.Animal#usePlayerItem` -> `Mob#usePlayerItem` +- `net.minecraft.world.entity.animal.armadillo.Armadillo#brushOffScute` now takes in an `Entity` and `ItemStack` +- `net.minecraft.world.entity.player` + - `Player` now extends `Avatar` instead of `LivingEntity` + - `DATA_SHOULDER_*` -> `DATA_SHOULDER_PARROT_*`, now private + - `oBob`, `bob` -> `ClientAvatarState#bob0`, `bob` + - `*Cloak*` -> `ClientAvatarState#*Cloak*` + - `setEntityOnShoulder` -> `ServerPlayer#setEntityOnShoulder` + - `*ShoulderEntity*` -> `ServerPlayer#*ShoulderEntity*` + - `setMainArm` -> `Avatar#setMainArm` + - `CROUCH_BB_HEIGHT`, `SWIMMING_BB_WIDTH`, `SWIMMING_BB_HEIGHT`, `STANDING_DIMENSIONS` have been moved to `Avatar` + - `POSES` -> `Avatar#POSES`, now protected + - `PlayerModelPart` now implements `StringRepresentable` +- `net.minecraft.world.entity.projectile.Projectile` + - `deflect` now takes in an `EntityReference` of the owner instead of the `Entity` itself + - `onDeflection` no longer takes in the direct `Entity` + - `checkLeftOwner` now checks if the projectile is outside the collision range only when `leftOwner` and `leftOwnerChecked` are both false + - The original logic pertaining to this method has been moved to `isOutsideOwnerCollisionRange`, which is still private +- `net.minecraft.world.entity.vehicle.MinecartBehavior#lerpMotion` now takes in a `Vec3` instead of three doubles +- `net.minecraft.world.item` + - `ItemStack#set` now has an overload that takes in a `TypedDataComponent` + - `SpawnEggItem` no longer takes in the `EntityType` + - `spawnsEntity` no longer takes in the `HolderLookup$Provider` + - `getType` no longer takes in the `HolderLookup$Provider` +- `net.minecraft.world.item.component` + - `Bees#STREAM_CODEC` now requires a `RegistryFriendlyByteBuf` + - `ResolvableProfile` is now a sealed class with a protected constructor, created through the static `createResolved`, `createUnresolved` + - `pollResolve`, `resolve`, `isResolved` -> `resolveProfile`, not one-to-one +- `net.minecraft.world.item.enchantment.effects.ExplodeEffect` now takes in a list of block particles to display +- `net.minecraft.world.level` + - `BaseCommandBlock` no longer implements `CommandSource` + - `createCommandSourceStack` now takes in a `CommandSource` + - `BaseSpawner#getoSpin` -> `getOSpin` + - `CustomSpawner#tick` no longer takes in the tick friendlies `boolean` + - `GameRules` + - `availableRules` is now public + - `$BooleanValue#create` is now public + - `$IntegerValue#create` is now public + - `Level` no longer implements `UUIDLookup` + - `explode` now takes in a weighter list of explosion particles to display + - `neighborUpdater` is now a `CollectingNeighborUpdater` + - `tickBlockEntities` is now public + - `ServerExplosion#explode` now returns the number of blocks exploded +- `net.minecraft.world.level.border` + - `BorderChangeListener` + - `onBorderSizeSet` -> `onSetSize` + - `onBorderSizeLerping` -> `onLerpSize` + - `onBorderCenterSet` -> `onSetCenter` + - `onBorderSetWarningTime` -> `onSetWarningTime` + - `onBorderSetWarningBlocks` -> `onSetWarningBlocks` + - `onBorderSetDamagePerBlock` -> `onSetDamagePerBlock` + - `onBorderSetDamageSafeZone` -> `onSetSafeZone` + - `WorldBorder` now extends `SavedData` + - `getLerpRemainingTime` -> `getLerpTime` + - `*DamageSafeZone` -> `*SafeZone` + - `DEFAULT_SETTINGS` -> `$Settings#DEFAULT` + - `createSettings` has been replaced with the `$Settings` constructor + - `$BorderExtent#getLerpRemainingTime` -> `getLerpTime` + - `$Settings` is now a record, meaning all getters now use the record format +- `net.minecraft.world.level.block` + - `BeehiveBlock#dropHoneycomb(Level, BlockPos)` -> `dropHoneyComb(ServerLevel, ItemStack, BlockState, BlockEntity, Entity, BlockPos)` + - `CaveVines#use` entity is no longer nullable + - `ChestBlock` now takes in an open and close sound + - `ChiseledBookShelfBlock` now implements `SelectableSlotContainer` + - `BOOKS_PER_ROW` is now private +- `net.minecraft.world.level.block.entity` + - `ChiseledBookShelfBlockEntity` now implements `ListBackedContainer` + - `count` -> `ListBackedContainer#count` + - `ContainerOpenersCounter` + - `isOwnContainer` is now public + - `incrementOpeners`, `decrementOpeners` now takes in a `LivingEntity` instead of a `Player` + - `getPlayersWithContainerOpen` -> `getEntitiesWithContainerOpen`, now public, not one-to-one +- `net.minecraft.world.level.block.state.BlockBehaviour` + - `getAnalogOutputSignal`, `$BlockStateBase#getAnalogOutputSignal` now takes in the direction the signal is coming from + - `$Properties#noCollission` -> `noCollision` +- `net.minecraft.world.level.block.state.properties.BlockStateProperties#CHISELED_BOOKSHELF_SLOT_*_OCCUPIED` -> `SLOT_*_OCCUPIED` +- `net.minecraft.world.level.chunk` + - `GlobalPalette#create` -> `Configuration#createPalette` + - `HashMapPalette` no longer takes in the `IdMap` + - `create` no longer takes in the `IdMap` and `PaletteResize` + - `LevelChunkSection` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `LinearPalette` no longer takes in the `IdMap` + - `create` no longer takes in the `IdMap` and `PaletteResize` + - `Palette` + - `idFor`, `read`, `write`, `getSerializedSize` now takes in an `IdMap` + - `copy` no longer takes in the `PaletteResize` + - `$Factory#create` no longer takes in the `IdMap` and `PaletteResize` + - `PalettedContainer` no longer takes in the `IdMap` + - `codec*` no longer takes in the `IdMap` + - `unpack` is now `public`, visible for testing + - `$Configuration` -> `Configuration$Simple` + - `$Strategy` -> `Strategy` + - `getConfiguration` now takes in an `int` instead of an `IdMap`, now protected + - `PalettedContainerRO` + - `pack` no longer takes in the `IdMap` + - `$PackedData` now takes in the bits per entry `int` + - `$Unpacker#read` no longer takes in the `IdMap` + - `PaletteResize` is now `public` + - `ProtoChunk` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `SingleValuePalette` no longer takes in the `IdMap` and `PaletteResize` + - `create` no longer takes in the `IdMap` and `PaletteResize` +- `net.minecraft.world.level.chunk.storage.SerializableChunkData#containerFactory` now takes in a `PalettedContainerFactory` instead of a `Registry` + - `parse` now takes in a `PalettedContainerFactory` instead of a `RegistryAccess` +- `net.minecraft.world.level.entity.UUIDLookup#getEntity` -> `lookup` +- `net.minecraft.world.level.gameevent` + - `BlockPositionSource` is now a record + - `EntityPositionSource#getUuid` is now public +- `net.minecraft.world.level.levelgen` + - `Beardifier` now takes in lists instead of iterators and a nullable `BoundingBox` + - `DensityFunctions%Coordinate` now implements `BoundedFloatFunction` instead of `ToFloatFunction` + - `NoiseRouter#initialDensityWithoutJaggedness` -> `preliminarySurfaceLevel` +- `net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement#addPieces` now takes in a `JigsawStructure$MaxDistance` instead of an integer +- `net.minecraft.world.level.levelgen.structure.structures.JigsawStructure` now takes in a `JigsawStructure$MaxDistance` instead of an integer +- `net.minecraft.world.level.pathfinder.Path` is now final +- `net.minecraft.world.level.portal.TeleportTransition#missingRespawnBlock` no longer takes in the `Entity` to get the respawn data from +- `net.minecraft.world.level.storage` + - `PrimaryLevelData` now takes in an optional wrapped `WorldBorder$Settings` + - `ServerLevelData#*WorldBorder` -> `*LegacyWorldBorderSettings`, now dealing with optional wrapped `WorldBorder$Settings` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction` + - `copyComponents` has been split to `copyComponentsFromEntity`, `copyComponentsFromBlockEntity` + - `$Source` is now an interface + - Original implementation is in `$BlockEntitySource` + - `getReferencedContextParams` -> `contextParam`, not one-to-one + - `CopyNameFunction` + - `copyName` now takes in a `$Source` instead of a `$NameSource` + - `$NameSource` -> `$Source`, now a record, not one-to-one +- `net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider` + - `CODEC` -> `MAP_CODEC`, not one-to-one + - `$Getter` -> `$Source` + - `get` now has an overload that takes in the generic + - `getReferencedContextParams` -> `contextParam`, not one-to-one +- `net.minecraft.world.phys.shapes.EntityCollisionContext` now takes in a `boolean` instead of a `Predicate` + - `EMPTY` -> `$Empty`, not one-to-one +- `net.minecraft.world.waypoints.TrackedWaypoint` + - `STREAM_CODEC` is now final + - `yawAngleToCamera` now takes in a `PartialTickSupplier` + - `pitchDirectionToCamera` now takes in a `PartialTickSupplier` + +#### List of Removals + +- `com.mojang.blaze3d.audio.Listener#setGain`, `getGain` +- `com.mojang.blaze3d.opengl` + - `GlShaderModule#compile` + - `GlStateManager` + - `_glUniform1`, `_glUniform2`, `_glUniform3`, `_glUniform4` + - `_glUniformMatrix4` + - `glActiveTexture`, `_getActiveTexture` +- `com.mojang.blaze3d.pipeline.RenderTarget#viewWidth`, `viewHeight` +- `com.mojang.blaze3d.systems.RenderSystem` + - `getQuadVertexBuffer` + - `setModelOffset`, `resetModelOffset`, `getModelOffset` +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat#BLIT_SCREEN` + - `VertexConsumer#setWhiteAlpha` +- `net.minecraft` + - `SharedConstants#VERSION_STRING` + - `Util#getVmArguments` +- `net.miencraft.advancements.critereon.MinMaxBounds$BoundsFactory`, `$BoundsFromReaderFactory` +- `net.minecraft.client` + - `Camera#FOG_DISTANCE_SCALE` + - `Minecraft` + - `getProgressListener` + - `getProfileKeySignatureValidator`, `canValidateProfileKeys` + - `Options#RENDER_DISTANCE_TINY`, `RENDER_DISTANCE_NORMAL` + - `User#getType`, `$Type` +- `net.minecraft.client.gui.components` + - `AbstractSelectionList` + - `headerHeight`, associated constructor has been removed + - `setSelectedIndex`, `getFirstElement`, `getEntry` + - `isSelectedItem` + - `renderHeader`, `renderDecorations` + - `ensureVisible` + - `remove` + - `OptionsList#getMouseOver` + - `StringWidget#alignLeft`, `alignCenter`, alignRight` +- `net.minecraft.client.gui.render.state.GuiRenderState` + - `down`, `$Node#down` + - `$LayeredElementConsumer` +- `net.minecraft.client.gui.screens.LevelLoadingScreen#renderChunks` +- `net.minecraft.client.gui.screens.achievement.StatsScreen#setActiveList` +- `net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen` + - `BUTTON_ROW_WIDTH`, `FOOTER_HEIGHT` + - `setSelected` + - `joinSelectedServer` +- `net.minecraft.client.main.GameConfig$UserData#userProperties`, `profileProperties` +- `net.minecraft.client.renderer.chunk.ChunkSectionLayer#outputTarget` +- `net.minecraft.client.resources.SkinManager#getInsecureSkin` +- `net.minecraft.gametest.framework.GameTestTicker#startTicking` +- `net.minecraft.network.syncher.EntityDataSerializers#COMPOUND_TAG` +- `net.minecraft.server.MinecraftServer#getSpawnRadius` +- `net.minecraft.server.dedicated.DedicatedServer#storeUsingWhiteList` +- `net.minecraft.server.level` + - `ServerChunkCache#getTickingGenerated` + - `ServerPlayer#loadGameTypes` +- `net.minecraft.server.packs.resources.ResourceMetadata` + - `copySections` + - `$Builder` +- `net.minecraft.world.entity.Entity` + - `spawnAtLocation(ServerLevel, ItemLike, int)` + - `getServer` +- `net.minecraft.world.entity.decoration.HangingEntity#HANGING_ENTITY` +- `net.minecraft.world.entity.item.ItemEntity#copy` +- `net.minecraft.world.entity.monster` + - `Creeper#canDropMobsSkull`, `increaseDroppedSkulls` + - `Zombie#getSkull` +- `net.minecraft.world.entity.player.Player` + - `getScoreboard` + - `isModelPartShown` +- `net.minecraft.world.entity.vehicle.MinecartTNT#explode(double)` +- `net.minecraft.world.item.Item#verifyComponentsAfterLoad` +- `net.minecraft.world.level` + - `BlockGetter#MAX_BLOCK_ITERATIONS_ALONG_TRAVEL` + - `GameRules#RULE_SPAWN_CHUNK_RADIUS` +- `net.minecraft.world.level.border` + - `BorderChangeListener$DelegateBorderChangeListener` + - `WorldBorder` + - `closestBorder` + - `$DistancePerDirection` + - `$Settings#read`, `write` +- `net.minecraft.world.level.block.FletchingTableBlock` +- `net.minecraft.world.level.block.entity.SkullBlockEntity` + - `CHECKED_MAIN_THREAD_EXECUTOR` + - `setup`, `clear` + - `fetchGameProfile` + - `setOwner` +- `net.minecraft.world.level.portal.TeleportTransition(ServerLevel, Entity, TeleportTransition.PostTeleportTransition)` +- `net.minecraft.world.level.storage.loot.providers.nbt.ContextNbtProvider` + - `BLOCK_ENTITY` + - `$Getter#getId` + +### Step 8: 1.21.9 -> 1.21.10 + +## Minecraft 1.21.9 -> 1.21.10 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.9 to 1.21.10. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @melanx for a typo + +### 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](https://misode.github.io/versions/?id=1.21.10&tab=changelog). + +### 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. + +#### List of Additions + +- `net.minecraft.world.entity.decoration.HangingEntity#getPopBox` - Returns the bounding box indicating where the entity will pop off if colliding. + +#### List of Changes + +`net.minecraft.world.level.block.state.BlockBehaviour#entityInside` now takes in a `boolean` indicating whether the entity is intersecting or inside the block + +### Step 9: 1.21.10 -> 1.21.11 + +## Minecraft 1.21.10 -> 1.21.11 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.10 to 1.21.11. 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](http://creativecommons.org/licenses/by/4.0/), 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: + +- @xfacthd for some educated guesses regarding the usage annotations +- @dinnerbone for pointing out gizmos can also be submitted on the server in singleplayer worlds +- @thatgravyboat for pointing out the change in parameter orders for `Mth#clampedLerp` + +### 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](https://misode.github.io/versions/?id=1.22&tab=changelog). + +### The Rename Shuffle + +Many core classes, method, and parameters have been shuffled around and renamed while still retaining their individual function. The following is a list of the most important changes + +#### `ResourceLocation` to `Identifier` + +All references to `ResourceLocation`, whether in method names, parameters, or other classes, have been replaced with `Identifier`. + +#### The `util` Package + +Most utility classes have been moved to `net.minecraft.util`. These will need to be reimported. + +#### `critereon` to `criterion` + +`net.minecraft.advancements.critereon` has been renamed to `net.minecraft.advancements.criterion`. These will need to be reimported. + +#### Entity and Object Subpackages + +Both `net.minecraft.client.model` and `net.minecraft.world.entity` have been reorganized into additional subpackages based on the type of backing object. These will need to be reimported. + +- `net.minecraft` + - `BlockUtil` -> `.util.BlockUtil` + - `FileUtil` -> `.util.FileUtil` + - `ResourceLocationException` -> `IdentifierException` + - `Util` -> `.util.Util` +- `net.minecraft.advancements.critereon` -> `.advancements.criterion` +- `net.minecraft.client.gui.screens.inventory.JigsawBlockEditScreen#isValidResourceLocation` -> `isValidIdentifier` +- `net.minecraft.client.model` + - `AbstractBoatModel` -> `.object.boat.AbstractBoatModel` + - `AbstractEquineModel` -> `.animal.equine.AbstractEquineModel` + - `AbstractPiglinModel` -> `.monster.piglin.AbstractPiglinModel` + - `AbstractZombieModel` -> `.monster.zombie.AbstractZombieModel` + - `AllayModel` -> `.animal.allay.AllayModel` + - `ArmadilloModel` -> `.animal.armadillo.ArmadilloModel` + - `ArmorStandArmorModel` -> `.object.armorstand.ArmorStandArmorModel` + - `ArmorStandModel` -> `.object.armorstand.ArmorStandModel` + - `ArrowModel` -> `.object.projectile.ArrowModel` + - `AxolotlModel` -> `.animal.axolotl.AxolotlModel` + - `BannerFlagModel` -> `.object.banner.BannerFlagModel` + - `BannerModel` -> `.object.banner.BannerModel` + - `BatModel` -> `.ambient.BatModel` + - `BeeModel` -> `.animal.bee.BeeModel` + - `BeeStingerModel` -> `.animal.bee.BeeStingerModel` + - `BellModel` -> `.object.bell.BellModel` + - `BlazeModel` -> `.monster.blaze.BlazeModel` + - `BoatModel` -> `.object.boat.BoatModel` + - `BoggedModel` -> `.monster.skeleton.BoggedModel` + - `BookModel` -> `.object.book.BookModel` + - `BreezeModel` -> `.monster.breeze.BreezeModel` + - `CamelModel` -> `.animal.camel.CamelModel` + - `CamelSaddleModel` -> `.animal.camel.CamelSaddleModel` + - `CatModel` -> `.animal.feline.CatModel` + - `ChestModel` -> `.object.chest.ChestModel` + - `ChickenModel` -> `.animal.chicken.ChickenModel` + - `CodModel` -> `.animal.fish.CodModel` + - `ColdChickenModel` -> `.animal.chicken.ColdChickenModel` + - `ColdCowModel` -> `.animal.cow.ColdCowModel` + - `ColdPigModel` -> `.animal.pig.ColdPigModel` + - `CopperGolemModel` -> `.animal.golem.CopperGolemModel` + - `CopperGolemStatueModel` -> `.object.statue.CopperGolemStatueModel` + - `CowModel` -> `.animal.cow.CowModel` + - `CreakingModel` -> `.monster.creaking.CreakingModel` + - `CreeperModel` -> `.monster.creeper.CreeperModel` + - `DolphinModel` -> `.animal.dolphin.DolphinModel` + - `DonkeyModel` -> `.animal.equine.DonkeyModel` + - `DrownedModel` -> `.monster.zombie.DrownedModel` + - `ElytraModel` -> `.object.equipment.ElytraModel` + - `EndCrystalModel` -> `.object.crystal.EndCrystalModel` + - `EndermanModel` -> `.monster.enderman.EndermanModel` + - `EndermiteModel` -> `.monster.endermite.EndermiteModel` + - `EquineSaddleModel` -> `.animal.equine.EquineSaddleModel` + - `EvokerFangsModel` -> `.effects.EvokerFangsModel` + - `FelineModel` -> `.animal.feline.FelineModel` + - `FoxModel` -> `.animal.fox.FoxModel` + - `FrogModel` -> `.animal.frog.FrogModel` + - `GhastModel` -> `.monster.ghast.GhastModel` + - `GiantZombieModel` -> `.monster.zombie.GiantZombieModel` + - `GoatModel` -> `.animal.goat.GoatModel` + - `GuardianModel` -> `.monster.guardian.GuardianModel` + - `GuardianParticleModel` -> `.monster.guardian.GuardianParticleModel` + - `HappyGhastHarnessModel` -> `.animal.ghast.HappyGhastHarnessModel` + - `HappyGhastModel` -> `.animal.ghast.HappyGhastModel` + - `HoglinModel` -> `.monster.hoglin.HoglinModel` + - `HorseModel` -> `.animal.equine.HorseModel` + - `IllagerModel` -> `.monster.illager.IllagerModel` + - `IronGolemModel` -> `.animal.golem.IronGolemModel` + - `LavaSlimeModel` -> `.monster.slime.MagmaCubeModel` + - `LeashKnotModel` -> `.object.leash.LeashKnotModel` + - `LlamaModel` -> `.animal.llama.LlamaModel` + - `LlamaSpitModel` -> `.animal.llama.LlamaSpitModel` + - `MinecartModel` -> `.object.cart.MinecartModel` + - `OcelotModel` -> `.animal.feline.OcelotModel` + - `PandaModel` -> `.animal.panda.PandaModel` + - `ParrotModel` -> `.animal.parrot.ParrotModel` + - `PhantomModel` -> `.monster.phantom.PhantomModel` + - `PiglinHeadModel` -> `.object.skull.PiglinHeadModel` + - `PiglinModel` -> `.monster.piglin.PiglinModel` + - `PigModel` -> `.animal.pig.PigModel` + - `PlayerCapeModel` -> `.player.PlayerCapeModel` + - `PlayerEarsModel` -> `.player.PlayerEarsModel` + - `PlayerModel` -> `.player.PlayerModel` + - `PolarBearModel` -> `.animal.polarbear.PolarBearModel` + - `PufferfishBigModel` -> `.animal.fish.PufferfishBigModel` + - `PufferfishMidModel` -> `.animal.fish.PufferfishMidModel` + - `PufferfishSmallModel` -> `.animal.fish.PufferfishSmallModel` + - `RabbitModel` -> `.animal.rabbit.RabbitModel` + - `RaftModel` -> `.object.boat.RaftModel` + - `RavagerModel` -> `.monster.ravager.RavagerModel` + - `SalmonModel` -> `.animal.fish.SalmonModel` + - `SheepFurModel` -> `.animal.sheep.SheepFurModel` + - `SheepModel` -> `.animal.sheep.SheepModel` + - `ShieldModel` -> `.object.equipment.ShieldModel` + - `ShulkerBulletModel` -> `.object.projectile.ShulkerBulletModel` + - `ShulkerModel` -> `.monster.shulker.ShulkerModel` + - `SilverfishModel` -> `.monster.silverfish.SilverfishModel` + - `SkeletonModel` -> `.monster.skeleton.SkeletonModel` + - `SkullModel` -> `.object.skull.SkullModel` + - `SkullModelBase` -> `.object.skull.SkullModelBase` + - `SlimeModel` -> `.monster.slime.SlimeModel` + - `SnifferModel` -> `.animal.sniffer.SnifferModel` + - `SnowGolemModel` -> `.animal.golem.SnowGolemModel` + - `SpiderModel` -> `.monster.spider.SpiderModel` + - `SpinAttackEffectModel` -> `.effects.SpinAttackEffectModel` + - `SquidModel` -> `.animal.squid.SquidModel` + - `StriderModel` -> `.monster.strider.StriderModel` + - `TadpoleModel` -> `.animal.frog.TadpoleModel` + - `TridentModel` -> `.object.projectile.TridentModel` + - `TropicalFishModelA` -> `.animal.fish.TropicalFishSmallModel` + - `TropicalFishModelB` -> `.animal.fish.TropicalFishLargeModel` + - `TurtleModel` -> `.animal.turtle.TurtleModel` + - `VexModel` -> `.monster.vex.VexModel` + - `VillagerModel` -> `.npc.VillagerModel` + - `WardenModel` -> `.monster.warden.WardenModel` + - `WarmCowModel` -> `.animal.cow.WarmCowModel` + - `WindChargeModel` -> `.object.projectile.WindChargeModel` + - `WitchModel` -> `.monster.witch.WitchModel` + - `WitherBossModel` -> `.monster.wither.WitherBossModel` + - `WolfModel` -> `.animal.wolf.WolfModel` + - `ZombieModel` -> `.monster.zombie.ZombieModel` + - `ZombieVillagerModel` -> `.monster.zombie.ZombieVillagerModel` + - `ZombifiedPiglinModel` -> `.monster.piglin.ZombifiedPiglinModel` +- `net.minecraft.client.model.dragon` + - `DragonHeadModel` -> `.model.object.skull.DragonHeadModel` + - `EnderDragonModel` -> `.model.monster.dragon.EnderDragonModel` +- `net.minecraft.client.resources.sounds` + - `AbstractSoundInstance#location` -> `identifier` + - `SoundInstance#getLocation` -> `getIdentifier` +- `net.minecraft.client.searchtree` + - `IdSearchTree` + - `resourceLocationSearchTree` -> `identifierSearchTree` + - `searchResourceLocation` -> `searchIdentifier` + - `ResourceLocationSearchTree` -> `IdentifierSearchTree` +- `net.minecraft.commands.arguments.ResourceLocationArgument` -> `IdentifierArgument` +- `net.minecraft.network.FriendlyByteBuf#readResourceLocation`, `writeResourceLocation` -> `readIdentifier`, `writeIdentifier` +- `net.minecraft.resources` + - `ResourceKey#location` -> `identifier` + - `ResourceLocation` -> `Identifier` +- `net.minecraft.util.ResourceLocationPattern` -> `IdentifierPattern` +- `net.minecraft.util.parsing.packrat.commands.ResourceLocationParseRule` -> `IdentifierParseRule` +- `net.minecraft.world.entity.GlowSquid` -> `.animal.squid.GlowSquid` +- `net.minecraft.world.entity.animal` + - `AbstractCow` -> `.cow.AbstractCow` + - `AbstractFish` -> `.fish.AbstractFish` + - `AbstractGolem` -> `.golem.AbstractGolem` + - `AbstractSchoolingFish` -> `.fish.AbstractSchoolingFish` + - `Bee` -> `.bee.Bee` + - `Cat` -> `.feline.Cat` + - `CatVariant` -> `.feline.CatVariant` + - `CatVariants` -> `.feline.CatVariants` + - `Chicken` -> `.chicken.Chicken` + - `ChickenVariant` -> `.chicken.ChickenVariant` + - `ChickenVariants` -> `.chicken.ChickenVariants` + - `Cod` -> `.fish.Cod` + - `Cow` -> `.cow.Cow` + - `CowVariant` -> `.cow.CowVariant` + - `CowVariants` -> `.cow.CowVariants` + - `Dolphin` -> `.dolphin.Dolphin` + - `Fox` -> `.fox.Fox` + - `HappyGhast` -> `.happyghast.HappyGhast` + - `HappyGhastAi` -> `.happyghast.HappyGhastAi` + - `IronGolem` -> `.golem.IronGolem` + - `MushroomCow` -> `.cow.MushroomCow` + - `Ocelot` -> `.feline.Ocelot` + - `Panda` -> `.panda.Panda` + - `Parrot` -> `.parrot.Parrot` + - `Pig` -> `.pig.Pig` + - `PigVariant` -> `.pig.PigVariant` + - `PigVariants` -> `.pig.PigVariants` + - `PolarBear` -> `.polarbear.PolarBear` + - `Pufferfish` -> `.fish.Pufferfish` + - `Rabbit` -> `.rabbit.Rabbit` + - `Salmon` -> `.fish.Salmon` + - `ShoulderRidingEntity` -> `.parrot.ShoulderRidingEntity` + - `SnowGolem` -> `.golem.SnowGolem` + - `Squid` -> `.squid.Squid` + - `TropicalFish` -> `.fish.TropicalFish` + - `Turtle` -> `.turtle.Turtle` + - `WaterAnimal` -> `.fish.WaterAnimal` +- `net.minecraft.world.entity.animal.coppergolem.*` -> `.animal.golem.*` +- `net.minecraft.world.entity.animal.horse.*` -> `.animal.equine.*` +- `net.minecraft.world.entity.boss.EnderDragonPart` -> `.enderdragon.EnderDragonPart` +- `net.minecraft.world.entity.decoration` + - `Painting` -> `.painting.Painting` + - `PaintingVariant` -> `.painting.PaintingVariant` + - `PaintingVariants` -> `.painting.PaintingVariants` +- `net.minecraft.world.entity.monster` + - `AbstractIllager` -> `.illager.AbstractIllager` + - `AbstractSkeleton` -> `.skeleton.AbstractSkeleton` + - `Bogged` -> `.skeleton.Bogged` + - `CaveSpider` -> `.spider.CaveSpider` + - `Drowned` -> `.zombie.Drowned` + - `Evoker` -> `.illager.Evoker` + - `Husk` -> `.zombie.Husk` + - `Illusioner` -> `.illager.Illusioner` + - `Parched` -> `.skeleton.Parched` + - `Pillager` -> `.illager.Pillager` + - `Skeleton` -> `.skeleton.Skeleton` + - `SpellcasterIllager` -> `.illager.SpellcasterIllager` + - `Spider` -> `.spider.Spider` + - `Stray` -> `.skeleton.Stray` + - `Vindicator` -> `.illager.Vindicator` + - `WitherSkeleton` -> `.skeleton.WitherSkeleton` + - `Zombie` -> `.zombie.Zombie` + - `ZombieVillager` -> `.zombie.ZombieVillager` + - `ZombifiedPiglin` -> `.zombie.ZombifiedPiglin` +- `net.minecraft.world.entity.npc` + - `AbstractVillager` -> `.villager.AbstractVillager` + - `Villager` -> `.villager.Villager` + - `VillagerData` -> `.villager.VillagerData` + - `VillagerDataHolder` -> `.villager.VillagerDataHolder` + - `VillagerProfession` -> `.villager.VillagerProfession` + - `VillagerTrades` -> `.villager.VillagerTrades` + - `VillagerType` -> `.villager.VillagerType` + - `WanderingTrader` -> `.wanderingtrader.WanderingTrader` + - `WanderingTraderSpawner` -> `.wanderingtrader.WanderingTraderSpawner` +- `net.minecraft.world.entity.projectile` + - `AbstractArrow` -> `.arrow.AbstractArrow` + - `AbstractHurtingProjectile` -> `.hurtingprojectile.AbstractHurtingProjectile` + - `AbstractThrownPotion` -> `.throwableitemprojectile.AbstractThrownPotion` + - `Arrow` -> `.arrow.Arrow` + - `DragonFireball` -> `.hurtingprojectile.DragonFireball` + - `Fireball` -> `.hurtingprojectile.Fireball` + - `LargeFireball` -> `.hurtingprojectile.LargeFireball` + - `SmallFireball` -> `.hurtingprojectile.SmallFireball` + - `Snowball` -> `.throwableitemprojectile.Snowball` + - `SpectralArrow` -> `.arrow.SpectralArrow` + - `ThrowableItemProjectile` -> `.throwableitemprojectile.ThrowableItemProjectile` + - `ThrownEgg` -> `.throwableitemprojectile.ThrownEgg` + - `ThrownEnderpearl` -> `.throwableitemprojectile.ThrownEnderpearl` + - `ThrownExperienceBottle` -> `.throwableitemprojectile.ThrownExperienceBottle` + - `ThrownLingeringPotion` -> `.throwableitemprojectile.ThrownLingeringPotion` + - `ThrownSplashPotion` -> `.throwableitemprojectile.ThrownSplashPotion` + - `ThrownTrident` -> `.arrow.ThrownTrident` + - `WitherSkull` -> `.hurtingprojectile.WitherSkull` +- `net.minecraft.world.entity.projectile.windcharge.*` -> `.projectile.hurtingprojectile.windcharge.*` +- `net.minecraft.world.entity.vehicle` + - `AbstractBoat` -> `.boat.AbstractBoat` + - `AbstractChestBoat` -> `.boat.AbstractChestBoat` + - `AbstractMinecart` -> `.minecart.AbstractMinecart` + - `AbstractMinecartContainer` -> `.minecart.AbstractMinecartContainer` + - `Boat` -> `.boat.Boat` + - `ChestBoat` -> `.boat.ChestBoat` + - `ChestRaft` -> `.boat.ChestRaft` + - `Minecart` -> `.minecart.Minecart` + - `MinecartBehavior` -> `.minecart.MinecartBehavior` + - `MinecartChest` -> `.minecart.MinecartChest` + - `MinecartCommandBlock` -> `.minecart.MinecartCommandBlock` + - `MinecartFurnace` -> `.minecart.MinecartFurnace` + - `MinecartHopper` -> `.minecart.MinecartHopper` + - `MinecartSpawner` -> `.minecart.MinecartSpawner` + - `MinecartTNT` -> `.minecart.MinecartTNT` + - `NewMinecartBehavior` -> `.minecart.NewMinecartBehavior` + - `OldMinecartBehavior` -> `.minecart.OldMinecartBehavior` + - `Raft` -> `.boat.Raft` +- `net.minecraft.world.level.gamerules.GameRule#getResourceLocation` -> `getIdentifier` + +### Oh Hey, Another Rendering Rewrite + +More of the rendering pipeline has been rewritten, with the majority focused on samplers, `RenderType` creation, and mipmaps. + +#### The Separation of Samplers + +Blaze3d has separated setting the `AddressMode`s and `FilterMode`s when reading texture data into `GpuSampler`. As the name implies, a `GpuSampler` defines how to sample data from a buffer, such as a texture. `GpuSampler` contains four methods: `getAddressModeU` / `getAddressModeV` for determining how the sampler should behave when reading the UV positions (either repeat or clamp), `getMinFilter` / `getMagFilter` for determining how to minify or magnify the texture respectively (either nearest neighbor or linear), `getMaxAnisotropy` for the largest anisotropic filtering level that can be used, and `getMaxLod` for the maximum level-of-detail on a texture. + +Samplers can be created via `GpuDevice#createSampler`, but that is not necessary unless you want to specify a different anisotropic filtering level greater than `1`, or a maximum level-of-detail that is not `0` or `1000`. If the default, as there are only 32 possible combinations, vanilla creates all `GpuSampler`s and stores them in a cache, accessible via `RenderSystem#getSamplerCache`, followed by `SamplerCache#getSampler`: + +```java +// Raw call +GpuSampler sampler = RenderSystem.getDevice().createSampler( + // U address mode + AddressMode.CLAMP_TO_EDGE, + // V address mode + AddressMode.CLAMP_TO_EDGE, + // Minification filter + FilterMode.LINEAR, + // Magnification filter + FilterMode.NEAREST, + // The maximum anisotropic filtering level + // Vanilla uses either 1, 2, 4, or 8 for level rendering + 4f, + // The maximum level of detail for a texture + // Vanilla either uses an 0 for the default, + // or an empty optional for moving objects and + // uploading to an atlas. + OptionalDouble.of(0.0) +); + +// Sampler cache method +GpuSampler sampler = RenderSystem.getSamplerCache().getSampler( + // U address mode + AddressMode.CLAMP_TO_EDGE, + // V address mode + AddressMode.CLAMP_TO_EDGE, + // Minification filter + FilterMode.LINEAR, + // Magnification filter + FilterMode.NEAREST, + // Whether to use 1000 or 0 for the maximum level-of-detail + true +); +``` + +To make user of the sampler for a texture, when binding the texture in a render pass (via `RenderPass#bindTexture`), you must now specify the sampler to use in addition to the texture view: + +```java +try (RenderPass pass = RenderSystem.getDevice().createCommandEncoder().createRenderPass(...)) { + // Set other parameters + pass.bindTexture( + // The name of the sampler2D uniform, usually in the fragment shader + "Sampler0", + // The texture to sample + ..., + // The sampler to use + sampler + ); + + // Draw buffer +} +``` + +Setting up the post processor has not changed from the user perspective as only clamp to edge address modes may be selected. + +#### The `RenderType` Shuffle + +Creating a `RenderType` has been reworked to some degree. While most of the features from the previous implementation still exist, they have been changed to match the new rendering system where direct OpenGL is abstracted away and only accessed through their defined pipelines and `RenderSystem`. + +##### Existing Types + +Existing types have been moved from `RenderType` to `RenderTypes` (e.g., `RenderType#solid` -> `RenderTypes#solid`). + +##### Custom Types + +Originally, to create a `RenderType`, you would construct a `$CompositeState` using `RenderStateShard`s. Each `RenderStateShard` would define how the pass should be setup and teardown when building some mesh, whether that was setting textures, the render target, model transforms, etc. Then, the `$CompositeState` would be built for use in whatever rendering application was needed. + +The new system splits the render definition in two: the `RenderSetup`, and our `RenderType`. The `RenderSetup`, as the name implies, sets up the renderer to be used when drawing to a texture. Teardown is completely removed as it is either handled directly when drawing the `RenderType` or uses newly constructed states that can just be thrown away. `RenderType`, on the other hand, is simply a named `RenderSetup`. It only handles drawing the mesh data and making some fields of the setup public for use in other buffer implementations. Multiple types can have the same `RenderSetup` as a number of existing types dynamically populate the texture used by the sampler and/or the outline of the object. + +A `RenderSetup` can be created through its builder via `RenderSetup#Builder`, supply the `RenderPipeline` to use. Once the builder properties are set, the actual setup can be created via `RenderSetup$RenderSetupBuilder#createRenderSetup`: + +```java +public static final RenderSetup EXAMPLE_SETUP = RenderSetup.builder( + // The pipeline to use. + // This can affect what settings are allowed from the setup. + RenderPipelines.ITEM_ENTITY_TRANSLUCENT_CULL +) + // Specifies the texture to bind to the provided sampler. + // The sampler must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + // The texture is represented as an absolute location. + .withTexture( + // 'Sampler0' is defined by the pipeline. + "Sampler0", + // Points to 'assets/minecraft/entity/wolf/wolf_armor_crackiness_low.png'. + Identifier.withDefaultNamespace("textures/entity/wolf/wolf_armor_crackiness_low.png"), + // An optional supplied `GpuSampler` to sample the texture with. + // The returned value with be cached after first resolution. + () -> RenderSystem.getSamplerCache().getClampToEdge(FilterMode.NEAREST) + ) + // When set, allows the pipeline to use the light texture. + // 'Sampler2' must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + .useLightmap() + // When set, allows the pipeline to use the overlay texture. + // 'Sampler1' must be defined by the pipeline via `RenderPipeline$Builder#withSampler`. + .useOverlay() + // When set, uses `RenderTypes#crumbling` to overlay the block destroy stages + // based on the crumbling progress for an entity model. + // This is only implemented in `ModelFeatureRenderer`. + .affectsCrumbling() + // When set, sorts the quads based on the set `ProjectionType` in + // `RenderSystem#getProjectionType`. + // This is only implemented when getting the buffers from `MultiBufferSource$BufferSource`. + .sortOnUpload() + // Sets the initial capacity of the used buffer. + // This is only used when constructing the initial buffers in `RenderBuffers` + // All custom applications of sources already have some defined buffer with the determined size. + .bufferSize(786432) + // An object-wrapped consumer that transforms the model view matrix. + // Vanilla implementations exist in `LayeringTransform`, applying + // the transformation through the projection type: + // - `NO_LAYERING`: Do nothing. + // - `VIEW_OFFSET_Z_LAYERING`: Offsets the Z by 1 based on its `ProjectionType` + // - `VIEW_OFFSET_Z_LAYERING_FORWARD`: Offsets the Z by -11 based on its `ProjectionType` + .setLayeringTransform( + // We can also construct a new transform + new LayeringTransform( + // The name of the transform + "examplemod:example_layer", + // The transform should not push or pop to the stack + // Only translate, scale, or rotate + stack -> stack.translate(0f, 0.1f, 0f) + ) + ) + // Sets the output target that this setup should write to, + // unless overridden by the `RenderSystem#output*Override` textures. + // This is typically the main target, though it can be other vanilla + // targets or a custom one if you plan to handle it. + .setOutputTarget(OutputTarget.MAIN_TARGET) + // An object-wrapped supplier that provides the texture matrix. + // This is typically used to modify the texture UV coordinates + // in the vertex shader before sampling in the fragment shader. + // Vanilla only uses this for the glint effect and breeze/energy: + // - `DEFAULT_TEXTURING`: Do nothing. + // - `GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 8. + // - `ENTITY_GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 0.5. + // - `ARMOR_ENTITY_GLINT_TEXTURING`: Translates based on the glint speed, rotates pi/18, and scales by 0.16. + // - `$OffsetTextureTransform`: Translates the texture by the provided XY coordinates. + .setTextureTransform( + // We can also construct a new transform + new TextureTransform( + // The name of the transform + "examplemod:example_texture", + // The transform to apply to the texture + () -> new Matrix4f().translation(0f, 1f, 0f).scale(1.5f) + ) + ) + // Sets how an outline of the mesh should be handled: + // - `NONE`: Do nothing. + // - `IS_OUTLINE`: This is an outline and should write to the outline buffer source. + // - `AFFECTS_OUTLINE`: This defines the shape of the outline and should use `RenderTypes#OUTLINE` to draw it. + // Checked when writing to the outline buffer source or, + // if the outline color for a feature is not 0 + .setOutline(RenderSetup.OutlineProperty.AFFECTS_OUTLINE) + // Builds the setup for use in a render type. + .createRenderSetup(); +``` + +Then, the `RenderType` can be created via `create`. + +```java +public static final RenderType EXAMPLE_TYPE = RenderType.create( + // The name of the type for debugging + "examplemod:example_type", + // The render setup to use + EXAMPLE_SETUP +); +``` + +`MeshData` can be written to the output target using `RenderType#draw`. + +#### Mipmap Strategy Metadata + +A texture's `mcmeta` can now specify the `mipmap_strategy` to use in the `textures` section. There are four available strategies, with `auto` defaulting to `mean` if there is no transparency, an `cutout` when there is transparency. + +| Strategy | Description | +|:---------------:|:-------------------------------------------------------------------------------------------------------------------------------| +| `mean` | The default that averages the color between four pixels for the current mipmap level. | +| `cutout` | `mean`, except that all levels are generated from the original texture, with alpha snapped to 0 or 1 using a threshold of 0.2. | +| `strict_cutout` | `cutout`, except that it sets the alpha snaps using a threshold of `0.6`. | +| `dark_cutout` | `mean`, except that the surrounding pixels are only included in the average if their alpha is not `0`. | + +```json5 +// In `assets/examplemod/textures/block/example/example_block.png.mcmeta +{ + "texture": { + // Uses the chosen strategy + "mipmap_strategy": "cutout", + // Determines how much the cutoff should be biased + // when determining whether a pixel is either fully + // opaque or transparent. + // Larger numbers means higher alpha cutoff while + // lower values use a lower alpha cutoff. + "alpha_cutoff_bias": 0.2 + } +} +``` + +#### Block and Terrain Split + +`RenderPipeline`s that were used by both a standalone block and the terrain has been split into separate pipelines: one with prefix `_BLOCK` and `_TERRAIN`, respectively. This includes the solid, cutout, translucent, and tripwire pipelines. No block variant exists for the translucent pipeline. + +#### Item Atlases + +The block atlas no longer contains textures specifically for items. Those have been moved to their own atlas named `minecraft:items`, with the id stored at `AtlasIds#ITEMS`. + +If a given `Material` can use both block and item textures, then it should be supplied with the `ModelManager#BLOCK_OR_ITEM` special case. + +- `com.mojang.blaze3d.buffers` + - `GpuBuffer`, `size` now uses a `long` for the size + - `slice` now uses `long`s for the length and offset + - `GpuBufferSlice` now uses `long`s for the length and offset +- `com.mojang.blaze3d.opengl` + - `BufferStorage` + - `createBuffer` now uses in a `long` for the size + - `mapBuffer` now uses `long`s for the length and offset + - `DirectStateAccess` + - `bufferSubData` now uses in a `long` for the offset + - `mapBufferRange`, `flushMappedBufferRange`, `copyBufferSubData` now use `long`s for the length and offset + - `GlBuffer` now uses a `long` for the size + - `GlDevice` now takes in a `ShaderSource` instead of a `BiFunction` + - `getOrCompileShader` now takes in a `ShaderSource` instead of a `BiFunction` + - `GlRenderPass` + - `samplers` now is a hash map of strings to `GlRenderPass$TextureViewAndSampler`s + - `$TextureViewAndSampler` - A record that defines a sampler with its sampled texture. + - `GlSampler` - The OpenGL implementation of a gpu sampler. + - `GlStateManager` + - `_glBufferSubData` now uses in a `long` for the offset + - `_glMapBufferRange` now uses `long`s for the length and offset + - `GlTexture#modesDirty`, `flushModeChanges` are removed + - `GlTextureView#getFbo` - Gets the framebuffer object of a texture, using the cache if present. +- `com.mojang.blaze3d.pipeline.RenderTarget#filterMode`, `setFilterMode` are removed +- `com.mojang.blaze3d.platform.TextureUtil` + - `solidify` - Modifies the texture by packing and unpacking the pixels to better help with non-darkened interiors within mipmaps. + - `fillEmptyAreasWithDarkColor` - Sets empty pixels to an empty pixel whose RGB value is the darkest color in the image. +- `com.mojang.blaze3d.shaders.ShaderSource` - A functional interface that gets the shader source from its id and type as a string. +- `com.mojang.blaze3d.systems` + - `CommandEncoder#copyTextureToBuffer` now uses a `long` for the offset + - `GpuDevice` + - `createSampler` - Creates a sampler for some source to destination with the desired address and filter modes. + - `precompilePipeline` now takes in a `ShaderSource` instead of a `BiFunction` + - `getMaxSupportedAnisotropy` - The maximum anisotropic filtering level supported by the hardware. + - `createBuffer` now uses in a `long` for the size + - `RenderPass#bindTexture` now takes in a `GpuSampler` + - `RenderSystem`now uses in a `long` for the size + - `samplerCache` - Returns a cache of samples containing all possible combinations. + - `TEXTURE_COUNT` is removed + - `setupOverlayColor`, `teardownOverlayColor` are removed + - `setShaderTexture`, `getShaderTexture` are removed + - `setTextureMatrix`, `resetTextureMatrix`, `getTextureMatrix` are removed + - `lineWidth` -> `VertexConsumer#setLineWidth` + - `getShaderLineWidth` -> `Window#getAppropriateLineWidth` + - `initRenderer` now takes in a `ShaderSource` instead of a `BiFunction` + - `SamplerCache` - A cache of all possible samplers that may be used by the renderer. +- `com.mojang.blaze3d.textures` + - `GpuSampler` - A buffer sampler with the specified UV address modes and minification and magnification filters. + - `GpuTexture` + - `addressModeU` -> `GpuSampler#getAddressModeU` + - `addressModeV` -> `GpuSampler#getAddressModeV` + - `minFilter` -> `GpuSampler#getMinFilter` + - `magFilter` -> `GpuSampler#getMagFilter` + - `setAddressMode`, `setTextureFilter` have been replaced by `SamplerCache#getSampler`, not one-to-one + - `useMipmaps`, `setUseMipmaps` are removed +- `net.minecraft.client` + - `Options#textureFiltering` - The chosen texture sampling method when viewed at an angle or from a distance. + - `TextureFilteringMethod` - The sampling method when viewing a texture at an angle or from a distance. +- `net.minecraft.client.gui.render.TextureSetup` now takes in the `GpuSampler`s for each of the textures + - This also includes the static constructors +- `net.minecraft.client.particle.SingleQuadParticle$Layer#ITEMS` - A layer for particles with item textures. +- `net.minecraft.client.renderer` + - `FaceInfo` + - `$Constants` -> `$Extent` + - `$VertexInfo` is now a record + - `ItemBlockRenderTypes#getRenderType(ItemStack)` + - `LightTexture#turnOffLightLayer`, `turnOnLightLayer` are removed + - `LevelRenderer#resetSampler` - Resets the chunk layer sampler. + - `PostPass` + - `$Input#bilinear` - Whether to use a bilinear filter. + - `$TextureInput` now takes in a `boolean` representing whether to use a bilinear filter + - `RenderPipelines` + - `SOLID` -> `SOLID_BLOCK`, `SOLID_TERRAIN` + - `CUTOUT` -> `CUTOUT_BLOCK`, `CUTOUT_TERRAIN` + - `CUTOUT_MIPPED` is removed + - `TRANSLUCENT` -> `TRANSLUCENT_TERRAIN` + - `TRIPWIRE` -> `TRIPWIRE_BLOCK`, `TRIPWIRE_TERRAIN` + - `ANIMATE_SPRITE_SNIPPET`, `ANIMATE_SPRITE_BLIT`, `ANIMATE_SPRITE_INTERPOLATION` - Pipelines for animated sprites. + - `RenderStateShard` has been replaced with `RenderSetup`, not one-to-one + - `$LightmapStateShard` -> `RenderSetup#useLightmap` + - `$OverlayStateShard` -> `RenderSetup#useOverlay` + - `$MultiTextureStateShard`, `$TextureStateShard` -> `RenderSetup#textures` + - `$LayeringStateShard` -> `RenderSetup#layeringTransform`, `LayeringTransform` + - `$LineStateShard` -> `VertexConsumer#setLineWidth` + - `$OutputStateShard` -> `RenderSetup#outputTarget`, `OutputTarget` + - `$TexturingStateShard`, `$OffsetTexturingStateShard` -> `RenderSetup#textureTransform`, `TextureTransform` + - `RenderType` has been split into two separate concepts, not one-to-one + - All of the stored `RenderType`s have been moved to `RenderTypes` + - The actual class usage has moved to `.rendertype.RenderType`, where it does the work of `$CompositeRenderType` + - `Sheets#translucentBlockItemSheet` - A render type for translucent block items. +- `net.minecraft.client.renderer.block` + - `BlockRenderDispatcher` no longer takes in the supplied `SpecialBlockModelRenderer` + - `LiquidBlockRenderer` now takes in a `MaterialSet` + - `setupSprites` has been moved into the `LiquidBlockRenderer` constructor +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` + - `vertices` -> `position*`, `packedUV*`, not one-to-one + - `position` - Gets the position vector given the index. + - `packedUV` - Gets the packed UV given the index. + - `BlockElementRotation` now takes in a `Vector3fc` for the origin and a `Matrix4fc` transform + - The constructor also takes in a `$RotationValue` instead of a `Direction$Axis` and angle `float` + - `$EulerXYZRotation` - A XYZ rotation in degrees. + - `$RotationValue` - An interface that defines the rotation transformation. + - `$SingleAxisRotation` - A rotation in degrees around a single axis. + - `FaceBakery` + - `VERTEX_COUNT` -> `BakedQuad#VERTEX_COUNT` + - `VERTEX_INT_SIZE`, `COLOR_INDEX`, `UV_INDEX` are removed + - `bakeQuad` now takes in a `ModelBaker$PartCache` + - `extractPositions` is removed + - `SimpleModelWrapper#bake` now returns a `BlockModelPart` + - `SimpleUnbakedGeometry#bake` now takes in a `ModelBaker` instead of a `SpriteGetter` + - `TextureSlots$parseTextureMap` no longer takes in an `Identifier` + - `Variant` + - `withZRot` - Rotates the model state around the Z axis. + - `$SimpleModelState` now takes in a Z `Quadrant` + - `withZ` - Sets the Z quadrant of the model state. + - `VariantMutator#Z_ROT` - Rotates a model around the Z axis. +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` no longer takes in whether to use mipmaps + - `CUTOUT_MIPPED` is removed + - `texture` is removed + - `ChunkSectionsToRender` now takes in the `GpuTextureView` + - `dynamicTransforms` -> `chunkSectionInfos` + - `renderGroup` now takes in the `GpuSampler` +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` constructor is now package-private + - `computeExtents` now returns an array of `Vector3fc`s + - `ItemStackRenderState$LayerRenderState` + - `NO_EXTENTS_SUPPLIER` is now a supplied array of `Vector3fc`s + - `setExtents` now takes in a supplied array of `Vector3fc`s +- `net.minecraft.client.renderer.rendertype.RenderTypes` + - `MOVING_BLOCK_SAMPLER` - A sampler for blocks that are in motion. + - `solid` -> `solidMovingBlock` + - `cutout` -> `cutoutMovingBlock` + - `tripwire` -> `tripwireMovingBlock` +- `net.minecraft.client.renderer.texture` + - `AbstractTexture#setUseMipmaps` is removed + - `MipmapGenerator#generateMipLevels` now takes in the name of the texture, a `MipmapStrategy` to determine how a specific texture should be mip mapped, and a `float` for the alpha cutoff bias + - `MipmapStrategy` - A enum defines the strategies used when constructing a mipmap for a texture. + - `OverlayTexture#setupOverlayColor`, `teardownOverlayColor` replaced by `getTextureView`, not one-to-one + - `SpriteContents` now takes in an optional `TextureMetadataSection` to determine the sprite's metadata + - `UBO_SIZE` - The uniform buffer object size of the sprite contents. + - `createTicker` -> `createAnimationState`, not one-to-one + - `uploadFirstFrame` no longer takes in the texture `int`s, instead a mip level `int` + - `$AnimatedTexture#createTicker`, `uploadFirstFrame` -> `createAnimationState`, not one-to-one + - `$Ticker` -> `$AnimationState`, not one-to-one + - `tickAndUpload` -> `tick`, `getDrawUbo`, `needsToDraw`, `drawToAtlas`; not one-to-one + - `SpriteTicker` interface is removed + - `Stitcher` now takes in the anisotropic filtering level + - `$Holder(T, int)` is removed + - `$Region#walk` now takes in a padding `int` + - `$SpriteLoader` no longer takes in the minimum width/height + - `load` now takes in a padding `int` + - `TextureAtlas` now implements `TickableTexture` instead of `Tickable` + - `TextureAtlasSprite` now implements `AutoCloseable` + - The constructor takes in a padding `int` + - `createTicker` -> `createAnimationState`, not one-to-one + - `getUOffset`, `getVOffset`, `uvShrinkRatio` are removed + - `uploadFirstFrame` now takes in the mip level `int` + - `uploadSpriteUbo` - Uploads the atlas sprite to the to the buffer. + - `$Ticker` interface is removed + - `TextureManager` no longer implements `Tickable` + - `Tickable` -> `TickableTexture` +- `net.minecraft.client.renderer.texture.atlas` + - `SpriteSource$SpriteSupplier` -> `$DiscardableLoader` + - `Function` superinterface is now represented as `$Loader` + - `apply` -> `get` + - `SpriteSourceList#list` now returns a list of `SpriteSource$Loader`s +- `net.minecraft.client.resources.metadata.texture.TextureMetadataSection` now takes in a `MipmapStrategy` to determine how a specific texture should be mip mapped, and a `float` for the alpha cutoff bias +- `net.minecraft.client.resources.model` + - `ModelBaker` + - `missingBlockModelPart` - The missing block model. + - `parts` - A cache of previously constructed vectors. + - `$PartCache` - A cache that interns previously constructed vertices in a quad. + - `ModelBakery` + - `*_STILL` - Fluid still texture locations. + - `$MissingModels` now takes in a `BlockModelPart` missing model + - `ModelManager` + - `BLOCK_OR_ITEM` - A special case that causes the model manager to check both the item and block atlas. + - `specialBlockModelRenderer` now returns the raw renderer instead of a supplied value. +- `net.minecraft.data.AtlasIds#ITEMS` - The item atlas identifier. +- `net.minecraft.world.level.block.LeavesBlock#setCutoutLeaves` - Sets whether the leaves is using cutout rendering. + +### Gizmos + +Gizmos are the newest iteration in the submission and rendering decoupling, this time for debug renderers. However, the underlying structure to submit gizmos for rendering is much more complex since debug renderers can submit objects at nearly any point during the client's process. + +#### What is a Gizmo? + +A `Gizmo` is basically an object that submits some object primitives -- specifically points, lines, triangle fans, quads, and text -- for rendering. Each gizmo essentially strings together these primitives via `emit` into its desired shape. During the render process, these make use of the `RenderPipelines#DEBUG_*` pipelines to render their primitives to the screen. Creating a new gizmo is as simple as extending the interface: + +```java +// Store some parameters like a render state to submit the element primitives +public record ExampleGizmo(Vec3 start, Vec3 end) implements Gizmo { + + @Override + public void emit(GizmoPrimitives gizmos, float alphaMultiplier) { + // Submit any elements here + gizmos.addLine(this.start, this.end, ARGB.multiplyAlpha(0, alphaMultiplier), 3f); + } +} +``` + +Actually submitting the elements happens through `Gizmos#addGizmo`. This stores the gizmo to be emitted and drawn to the screen, as long as it is called during `Minecraft#tick` or any rendering on the client -- which is how the debug renderers emit theirs, `IntegratedServer#tickServer` in a singleplayer world, or packet processing on either side. All of the methods in `Gizmos` call `addGizmo` internally, which is why the method is typically absent outside its class: + +```java +// Somewhere in GameRenderer#render + +Gizmos.addGizmo(new ExampleGizmo(Vec3.ZERO, Vec3.X_AXIS)); + +// Calls addGizmo internally +Gizmos.point(Vec3.ZERO, 0, 5f); +``` + +Calling `addGizmo` returns a `GizmoProperties`, which sets some properties for when the element is drawn, assuming that `GizmoCollector` is not a `NOOP`. `GizmoProperties` provides three methods: + +| Method | Description | +|:------------------:|:--------------------------------------------------------------------------------| +| `setAlwaysOnTop` | Clears the depth texture before rendering. | +| `persistForMillis` | Keeps the gizmo on screen for the specified amount of time before disappearing. | +| `fadeOut` | Fades the disappearing when persisted for a certain amount of time. | + +#### Putting it Together + +With that, how can you submit gizmos for rendering pretty much anywhere in the client pipeline? Well, this all starts from `Gizmos#withCollector` and `SimpleGizmoCollector`. + +`SimpleGizmoCollector` is basically just a list that holds the collected gizmos to render. During the rendering process, `SimpleGizmoCollector#drainGizmos` is called, copying the gizmos over to a separate list for the renderer to `Gizmo#emit`, before drawing to the screen through the familiar frame pass and buffer source. `drainGizmos` then clears the internal list based on `GizmoProperties#persistForMillis`, or immediately if not specified, for the next frame. + +To actually collect these elements, there is a rather convoluted process. `Minecraft`, `LevelRenderer`, and `IntegratedServer` have their own `SimpleGizmoCollector`. This is done by setting the collector using `Gizmo#withCollector`, which returns a `Gizmos$TemporaryCollection`. The collection is `AutoCloseable` that, when closed, releases the held collector on the local thread. So, the collectors are wrapped in a try-with-resources to facilitate the submission during these periods. Then, during the debug pass, the per tick gizmos are merged with the per frame gizmos and drawn to the screen via `addTemporaryGizmos`, quite literally at the last moment in `LevelRenderer#renderLevel`. The `IntegratedServer` gizmos in a singleplayer world are stored in a volatile field, allowing it to be accessed from the client thread. + +- `net.minecraft.client.Minecraft` + - `collectPerTickGizmos` - Returns a collection of all gizmos to emit. + - `getPerTickGizmos` - Gets the gizmos to draw to the screen. +- `net.minecraft.client.renderer` + - `LevelRenderer#collectPerFrameGizmos` - Returns a collection of all gizmos to emit. + - `OrderedSubmitNodeCollector#submitHitbox` is removed + - `ShapeRenderer` + - `renderShape` now takes in a line width `float` + - `renderLineBox` -> `Gizmos#cuboid`, not one-to-one + - `addChainedFilledBoxVertices` -> `Gizmos#cuboid`, not one-to-one + - `renderFace` -> `Gizmos#rect`, not one-to-one + - `renderVector` -> `Gizmos#line`, not one-to-one + - `SubmitNodeCollection#getHitboxSubmits` is removed + - `SubmitNodeStorage$HitboxSubmit` record is removed +- `net.minecraft.client.renderer.debug` + - `DebugRenderer` + - `render` -> `emitGizmos`, no longer takes in the `PoseStack`, `BufferSource` or `boolean`, now taking in the partial tick `float` + - `renderFilledUnitCube` -> `Gizmos#cuboid`, not one-to-one + - `renderFilledBox` -> `Gizmos#cuboid`, not one-to-one + - `renderTextOverBlock` -> `Gizmos#billboardTextOverBlock`, not one-to-one + - `renderTextOverMob` -> `Gizmos#billboardTextOverMob`, not one-to-one + - `renderFloatingText` -> `Gizmos#billboardText`, not one-to-one + - `renderVoxelShape` -> `LevelRenderer#renderHitOutline`, now private, not one-to-one + - `SimpleDebugRenderer$render` -> `emitGizmos`, no longer takes in the `PoseStack`, `BufferSource` or `boolean`, now taking in the partial tick `float` + - `GameTestBlockHighlightRenderer` + - `render` -> `emitGizmos`, taking in no parameters + - `renderMarker` no longer takes in the `PoseStack` or buffer source + - `$Marker#get*` are removed + - `LightDebugRenderer` now takes in two flags determining whether to show the block or sky light + - `PathfindingRenderer#renderPath`, `renderPathLine` no longer take in the `PoseStack` or buffer source +- `net.minecraft.client.renderer.entity.EntityRenderer#extractAdditionalHitboxes` is removed +- `net.minecraft.client.renderer.entity.state` + - `EntityRenderState#hitboxesRenderState`, `serverHitboxesRenderState` are removed + - `HitboxesRenderState` class is removed + - `ServerHitboxesRenderState` class is removed +- `net.minecraft.client.renderer.feature.HitboxFeatureRenderer` -> `EntityHitboxDebugRenderer`, not one-to-one +- `net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives` - A storage and renderer for primitive shapes. or gizmos. +- `net.minecraft.client.renderer.texture` + - `AbstractTexture` + - `sampler`, `getSampler` - Returns the `GpuSampler` used by the texture. + - `setClamp` -> `GpuSampler#getAddressMode*`, not one-to-one + - `setFilter` -> `GpuSampler#get*Filter`, not one-to-one + - `ReloadableTexture` no longer takes in the address mode and filter `boolean`s +- `net.minecraft.client.server.IntegratedServer#getPerTickGizmos` - Gets the gizmos to draw to the screen for the current tick. +- `net.minecraft.gizmos` + - `ArrowGizmo` - A gizmo that draws an arrow. + - `CircleGizmo` - A gizmo that draws an approximate circle with twenty vertices. + - `CuboidGizmo` - A gizmo that draws a rectangular prism. + - `Gizmo` - An object that can emit simple shape primitives to draw. + - `GizmoCollector` - An add-only collector. + - `GizmoPrimitives` - Shape primitives that can be drawn. + - `GizmoProperties` - Properties that apply to how the gizmo should be drawn. + - `Gizmos` - A collection of static methods for creating gizmos and collecting them. + - `GizmoStyle` - A property holder to define how a gizmo should be drawn. These are used by the gizmos themselves and not the actual primitives. + - `LineGizmo` - A gizmo that draws a line. + - `PointGizmo` - A gizmo that draws a point. + - `RectGizmo` - A gizmo that draws a rectangle. + - `SimpleGizmoCollector` - A collector implementation for adding gizmos before sending them off for rendering. + - `TextGizmo` - A gizmo that draws text. +- `net.minecraft.server.MinecraftServer#processPacketsAndTick` - Handles server ticking and packet processing. + +### Permission Overhaul + +The permission level integer has been expanded into an entirely new system that is both simple yet complicated. There are three main parts: `Permission`s, `PermissionSet`s, and `PermissionCheck`s. + +#### Permissions + +`Permission`s are functionally data objects that define some sort of state. Vanilla provides two types of permissions: `Permission$Atom`, which just is a unique unit object; and `Permission$HasCommandLevel`, which holds the desired `PermissionLevel` for a command. Both of the data objects are registered as map codecs for dumping the command report. + +```java +// Attempts to query moderator level permissions. +public static final Permission COMMANDS_MODERATOR = new Permission.HasCommandLevel(PermissionLevel.MODERATORS); +``` + +A custom permission can be created through some class or record that extends `Permission` with an associated `MapCodec` registered to its static registry: + +```java +// This does not check whether the user has the given permission +// It is literally just holding data representing the permission state +public record HasExamplePermission(int state) implements Permission { + public static final MapCodec MAP_CODEC = Codec.INT.fieldOf("state") + .xmap(HasExamplePermission::new, HasExamplePermission::state); + + @Override + public MapCodec codec() { + return HasExamplePermission.MAP_CODEC; + } +} + +// In some registration handler +Registry.register( + BuiltInRegistries.PERMISSION_TYPE + Identifier.withNamespaceAndPath("examplemod", "has_example_permission"), + HasExamplePermission.MAP_CODEC +); + +// Storing the permission for use +public static final Permission HAS_STATE_ONE = new HasExamplePermission(1); +``` + +#### Permission Sets + +If `Permission`s define the queryable state, then `PermissionSet`s are the permissions the user actually has. `PermissionSet` is a functional interface that checks whether the user has the desired permission state (via `hasPermission`). Vanilla uses a `LevelBasedPermissionSet` for checking whether the permission queried matches the current `PermissionLevel`. As a permission set is usually checked against some swathe of permissions, multiple permission sets can be combined into one via `PermissionSet#union`. It functionally performs an OR operation, meaning that if a set does not check a permission, it should default to `false`. + +```java +public interface ExamplePermissionSet extends PermissionSet { + + // Keep track of the user's state for our permissions + int state(); + + @Override + default boolean hasPermission(Permission permission) { + // Check our permission + if (permission instanceof HasExamplePermission example) { + return this.state() >= example.state(); + } + + // Otherwise ignore + return false; + } +} + +// Storing a permission set +// Could also be implemented or stored on the desired target +public static ExamplePermissionSet STATE_ONE = () -> 1; + +// Check whether the permission set has the desired permission +STATE_ONE.hasPermission(HAS_STATE_ONE); +``` + +Currently, there is no simple method to store custom permission sets on the desired user. `CommandSourceStack` does have a method to union other permission sets via `withMaximumPermission`, but that would need to be handled within the associated `createCommandSourceStack` method. The normal `LevelBasedPermissionSet` can typically be queried through a `permissions` method, though there is no common interface across objects, even though `PermissionSetSupplier` seems to exist for that purpose. + +#### Permission Checks + +Now, a `PermissionSet` never directly checks a `Permission` within the codebase. That would require having the object accessible at all times. Instead, a `PermissionCheck` object is created, which takes in the `PermissionSet` and `check`s whether the user has the desired data to continue execution. Vanilla provides two types of checks: `$AlwaysPass`, which means it will always return true; and `$Require`, which requires the set to have the desired `Permission`. The checks also have a map codec for dumping the command report. + +```java +// Requires the permission set has acccess to moderator commands +public static final PermissionCheck LEVEL_MODERATORS = new PermissionCheck.Require(COMMANDS_MODERATOR); +``` + +Custom permission checks can be created through some class or record that implements `check` and registers the map codec to its static registry: + +```java +public static record AnyOf(List permissions) implements PermissionCheck { + public static final MapCodec MAP_CODEC = Permission.CODEC.listOf().fieldOf("permissions") + .xmap(AnyOf::new, AnyOf::permissions); + + @Override + public boolean check(PermissionSet permissionSet) { + return this.permissions.stream().filter(perm -> permissionSet.hasPermission(perm)).findAny().isPresent(); + } + + @Override + public MapCodec codec() { + return MAP_CODEC; + } +} + +// In some registration handler +Registry.register( + BuiltInRegistries.PERMISSION_CHECK_TYPE + Identifier.withNamespaceAndPath("examplemod", "any_of"), + AnyOf.MAP_CODEC +); + +// Storing the check for use in a command +public static final PermissionCheck CHECK_STATE_ONE = new AnyOf(List.of( + HAS_STATE_ONE, + Permissions.COMMANDS_GAMEMASTER +)); + +// For some command +Commands.literal("example").requires(Commands.hasPermission(CHECK_STATE_ONE)); +``` + +- `net.minecraft.client.multiplayer.ClientSuggestionProvider` no longer implements `PermissionSource` + - The constructor now takes in a `PermissionSet` instead of a `boolean` + - `allowsRestrictedCommands` -> `ClientPacketListener#ALLOW_RESTRICTED_COMMANDS`, now private, not one-to-one +- `net.minecraft.client.player.LocalPlayer#setPermissionLevel` -> `setPermissions`, not one-to-one +- `net.minecraft.commands` + - `Commands` + - `LEVEL_*` are now `PermissionCheck`s instead of `int`s + - `hasPermission` now takes in a `PermissionCheck` instead of an `int`, and returns a `PermissionProviderCheck` instead of a `PermissionCheck` + - `createCompilationContext` - Creates a source stack with the given permissions. + - `CommandSourceStack` no longer implements `PermissionSource` + - The constructor now takes in a `PermissionSet` instead of an `int` + - The `protected` constructor is now `private` + - `withPermission` now takes in a `PermissionSet` instead of an `int` + - `withMaximumPermission` now takes in a `PermissionSet` instead of an `int` + - `ExecutionCommandSource` now extends `PermissionSetSupplier` instead of `PermissionSource` + - `PermissionSource` interface is removed + - `SharedSuggestionProvider` now extends `PermissionSetSupplier` +- `net.minecraft.commands.arguments.selector.EntitySelectorParser#allowSelectors` now has an overload that takes in a `PermissionSetSupplier` +- `net.minecraft.core.registries` + - `BuiltInRegistries#PERMISSION_TYPE`, `Registries#PERMISSION_TYPE` - An object that defines some data requirement. + - `BuiltInRegistries#PERMISSION_CHECK_TYPE`, `Registries#PERMISSION_CHECK_TYPE` - A predicate that checks whether the set has the required data. +- `net.minecraft.server` + - `MinecraftServer` + - `operatorUserPermissionLevel` -> `operatorUserPermissions`, not one-to-one + - `getFunctionCompilationLevel` -> `getFunctionCompilationPermissions`, not one-to-one + - `getProfilePermissions` now returns a `LevelBasedPermissionSet` + - `ReloadableServerResources#loadResources` now takes in a `PermissionSet` instead of an `int` + - `ServerFunctionLibrary` now takes in a `PermissionSet` instead of an `int` + - `WorldLoader$InitConfig` now takes in a `PermissionSet` instead of an `int` +- `net.minecraft.server.commands.PermissionCheck` -> `.server.permissions.PermissionCheck`, not one-to-one +- `net.minecraft.server.dedicated.DedicatedServerProperties` + - `opPermissionLevel` -> `opPermissions`, not one-to-one + - `functionPermissionLevel` -> `functionPermissions`, not one-to-one + - `deserializePermissions`, `serializePermission` - Reads and writes the chosen level permission set. +- `net.minecraft.server.jsonrpc.internalapi` + - `MinecraftOperatorListService#op` now takes in an optional `PermissionLevel` instead of an `int` + - `MinecraftServerSettingsService` + - `getOperatorUserPermissionLevel` -> `getOperatorUserPermissions`, not one-to-one + - `setOperatorUserPermissionLevel` -> `setOperatorUserPermissions`, not one-to-one +- `net.minecraft.server.jsonrpc.methods` + - `OperatorService$OperatorDto#permissionLevel` now takes in an optional `PermissionLevel` instead of an `int` + - `ServerSettingsService` + - `operatorUserPermissionLevel` now returns a `PermissionLevel` instead of an `int` + - `setOperatorUserPermissionLevel` now takes in and returns a `PermissionLevel` instead of an `int` +- `net.minecraft.server.permissions` + - `LevelBasedPermissionSet` - A set of permissions that checks whether the user has an equal or higher command permission level. + - `Permission` - Data related to the user's permissions, such as command level. + - `PermissionCheckTypes` - The types of permission checks vanilla provides. + - `PermissionLevel` - Defines a level sequence for a permission. + - `PermissionProviderCheck` - A predicate that checks that tests the supplier's permission set against a check. + - `Permissions` - The permissions vanilla provides. + - `PermissionSet` - A set of a permissions to user has, but mostly defines a method to determine whether a user has the desired permission. + - `PermissionSetSupplier` - An object that supplies a `PermissionSet`. + - `PermissionSetUnion` - A union of multiple permission sets. + - `PermissionTypes` - The types of permissions vanilla provides. +- `net.minecraft.server.players` + - `PlayersList#op` now takes in an optional `LevelBasedPermissionSet` instead of an `int` + - `ServerOpListEntry` now takes in a `LevelBasedPermissionSet` instead of an `int` + - `getLevel` -> `permissions`, not one-to-one +- `net.minecraft.world.entity.player.Player#getPermissionLevel`, `hasPermissions` -> `permissions`, not one-to-one +- `net.minecraft.world.entity.projectile.ProjectileUtils` + - `getHitEntitiesAlong` - Gets the entities hit along the provided path. + - `getManyEntityHitResult` - Gets all entities hit along the path of the two points within the bounding box. +- `net.minecraft.world.entity.projectile.arrow.AbstractArrow#findHitEntities` - Gets all entities hit by the vector. + +### New Data Components + +With the addition of the spear, a number of data components have been added to provide the associated functionality. The following is an brief overview of these components. + +#### Use Effects + +`DataComponents#USE_EFFECTS` defines some effects to apply to the player that is using (e.g., right-clicking) an item. Currently, there are only three types of effects: whether the player can sprint when using the item, whether the use interaction causes vibrations, and the scalar that is applied to the player's horizontal movement. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.USE_EFFECTS, + new UseEffects( + // Whether the player can sprint while using the item + true, + // Whether on item use that a vibration is sent from the player + false + // The scalar applied to the player's horizontal movement + 0.5f + ) +)); +``` + +#### Damage Type + +`DataComponents#DAMAGE_TYPE` defines the damage type applied to an entity when hit with this item. It takes in either the `ResourceKey` of the damage type or the `DamageType` object itself. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.DAMAGE_TYPE, + new EitherHolder<>( + // The damage type this item applies to the attacked entity + DamageTypes.FALLING_ANVIL + ) +)); +``` + +#### Swing Animation + +`DataComponents#SWING_ANIMATION` defines the animation to play when swinging or attacking (e.g., left-clicking) with the item. There are three types of animation to play: `SwingAnimationType#NONE`, which does nothing; `WHACK`, which plays the standard swing animation; and `STAB`, which plays the spear thrust animation. The length of the animation can also be specified. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.SWING_ANIMATION, + new SwingAnimation( + // The animation to play + SwingAnimationType.NONE, + // The amount of time to play the animation for, in ticks + 20 + ) +)); +``` + +#### Minimum Attack Charge + +`DataComponents#MINIMUM_ATTACK_CHARGE` determines how long the player must wait before making another attack with the item. The charge is a value between 0 and 1, which determines percentage of the delay to wait before making another attack. The delay is determined by the player's attack speed. This is checked twice if the player's action is a stab. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.MINIMUM_ATTACK_CHARGE, + // The percentage of time the player must wait before making another attack with this item + 0.5f +)); +``` + +#### Attack Range + +`DataComponents#ATTACK_RANGE` determines the range that an entity can attack another entity from when attacking with this item. If not set, it defaults to the entity's interaction range attribute. The range specified is for the player, with mob reach determined by the range times the mob factor. A range can also be specified for the player when in creative mode, overriding the default range. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.ATTACK_RANGE, + new AttackRange( + // The minimum range in blocks for this item to hit the entity. + // Must be between [0, 64]; defaults to 0. + 0.4f, + // The maximum range in blocks for this item to hit the entity. + // Must be between [0,64]; defaults to 3. + 4.5f, + // The minimum range in blocks for this item to hit the entity, + // provided the holding entity is a player in creative mode. + // This supercedes the minimum range. + // Must be between [0, 64]; defaults to 0. + 0f, + // The maximum range in blocks for this item to hit the entity, + // provided the holding entity is a player in creative mode. + // This supercedes the maximum range. + // Must be between [0,64]; defaults to 3. + 5f, + // The margin to inflate the hitbox by in blocks, compensating + // for potential precision issues. + // Must be between [0,1]; defaults to 0.3. + 0.25f, + // A scalar to multiply the minimum and maximum range by to determine + // a non-player entity's reach. + // Must be between [0,2]; defaults to 1. + 1.1f + ) +)); +``` + +#### Piercing Weapon + +`DataComponents#PIERCING_WEAPON` sets the player's attack as not an attack, but as a stab or piercing attack. This is a separate action than swinging, which either attacks the entity or breaks a block. A piercing weapon can attack an entity, but is unable to break blocks. It also applies any enchantment effects for lunging. Piercing weapons are only applied to the player. + +The logic pipeline flows like so: + +- If `Player#cannotAttackWithItem` returns true, then the pipeline is terminated +- Piercing attack is handled via: + - Client - `MultiPlayerGameMode#piercingAttack` + - Server - `PiercingWeapon#attack` +- Server-only: + - Get all entities that: + - Are within the entity's attack range `DataComponents#ATTACK_RANGE` + - Are within the hitbox constructed from the reach starting at the player's eye position + - If `PiercingWeapon#canHitEntity` returns true: + - Player is not invulnerable or dead, and + - Either: + - Entity is an `Interaction` entity + - Or: + - Entity can be hit by a projectile + - If both players, that this player can harm the other player + - Is not a passenger of the same vehicle + - Call `LivingEntity#stabAttack` on each entity +- `LivingEntity#onAttack` is fired +- `LivingEntity#lungeForwardMaybe` is fired +- Server-only: + - `PiercingWeapon#makeHitSound` is played if at least one entity was hit + - `PiercingWeapon#makeSound` is played +- `LivingEntity#swing` is fired + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.PIERCING_WEAPON, + new PiercingWeapon( + // Whether being hit by this item deals knockback to the entity. + true, + // Whether being hit by this item dismounts the entity from its vehicle. + true, + // The sound to play when attacking with this item. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.LLAMA_SWAG), + // The sound to play when this item hits an entity. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.ITEM_BREAK) + ) +)); +``` + +#### Kinetic Weapon + +`DataComponents#KINETIC_WEAPON` affects an entity's use (e.g., right-click) behavior. On right-click, if an item has the component, then `KineticWeapon#damageEntities` is called every tick instead of `Item#onUseTick`, only on the server. The kinetic weapon also calls `LivingEntity#stabAttack` to damage its entities similar to piercing attack. In fact, the component itself is similar to `PiercingWeapon`, except with a few additional fields to handle the kinetic damage applied and to make it accessible to all living entities instead of only the player. + +For the stab attack to occur, one of the conditions (dismount, knockback, damage) must be present and return true. The attack range is obtained from the `DataComponents#ATTACK_RANGE` component. If a stab attack occurs, then the `SPEAR_MOBS_TRIGGER` criteria will be fired on the server. + +```java +// For some item registration +new Item(new Item.Properties.component( + DataComponents.KINETIC_WEAPON, + new KineticWeapon( + // The number of ticks to wait before this entity can attempt to contact + // (e.g., damage) another entity. + 10, + // The number of ticks to wait before attempting to stab any entities in range. + 20, + // The condition to check whether an attack from this item will dismount + // an entity in a vehicle. + // If the optional is not present, then it will default to false. + Optional.of(new KineticWeapon.Condition( + // The maximum number of ticks from first use plus delay that this + // condition may return true. + 100, + // The minimum speed the entity must be traveling for this condition + // to succeed. + // The speed is calculated as the dot product of the delta movement + // and the view vector multiplied by 20. + // Vanilla spears use values from 7-14 for dismount and 5.1 for knockback. + 9f, + // The minimum speed relative to the attacking entity that this entity + // must be traveling for this condition to succeed. + // Vanilla spears use 4.6 for damage. + 5f + )), + // The condition to check whether an attack from this item will cause knockback + // to an entity. + // If the optional is not present, then it will default to false. + Optional.of(KineticWeapon.Condition.ofAttackerSpeed( + // Maximum ticks + 100, + // Entity traveling speed + 5.1f + )), + // The condition to check whether an attack from this item will damage an + // entity. + // If the optional is not present, then it will default to false. + Optional.of(KineticWeapon.Condition.ofRelativeSpeed( + // Maximum ticks + 100, + // Relative traveling speed + 4.6f + )), + // The movement of the item during the third person attack animation + // Vanilla spears use 0.38. + 0.38f, + // A multiplier to apply to the damage of an entity + // The damage is calculated as the relative traveling speed of this entity + // to its target. + 4f, + // The sound to play when first using this item. + // If the optional is empty, no sound is played. + Optional.of(SoundEvents.LLAMA_SWAG), + // The sound to play when this item hits an entity. + // If the optional is empty, no sound is played. + Optiona.of(SoundEvents.ITEM_BREAK) + ) +)); +``` + +- `net.minecraft.core.components` + - `DataComponents` + - `USE_EFFECTS` - The effects to apply to the entity when using the item. + - `MINIMUM_ATTACK_CHARGE` - The minimum amount of time to attack with the item. + - `DAMAGE_TYPE` - The `DamageType` the item deals + - `PIERCING_WEAPON` - A weapon with some hitbox range that lunges towards the entity. + - `KINETIC_WEAPON` - A weapon with some hitbox range that requires some amount of forward momentum. + - `SWING_ANIMATION` - The animation applied when swinging an item. + - `ATTACK_RANGE` - Sets a custom attack range when using the item, overriding the normal entity interaction range. +- `net.minecraft.core.component.DataComponentType#ignoreSwapAnimation`, `$Builder#ignoreSwapAnimation` - When true, the swap animation does not affect the data component 'usage'. +- `net.minecraft.core.component.predicates` + - `AnyValue` - A predicate that checks if the component exists on the getter. + - `DataComponentPredicate` + - `$Type` is now an interface + - Its original implementation has been replaced by `$TypeBase` + - `$AnyValueType` - A type that uses the `AnyValue` predicate. + - `$ConcreteType` - A type that defines a specific predicate. +- `net.minecraft.network.protocol.game.ServerboundInteractPacket#isWithinRange` - Whether the interaction from the player is within the valid range to execute. +- `net.minecraft.world.entity` + - `LivingEntity` + - `SWING_DURATION` -> `SwingAnimation#duration`, not one-to-one + - `stabbedEntities` - The number of recent entities attacked by a kinetic weapon. + - `entityAttackRange` - The range that this entity can attack. + - `getActiveItem` - The currently used item, or the mainhand item. + - `Mob` + - `chargeSpeedModifier` - The modifier applied to the movement speed when charging. + - `canFireProjectileWeapon` -> `canUseNonMeleeWeapon`, now taking in an `ItemStack` instead of a `ProjectileWeaponItem` + - `getAttackBoundingBox` now takes in a horizontal inflation offset +- `net.minecraft.world.entity.ai.behavior` + - `ChargeAttack` - Handles a charge attack performed by a mob. + - `SpearApproach` - Approaches the enemy when holding a kinetic weapon. + - `SpearAttack` - Attacks the enemy with a kinetic weapon. + - `SpearRetreat` - Flees from the attacked target after using a kinetic weapon. +- `net.minecraft.world.entity.ai.goal.SpearUseGoal` - Handles a mob using a spear. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `SPEAR_FLEEING_TIME` - The number of ticks the entity has been fleeing for after using a kinetic weapon. + - `SPEAR_FLEEING_POSITION` - The position the entity flees to after using a kinetic weapon. + - `SPEAR_CHARGE_POSITION` - The position the entity charges to when using a kinetic weapon. + - `SPEAR_ENGAGE_TIME` - How long this entity has been engaged with its enemy when using a kinetic weapon. + - `SPEAR_STATUS` - The status of the entity when using a kinetic weapon. +- `net.minecraft.world.entity.player.Player` + - `hasEnoughFoodToDoExhaustiveManoeuvres` - Returns whether the player can perform an exhaustive manuever. + - `canInteractWithEntity` -> `isWithinEntityInteractionRange` + - `isWithinAttackRange` - If the bounding box being targeted is within the player's range. + - `canInteractWithBlock` -> `isWithinBlockInteractionRange` + - `CREATIVE_ENTITY_INTERACTION_RANGE_MODIFIER_VALUE` - A modifiers that increases the maximum range of an interaction by the given amount. +- `net.minecraft.world.item` + - `Item#getDamageSource` -> `getItemDamageSource`, now deprecated + - `ItemStack` + - `getSwingAnimation` - Returns the swing animation of the item. + - `getDamageSource` - Returns the damage source the item provides when hit. + - `causeUseVibration` - Sends the game event if the item on use can cause vibrations. + - `SwingAnimationType` - The type of animation played when swinging the item. +- `net.minecraft.world.item.component` + - `AttackRange` - The hitbox range of this item. + - `KineticWeapon` - A weapon that requires some amount of forward momentum. + - `PiercingWeapon` - A weapon that lunges towards the entity. + - `SwingAnimation` - The animation applied when swinging an item. + - `UseEffects` - The effects to apply to the entity when using the item. + +### The Timeline of Environment Attributes + +Environment attributes, as the name implies, defines a set of properties or modifications ('attributes') for a given dimension and/or biome ('environment'). They are stored directly within the biome or dimension type under the `attributes` field, or as part of a mutable timeline under the `tracks` field. Each attribute can represent anything from the visual settings to gameplay behavior, interpolating between different values as defined. Vanilla provides their available attributes within `EnvironmentAttributes` while the stored attributes are obtained from `Level#environmentAttributes`. + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + // Defines the attributes to apply within the dimension + "attributes": { + // Sets the cloud height + // More technically, modifies the value by overriding it + "minecraft:visual/cloud_height": 90 + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + // Defines the attributes to apply within the biome + // Defaults or modifies those in the dimension + // These attributes must be positional + "attributes": { + "minecraft:visual/cloud_height": { + // Instead of setting the value, apply a modifier + "modifier": "add", + // Adds 60 to 90, making this biome have a cloud height of 150 + "argument": 60 + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + // The number of ticks this track takes before repeating + "period_ticks": 24000, + // Defines the attributes to interpolate between + // based on the defined keyframes. + // Defaults or modifies those in the biome, or dimension + "tracks": { + "minecraft:visual/cloud_height": { + // The keyframes that define certain values of the attribute + "keyframes": [ + { + // The tick representing the keyframe + "tick": 12000, + // The argument that modifies the value + // In this case, adds 1 to 60 + 90, making this have a cloud height of 151 + "value": 1 + }, + { + // The tick representing the keyframe + "tick": 23999, + // The argument that modifies the value + // In this case, adds 0 to 60 + 90, making this have a cloud height of 150 + "value": 0 + } + ], + // Instead of setting the value, applies a modifier to the argument + "modifier": "add", + // The sampler function to apply when interpolating between ticks + "ease": "linear" + } + } +} +``` + +When calling `EnvironmentAttributeSystem#getValue`, the attribute value is obtained through the layers defined by the `Level`: + +1. Read the default value from the registered attribute (via `EnvironmentAttribute#defaultValue`). +2. Apply the modifier from the dimension, or do nothing if one does not exist for this attribute. +3. Apply the modifier from the biome, or do nothing if one does not exist. +4. Apply the modifiers from all active timelines defined in the `DimensionType`, or do nothing if none exist. Timeline order is not guaranteed. +5. If the dimension can have weather (skylight, no ceiling, and not the end), apply the modifiers from the `WeatherAttributes`. +6. If on the client (i.e. `ClientLevel`), apply the sky flashes modifier. +7. Sanitize the final value to be in the range defined by the `EnvironmentAttribute`. + +This is highly oversimplified and introduces many new concepts, so let's break it down further by creating our own environment attribute and timeline. + +#### Custom Environment Attributes + +Environment attributes are created through the `$Builder`, via `EnvironmentAttribute#builder`, taking the type value it represents (e.g., float, integer, object). The builder only requires one value to be set: the `defaultValue`. This is used if the attribute is not overridden by a dimension or biome. If the attribute value should have a valid set of states, then an `AttributeRange` can be set via `valueRange`. The `AttributeRange` is basically a unary operator that transforms the input into its 'valid' state via `sanitize`. It also verifies that the value passed in through the JSON is in a 'valid' state via `validate`. + +From there, there are three more methods responsible for determining the logic used to compute the value. `$Builder#syncable` syncs the attribute to the client, which is required for any attribute that causes some sort of change that is not specific to the server (e.g., visuals, audio, or common code). `notPositional` means that the attribute cannot be applied on a biome (still settable in a dimension or timeline), else an exception is thrown. Finally `spatiallyInterpolated` will attempt to interpolate using the attribute type between different biomes to apply a more seamless transition. Vanilla only handles client side attributes for spatial interpolation. Anything on the server must handle their own `SpatialAttributeInterpolator`. + +Finally the actual attribute can be obtained via `$Builder#build`. This value must be registered to `BuiltInRegistries#ENVIRONMENT_ATTRIBUTE`: + +```java +public static final EnvironmentAttribute EXAMPLE_ATTRIBUTE = Registry.register( + BuiltInRegistries.ENVIRONMENT_ATTRIBUTE, + Identifier.withNamespaceAndPath("examplemod", "example_attribute"), + EnvironmentAttribute.builder( + // The attribute type + // Must match the generic for the attribute value + AttributeTypes.BOOLEAN + ) + // The value this attribute should have by default + .defaultValue(false) + // Syncs this value to the client + .syncable() + .build() +); +``` + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + "attributes": { + "examplemod:example_attribute": true + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + "attributes": { + "examplemod:example_attribute": { + "modifier": "xor", + "argument": true + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + "period_ticks": 24000, + "tracks": { + "examplemod:example_attribute": { + "keyframes": [ + { + "tick": 12000, + "value": false + }, + { + "tick": 23999, + "value": true + } + ], + "modifier": "and", + "ease": "linear" + } + } +} +``` + +#### Custom Attribute Types + +Every environment attribute has an associated attribute type that is statically registered to `BuiltInRegistries#ATTRIBUTE_TYPE`. Not only does this define how to serialize the object value, but it also contains the modifications that can be applied to the value along with how to interpolate between spaces and frames. In fact, all of the builder settings, including `syncable` and `spatiallyInterpolated`, rely on the attribute type to determine what does it mean to perform that action. Without it, the attribute couldn't even be read from the dimension or biome JSON, much less the actual logic behind getting the value of the attribute. + +As such, the attribute type can be broken into three parts: the serialization codec, the modifier library, and the interpolation functions. + +```java +// We will use this example object for explaining the attribute type +public record ExampleObject(int value1, boolean value2) { + // The default value + public static final ExampleObject DEFAULT = new ExampleObject(0, false); +} +``` + +##### Type Serialization + +Serialization of the attribute type is handled through a codec of that type, both to disk (biome and dimension JSON) and network (`$Builder#syncable`): + +```java +// The codec to serialize the attribute type value +public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.INT.fieldOf("value1").forGetter(ExampleObject::value1), + Codec.BOOL.fieldOf("value2").forGetter(ExampleObject::value2) + ).apply(instance, ExampleObject::new) +); +``` + +##### Modifier Library + +The modifier library is a map of `AttributeModifier$OperationId` to `AttributeModifier`s that determine what operations can be performed on the default value. If the map contains no operations, the the default value cannot be mutated. All of the static constructors for `AttributeType` add the `OVERRIDE` modifier, allowing for the dimension and/or biome to set the value. This map should be thought of as a pseudo-registry (basically keys to unique values), as the default codec used to serialize is for a `BiMap` via an id resolver. + +An `AttributeModifier` defines two generics: the first being the environment attribute value type, and the second being an arbitrary object to apply the operation with. The modifier has two methods: `apply`, which takes in the value and the argument to return a new value; and `argumentCodec` to properly serialize the argument. For any operation, all possible mutations must be implemented within a single `AttributeModifier`: + +```java +// Modifiers only handling a part of the object +public static final AttributeModifier ADD = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Integer argument) { + // Apply the operation to the subject + return new ExampleObject(subject.value1() + argument, subject.value2()); + } + + @Override + public Codec argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + return Codec.INT; + } +}; + +public static final AttributeModifier OR = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Boolean argument) { + // Apply the operation to the subject + return new ExampleObject(subject.value1(), subject.value2() || argument); + } + + @Override + public Codec argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + return Codec.BOOL; + } +}; + +// A modifier handling all possible object combinations +public static final AttributeModifier>> AND = new AttributeModifier<>() { + + @Override + public ExampleObject apply(ExampleObject subject, Either> argument) { + return argument.map( + arg -> new ExampleObject(subject.value1() & arg.value1(), subject.value2() && arg.value2()), + either -> either.map( + arg -> new ExampleObject(subject.value1() & arg, subject.value2()), + arg -> new ExampleObject(subject.value1(), subject.value2() && arg) + ) + ); + } + + @Override + public Codec>> argumentCodec(EnvironmentAttribute attribute) { + // Construct the codec to deserialize the argument + // We can use the attribute codec for the value type + return Codec.either(attribute.valueCodec(), Codec.either(Codec.INT, Codec.BOOL)); + } +}; + +// Constructing the library +// The argument can be any value as long as it can be serialized and handled +// If using one of the static constructors for the attribute type, the override +// handler is added automatically along with the associated modifier codec for +// the map +public static final Map> EXAMPLE_LIBRARY = Map.of( + AttributeModifier.OperationId.ADD, ADD, + AttributeModifier.OperationId.OR, OR, + AttributeModifier.OperationId.AND, AND +); +``` + +##### Type Interpolation + +To support interpolation, whether for client frames (because of `$Builder#syncable`), spatial (`$Builder#spatiallyInterpolated`), states (weather), or keyframes (timelines), there needs to be some function that, given some step between 0 and 1 (either time or position), how are the two values merged. This is handled through a `LerpFunction`, of which the generic is the environment attribute value type. For non-interpolated values, this normally uses `LerpFunction#ofStep`, which acts like a simple threshold between the two values. More specifically, spatial will set the threshold as 0.5 while the partial tick, keyframe, and state change will only consider full steps (meaning always the next value). However, this function can be however you choose to define it: + +```java +// Step represents the value between 0 and 1 to interpolation +// Original represents the step at 0 +// Next represents the step at 1 +public static final LerpFunction EXAMPLE_SPATIAL_LERP = (step, original, next) -> { + return new ExampleObject( + Mth.lerp(step, original.value1(), next.value1()), + step >= 0.5f ? next.value2() : original.value2() + ); +} + +public static final LerpFunction EXAMPLE_PARTIAL_LERP = (step, original, next) -> { + return new ExampleObject( + Mth.lerp(step, original.value1(), next.value1()), + next.value2() + ); +} + +// Will always return the first value +public static final LerpFunction EXAMPLE_KEYFRAME_LERP = LerpFunction.ofConstant(); + +// Will change to the next state after 0.1 of the step has past +public static final LerpFunction EXAMPLE_STATE_CHANGE_LERP = LerpFunction.ofStep(0.1f); +``` + +##### Putting it all Together + +With each of these parts, an `AttributeType` can now be constructed. This is typically done using one of the static constructors: `ofInterpolated` for values that define their interpolation function, or `ofNotInterpolated`, for values that are okay just snapping between two values. For common use cases, unless your value transitions between something that is inherently obvious to the player (e.g., visuals like fog or sky color), then interpolation is generally unnecessary. + +If you decide to use the `AttributeType` instance constructor instead, you will also have to create a codec to serialize the modifier map. See `AttributeType#createModifierCodec` on how to do so. + +```java +// The attribute type must be statically registered to be handled correctly +public static final AttributeType EXAMPLE_ATTRIBUTE_TYPE = Registry.register( + BuiltInRegistries.ATTRIBUTE_TYPE, + Identifier.withNamespaceAndPath("examplemod", "example_attribute_type"), + new AttributeType<>( + // The codec for the value + ExampleObject.CODEC, + // The map of operations that can be modified + // `OVERRIDE` is automatically added for serialization + EXAMPLE_LIBRARY, + // The codec used to serialize the modifier library + Util.make(() -> { + ImmutableBiMap> map = ImmutableBiMap.builder() + .put(AttributeModifier.OperationId.OVERRIDE, AttributeModifier.override()) + .putAll(EXAMPLE_LIBRARY) + .buildOrThrow(); + return ExtraCodecs.idResolverCodec(AttributeModifier.OperationId.CODEC, map::get, map.inverse()::get); + }), + // The function interpolating between two keyframes in a timeline + EXAMPLE_KEYFRAME_LERP, + // The function interpolating between two states (only used for attributes in the weather maps) + EXAMPLE_STATE_CHANGE_LERP, + // The function interpolating between two spatial coordinates + EXAMPLE_SPATIAL_LERP, + // The function interpolating between client frames + EXAMPLE_PARTIAL_LERP + ) +); +``` + +From there, we can create an `EnvironmentAttribute` that uses said type: + +```java +public static final EnvironmentAttribute EXAMPLE_OBJECT_ATTRIBUTE = Registry.register( + BuiltInRegistries.ENVIRONMENT_ATTRIBUTE, + Identifier.withNamespaceAndPath("examplemod", "example_object_attribute"), + EnvironmentAttribute.builder( + EXAMPLE_ATTRIBUTE_TYPE + ) + .defaultValue(ExampleObject.DEFAULT) + // Possible because of the codec and partial tick lerp + .syncable() + // Possible because of the spatial lerp + .spatiallyInterpolated() + .build() +); +``` + +```json5 +// For some DimensionType json +// In `data/examplemod/dimension_type/example_dimension.json` +{ + "attributes": { + "examplemod:example_object_attribute": { + "value1": 10, + "value2": true + } + }, + // ... +} + +// For some Biome json +// In `data/examplemod/worldgen/biome/example_biome.json` +{ + "attributes": { + "examplemod:example_object_attribute": { + // Must use one of the arguments defined in the library + // In this case either 'add', 'or', or 'and' + "modifier": "and", + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "argument": false + } + } + // ... +} + +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + "period_ticks": 24000, + "tracks": { + "examplemod:example_object_attribute": { + "keyframes": [ + { + "tick": 12000, + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "value": 1 + }, + { + "tick": 23999, + // This can be either a boolean, integer, or object + // because of how the serializer was defined + "value": { + "value1": 0, + "value2": false + } + } + ], + // Must use one of the arguments defined in the library + // In this case either 'add', 'or', or 'and' + "modifier": "and", + "ease": "linear" + } + } +} +``` + +#### Timelines + +`Timeline`s are method of modifying attributes based on the current game time. More specifically, they define some keyframes that the values are interpolated between, first determining the step using the `EasingType` function, and second using `AttributeType#keyframeLerp` to get the value. This is not only a replacement of `Schedule`s in brains, but also attributes relating to the day/night cycle (e.g., sky color, slime spawn chance, etc.). These function as a layer after the biome modifiers are applied for both positional and non-positional attributes. + +Timelines are activated based on the `DimensionType#timelines` tag, which are prefixed with `in_` (e.g. `minecraft:in_overworld` is the timeline tag for the overworld). All dimension tags include the `minecraft:universal` tag, meaning all timelines tagged within will run within all dimensions (provided they add the universal tag). + +The vanilla timelines are like so: + +- `minecraft:day`: The day/night cycle +- `minecraft:moon`: The moon phase and spawn chance +- `minecraft:villager_schedule`: What `Activity` a villager performs +- `minecraft:early_game`: Stops pillager patrol spawns for the first few days + +The associated tags are the following; + +- `minecraft:universal` + - `minecraft:villager_schedule` +- `minecraft:in_overworld` - Overworld dimension + - `#minecraft:universal` + - `minecraft:day` + - `minecraft:moon` + - `minecraft:early_game` +- `minecraft:in_nether` - Nether dimension + - `#minecraft:universal` +- `minecraft:in_end` - End dimension + - `#minecraft:universal` + +##### Keyframes + +Each `Timeline` is made up of keyframes responsible for determining what the argument to the modifier should be at a given tick. These keyframes are then compiled into a list called a `KeyframeTrack`, baked into a `KeyframeTrackSampler` when constructing the attribute layers. Every two adjacent keyframes (including the first and last) is considered a `KeyframeTrackSampler$Segment`. This is what's used to sample an attribute at a given tick. + +Let's say we have the following (keyframe, value) segment (100, 0) -> (200, 1) and we are currently at tick 150. How do we choose what argument to use? Well, this is performed in two operations. First, we calculate the step: a value between `0` and `1` that determines how much to interpolate the value with. The step is calculated first linearly: (current_tick - start_segment_tick) / (end_segment_tick - start_segment_tick). Then, the step is passed into the desired `EasingType`, which is a function that takes in a 0-1 value and returns a 0-1 value, such as `in_out_bounce` or `out_back`. You can also create your own `EasingType` like so: + +```java +// `EasingType#registerSimple` must be made public +EasyingType.registerSimple( + // The name of the function + "examplemod:ease", + // The function to apply to the value + // For smooth transitions, the function should map 0 -> 0 and 1 -> 1 + original -> 0.5f * (float) Mth.sin(Math.PI * (3 * original - 0.5)) + 0.5f +); +``` + +Then, it passes the step to the `AttributeType#keyframeLerp` function along with the two arguments to get the lerped argument to apply. + +##### Attribute Tracks + +With the keyframes determining the arguments, we apply the arguments to the attribute through an `AttributeTrack`, baked into an `AttributeTrackSampler` when constructing the attribute layers. An `AttributeTrack` contains the `KeyframeTrack` to get the arguments, and an `ArgumentModifier` to apply the argument to the value. Note that there can only be one modifier for a given track. + +These `AttributeTrack`s are then stored in a map of attributes to tracks, which define our `Timeline`. The timeline also contains an optional integer indicating the period of the tracks. The 'period', in this case, acts as one full run of all tracks in the timeline. Values outside of the period are modulo'd. Most timelines use `24000` for the period as that represents one Minecraft day in ticks. + +##### Custom Timelines + +Custom `Timeline`s are added to the `timeline` datapack registry: + +```json5 +// For some Timeline json +// In `data/examplemod/timeline/example_timeline.json +{ + // Runs for every 3000 ticks (1/8 of a day) + "period_ticks": 3000, + "tracks": { + // The attribute(s) to modify + "examplemod:example_object_attribute": { + // The easing function to determine the step between arguments + "ease": "examplemod:ease", + // The list of keyframes defining the arguments at set ticks + // The arguments are then interpolated using the easing function + // and keyframe lerp + "keyframes": [ + { + // The tick for which this argument is the given value + "tick": 1500, + // Adds 10 to the attribute + "value": 10 + }, + // In-between, uses the easing function to step down between + // 10 and 0 + { + "tick": 2999, + // Adds 0 to the attribute + "value": 0 + } + // In-between, uses the easing function to step up between + // 0 and 10 + ], + // The modifier to use when applying the argument + // to the value + "modifier": "add" + } + } +} +``` + +- `net.minecraft.client` + - `Camera#attributeProbe` - Gets the client environment attribute probe for values and interpolation. + - `Minecraft` + - `getSituationalMusic` now returns `Music` instead of `MusicInfo` + - `getMusicVolume` - Gets the volume of the background music, or normal volume if the open screen has background music. +- `net.minecraft.client.multiplayer.ClientLevel` + - `effects` is removed + - `getSkyDarken` -> `EnvironmentAttributes#SKY_LIGHT_COLOR`, `SKY_LIGHT_FACTOR`; not one-to-one + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR`, not one-to-one + - `getCloudColor` -> `EnvironmentAttributes#CLOUD_COLOR`, not one-to-one + - `getStarBrightness` -> `EnvironmentAttributes#STAR_BRIGHTNESS`, not one-to-one + - `getSkyFlashTime` is now private +- `net.minecraft.client.renderer` + - `DimensionSpecialEffects` class is removed, replaced entirely by `EnvironmentAttribute`s + - `SkyRenderer` + - `renderSkyDisc` now takes in a single ARGB `int` instead of three RGB `float`s + - `renderSunMoonAndStars` now take in two additional `float`s for the moon and star rotation +- `net.minecraft.client.renderer.state.SkyRenderState` + - `skyType` -> `skybox`, not one-to-one + - `isSunriseOrSunset`, `timeOfDay` are removed + - `moonAngle`, `starAngle` - The angle of the moon and stars. +- `net.minecraft.client.resources.sounds.BiomeAmbientSoundsHandler` no longer takes in the `BiomeManager` +- `net.minecraft.client.sounds` + - `MusicInfo` -> `Minecraft#getSituationalMusic`, `getMusicVolume`; not one-to-one + - `MusicManager#startPlaying` now takes in the `Music` instead of the `MusicInfo` +- `net.minecraft.core.registries` + - `BuiltInRegistries`, `Registries#ENVIRONMENT_ATTRIBUTE` - The registry for the environment attributes. + - `BuiltInRegistries`, `Registries#ATTRIBUTE_TYPE` - The registry for the attribute types. + - `BuiltInRegistires`, `Registries#SCHEDULE` are removed + - `Registries#TIMELINE` - The registry key for the timeline. +- `net.minecraft.data.tags.TimelineTagsProvider` - The tags provider for the timeline. +- `net.minecraft.server.level.ServerLevel#getMoonBrightness` - Returns the brightness of the moon. +- `net.minecraft.sounds.Music#event` -> `sound` +- `net.minecraft.tags.TimelineTags` - The tags for the timeline. +- `net.minecraft.util` + - `BinaryAnimator$EasingFunction` -> `EasingType` + - `CubicSampler` -> `GaussianSampler`, `SpatialAttributeInterpolator`; not one-to-one + - `KeyframeTrack` - A track of keyframes and the easing performed between them. + - `KeyframeTrackSampler` - A keyframe track that replays based on the period, lerping between values using the provided function. +- `net.minecraft.world.attribute` + - `AmbientSounds` - The sounds that ambiently play within an environment. + - `AttributeRange` - An interface meant to validate inputs and sanitize the corresponding value into an appropriate bound. + - `AttributeType` - A type definition of the operations and modifications that can be performed by an attribute. + - `AttributeTypes` - A registry of all vanilla attribute types. + - `BackgroundMusic` - The background music that plays within an environment. + - `BedRule` - The rules of how beds function within an environment. + - `EnvironmentAttribute` - A definition of some attribute within an environment. + - `EnvironmentAttributeLayer` - A layer that modifies a value. + - `EnvironmentAttributeMap` - A map of attribute definitions to their argument and modifier. + - `EnvironmentAttributeProbe` - The attribute handler for getting and interpolating between values. Used only by the camera. + - `EnvironmentAttributeReader` - A reader that can lookup the environment attributes either by dimension or position. + - `EnvironmentAttributes` - A registry of all vanilla environment attributes. + - `EnvironmentAttributeSystem` - A reader implementation that gets and spatially interpolates environment attributes. + - `LerpFunction` - A functional interface that takes in some value between 0-1 along with the start and end values to interpolate between. + - `WeatherAttributes` - Attributes maps for applying weather layers. +- `net.minecraft.world.attribute.holder` + - `AttributeModifier` - A modifier that takes in the attribute value along with some argument (typically a value of the same type) to produce a modified value. + - `BooleanModifier` - Modifier for a boolean with a boolean argument. + - `ColorModifier` - Modifier for an ARGB integer with some argument, typically integers. + - `FloatModifier` - Modifier for a float with some argument, typical floats or a float with an alpha interpolator. + - `FloatWithAlpha` - A record containing some value and an alpha typically used for blending. +- `net.minecraft.world.entity.ai.Brain` + - `getSchedule` is removed + - `setSchedule` now takes in an `EnvrionmentAttribute` instead of a `Schedule` + - `updateActivityFromSchedule` now takes in the `EnvironmentAttributeSystem` and position instead of the day time +- `net.minecraft.world.entity.animal.bee.Bee#isNightOrRaining` replaced with `EnvironmentAttributes#BEES_STAY_IN_HIVE` +- `net.minecraft.world.entity.player.Player$BedSleepingProblem` is now a record + - `NOT_POSSIBLE_HERE` -> `BedRule#EXPLODES` + - `NOT_POSSIBLE_NOW` -> `BedRule#CAN_SLEEP_WHEN_DARK` +- `net.minecraft.world.entity.schedule` + - `Keyframe` -> `.minecraft.util.Keyframe`, not one-to-one + - `Schedule` is removed, its logic replaced by `Timeline`, `Timelines` + - `ScheduleBuilder` is remvoed, its logic replaced by `Timeline$Builder` + - `Timeline` -> `.world.timeline.Timeline`, not one-to-one +- `net.minecraft.world.entity.variant.SpawnContext` now takes in the `EnvironmentAttributeReader` +- `net.minecraft.world.level` + - `Level` + - `isMoonVisible` replaced by `EnvironmentAttributes#MOON_ANGLE` + - `getSunAngle` replaced by `EnvironmentAttributes#SUN_ANGLE` + - `canHaveWeather` is now `public` + - `LevelAccessor` now implements `LevelReader` instead of `LevelTimeAccess` + - `LevelReader#environmentAttributes` - Returns the manager for get the environment attribute within a dimension and its associated biomes. + - `LevelTimeAccess` interface is removed + - `MoonPhase` + - `CODEC` - The codec for the moon phase. + - `PHASE_LENGTH` - The number of ticks that a moon phase is present for. + - `startTick` - The start tick for a particular phase. +- `net.minecraft.world.level.biome` + - `AmbientAdditionsSettings` -> `.world.attribute.AmbientAdditionsSettings` + - `AmbientMoodSettings` -> `.world.attribute.AmbientMoodSettings` + - `AmbientParticleSettings` -> `.world.attribute.AmbientParticle` + - `Biome` now takes in the `EnvironmentAttributeMap` + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR` + - `getFogColor` -> `EnvironmentAttributes#FOG_COLOR` + - `getAttributes` - Gets the attributes for this biome. + - `getWaterFogColor` -> `EnvironmentAttributes#WATER_FOG_COLOR` + - `getAmbientParticle` -> `EnvironmentAttributes#AMBIENT_PARTICLES` + - `getAmbientLoop` -> `AmbientSounds#loop` environment attribute + - `getAmbientMood` -> `AmbientSounds#mood` environment attribute + - `getAmbientAdditions` -> `AmbientSounds#additions` environment attribute + - `getBackgroundMusic` -> `EnvironmentAttributes#BACKGROUND_MUSIC` + - `getBackgroundMusicVolume` -> `EnvironmentAttributes#MUSIC_VOLUME` + - `$Builder` + - `putAttributes` - Puts all attributes from another map. + - `setAttribute` - Sets an environment attribute. + - `modifyAttribute` - Modifies an attribute source for the biome. + - `BiomeSpecialEffects` is now a record + - `getFogColor` -> `EnvironmentAttributes#FOG_COLOR` + - `getWaterFogColor` -> `EnvironmentAttributes#WATER_FOG_COLOR` + - `getSkyColor` -> `EnvironmentAttributes#SKY_COLOR` + - `getAmbientParticleSettings` -> `EnvironmentAttributes#AMBIENT_PARTICLES` + - `getAmbientLoopSoundEvent` -> `AmbientSounds#loop` environment attribute + - `getAmbientMoodSettings` -> `AmbientSounds#mood` environment attribute + - `getAmbientAdditionsSettings` -> `AmbientSounds#additions` environment attribute + - `getBackgroundMusic` -> `EnvironmentAttributes#BACKGROUND_MUSIC` + - `getBackgroundMusicVolume` -> `EnvironmentAttributes#MUSIC_VOLUME` +- `net.minecraft.world.level.block` + - `BedBlock#canSetSpawn` -> `BedRule#canSetSpawn` environment attribute + - `CreakingHeartBlock#isNaturalNight` replaced by `EnvironmentAttributes#CREAKING_ACTIVE` + - `RespawnAnchorBlock#canSetSpawn` now takes in the `ServerLevel` and `BlockPos` +- `net.minecraft.world.level.dimension` + - `BuiltinDimensionTypes#*_EFFECTS` are removed + - `DimensionDefaults#OVERWORLD_CLOUD_HEIGHT` is now a `float` + - `DimensionType` + - `fixedTime` -> `hasFixedTime`, now a `boolean` instead of a `OptionalLong` + - `natural`, `effectsLocation` are removed + - `skybox` - The skybox to display within the dimension. + - `cardinalLightType` - The type of light permeating through a dimension. + - `timelines` - A set of timelines that modify the environment attributes of this dimension. + - `ultraWarm` -> `EnvironmentAttributes#WATER_EVAPORATES`, `FAST_LAVA`, `DEFAULT_DRIPSTONE_PARTICLE` + - `bedWorks` -> `EnvironmentAttributes#BED_RULE` + - `respawnAnchorWorks` -> `EnvironmentAttributes#RESPAWN_ANCHOR_WORKS` + - `cloudHeight` -> `EnvironmentAttributes#CLOUD_HEIGHT` + - `attribute` - Gets the attributes for this dimension. + - `piglinSafe`, `$MonsterSettings#piglinSafe` -> `EnvironmentAttributes#PIGLINS_ZOMBIFY` + - `hasRaids`, `$MonsterSettings#hasRaids` -> `EnvironmentAttributes#CAN_START_RAID` + - `timeOfDay` is removed + - `moonPhase` replaced by `EnvironmentAttributes#MOON_PHASE` + - `hasEndFlashes` - Returns whether the skybox is the end. + - `$CardinalLightType` - The light permeating through a dimension. + - `$Skybox` - The skybox of a dimension. +- `net.minecraft.world.level.material.FogType#DIMENSION_OR_BOSS` is removed +- `net.minecraft.world.timeline` + - `AttributeTrack` - A track that applies the attribute modifier with the argument sampled from the given keyframe track. + - `AttributeTrackSampler` - A baked attribute track. + - `Timeline` - A map of attributes to tracks that are applied based on the given time in ticks modulo the period. + - `Timelines` - All vanilla timelines. + +### The Game Rule Shuffle + +The gamerule system has been overhauled to a degree, allowing its keys to be stored as proper registry objects while still having its values limited to either integers or booleans. Most of the classes are basically just combinations of others. + +#### Existing Game Rules + +Existing game rules are still in a `GameRules` class, just moved to a different location. Their fields have been renamed and seem to follow some basic rules: + +1. Rules no longer have the `RULE_` prefix +1. Rules now have underscores separating words +1. The `DO` prefix is removed from rule names (e.g. `RULE_DOENTITYDROPS` -> `ENTITY_DROPS`) +1. The `SPAWNING` suffix has been replaced with the `SPAWN_` prefix (e.g. `RULE_DOMOBSPAWNING` -> `SPAWN_MOBS`) +1. The `DISABLE` prefix is removed, meaning that their values are inverted (e.g., `RULE_DISABLERAIDS` -> `RAIDS`) + +While there are some edge cases, searching for a specific word in the previous game rule name will most likely lead you to the new name (e.g., searching for `ADVANCEMENT` in `RULE_ANNOUNCEADVANCEMENTS` leads to `SHOW_ADVANCEMENT_MESSAGES`). + +To actually get a value from the game rules, you would use `GameRules#get` instead of the previous `getBoolean` and `getInteger`. The type is obtained from the generic on the registered `GameRule`. + +```java +// With ServerLevel level +boolean fallDamage = level.getGameRules().get(GameRules.FALL_DAMAGE); +``` + +Additionally, setting the game rule is now simplified to calling `GameRules#set` -- taking in the `GameRule`, value, and the current server if the changes are propogated through `MinecraftServer#onGameRuleChanged`, which it should generally be. + +```java +// With ServerLevel level +level.getGameRules().set(GameRules.FALL_DAMAGE, false, level.getServer()); +``` + +#### Creating a Game Rule + +Game rules are created through the `GameRule` class, which is basically a type definition of how the game rule functions depending on its caller. Its generic represents the type of the value being held. The only hardcoded concepts that separate this from being a general type is that the actual arguments can be limited to a specific range, and that they store the default value. Otherwise, the fields are mostly the same from its previous counterparts in `GameRules$Type` and `GameRules$Key`. + +Then, once created, the `GameRule` must be statically registered to `BuiltInRegistries#GAME_RULE` + +```java +public static final GameRule EXAMPLE_RULE = Registry.register( + BuiltInRegistries.GAME_RULE + Identifier.withNamespaceAndPath("examplemod", "example_rule"), + new GameRule( + // The category that best represents the game rule. + // This is only used by the edit game rule screen + // when first constructing the world. + // A custom category can be created by calling + // `GameRuleCategory#register` or just its constructor + // as the sort order goes unused + GameRuleCategory.register( + Identifier.withNamespaceAndPath("examplemod", "example_category") + ), + // The type of the game rule, represenative of the + // JSON schema version of the generic. + // This is only used by the management system for + // checking an untyped rule. + GameRuleType.INT, + // The argument type used for serializing the value + // in commands. + // This can be range-limited based on the constructor. + IntegerArgumentType.integer(0, 5), + // A caller that runs typically during the visiting process + // for each game rule. + // This caller is only used by the edit game rules screen + // for adding the correct component that modifies the value. + // `GameRuleTypeVisitor#visit` should not be used here + // as the visitor already calls that function. + GameRuleTypeVisitor::visitInteger, + // The codec used to serialize the game rules to disk + // or for the managment service. + // This can be range-limited based on the constructor. + Codec.intRange(0, 5), + // A function that maps the set value to an integer + // result used when setting or querying the game rule + // via a command. + // This is the only case when a result of `0` does not + // mean the command has failed. + gameRuleValue -> gameRuleValue, + // The default value to set for this rule. + 3, + // A feature flag set that are required for this game rule + // to be enabled in game. + // An empty flag set means it should be enabled at all times. + FeatureFlagSet.of() + ) +); +``` + +`net.minecraft.client.gui.screens.worldselection` + - `EditGameRulesScreen` + - `$BooleanRuleEntry` now takes in a `GameRule` instead of a `GameRules$BooleanValue` + - `$EntryFactory` no longer bounds its generic + - `$IntegerRuleEntry` now takes in a `GameRule` instead of a `GameRules$IntegerValue` + - `InitialWorldCreationOptions#disabledGameRules` is now a `GameRuleMap` +- `net.minecraft.core.registries.BuiltInRegistries#GAME_RULE`, `Registries#GAME_RULE` - Game rule registry. +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` + - `$SetGameRules` now takes in a `GameRulesMap` instead of `$Entry`s + - `entry`, `$Entry` are removed +- `net.minecraft.server.MinecraftServer#onGameRuleChanged` now takes in the `GameRule` and value instead of the string key and `$Value` wrapper +- `net.minecraft.server.jsonrpc.api.Schema` + - `RULE_TYPE_SCHEMA` is now a `GameRuleType` instead of a `GameRulesService$RuleType` + - `TYPED_GAME_RULE_SCHEMA` is now a `GameRulesService$GameRuleUpdate` instead of a `GameRulesService$TypedRule` + - `UNTYPED_GAME_RULE_SCHEMA` is now a `GameRulesService$GameRuleUpdate` instead of a `GameRulesService$UntypedRule` +- `net.minecraft.server.jsonrpc.internalapi` + - `GameRules` interface is removed + - `MinecraftGameRuleService#getRule` -> `getRuleValue` +- `net.minecraft.server.jsonrpc.methods.GameRulesService` + - `$RuleType` is removed + - `$TypedRule`, `$UntypedRule` -> `$GameRuleUpdate`, not one-to-one +- `net.minecraft.server.notifications.NotificationService#onGameRuleChanged` now takes in the `GameRule` and value instead of the string key and `$Value` wrapper +- `net.minecraft.world.level.GameRules` + - The static rule keys are now located in `.gamerules.GameRules` without the `RULE_` prefix and underscores in-between words + - `DO` is removed from the name (e.g. `RULE_DOENTITYDROPS` -> `ENTITY_DROPS`) + - `SPAWNING` names now start with `SPAWN_` (e.g. `RULE_DOMOBSPAWNING` -> `SPAWN_MOBS`) + - The map behavior linking the key to its associated value is now handled by `GameRuleMap` + - `getBoolean`, `getInteger` -> `get` + - `$Key`, `$Type` -> `GameRule`, not one-to-one + - `GameRule` implements `FeatureElement` + - `$Category` -> `GameRuleCategory`, not one-to-one + - `$Value`, `$BooleanValue`, `$IntegerValue` are removed, replaced with the direct object being wrapped + - `$GameRuleTypeVisitor` -> `GameRuleTypeVisitor` + +### 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. + +#### Usage Annotations + +Mojang has recently given some integer values and flags an annotation, marking its intended usage. This does not affect modders in any way, as it likely seems to be a way to perform static analysis on the values passed around, probably for some kind of validation. + +- `com.mojang.blaze3d.buffers.GpuBuffer$Usage` - An annotation that marks whether a given integer defines the usage flags of the particular buffer. +- `com.mojang.blaze3d.platform.InputConstants$Value` - An annotation that marks whether a given integer defines the input of a device. +- `com.mojang.blaze3d.buffers.GpuTexture$Usage` - An annotation that marks whether a given integer defines the usage flags of the particular texture. +- `net.minecraft.client.input` + - `InputWithModifiers$Modifiers` - An annotation that marks whether a given integer defines the modifiers of an input. + - `KeyEvent$Action` - An annotation that marks whether a given integer defines the action being performed by the input (i.e., press, release, repeat). + - `MouseButtonInfo` + - `$Action` - An annotation that marks whether a given integer defines the action being performed by the mouse (i.e., press, release, repeat). + - `$MouseButton` - An annotation that marks whether a given integer defines the input of a mouse. +- `net.minecraft.server.level.TicketType$Flags` - An annotation that marks whether a given integer defines the flags of a ticket type. +- `net.minecraft.world.level.block.Block$UpdateFlags` - An annotation that marks whether a given integer defines the flags for a block update. + +#### Text Collectors + +`ActiveTextCollector` is a method of submitting strings and components to render, meant to provide common utilities for alignment, especially with text that goes off the screen. While this does not necessarily replace `GuiGraphics#drawString`, a few widgets require the use of the `ActiveTextCollector`, such as `AbstractStringWidget#renderLines`. + +An `ActiveTextCollector` can be created by calling one of the `GuiRenderer#textRenderer*` methods. They take in a `$HoveredTextEffects`, which handles how to render the component hover and click event, and a `Style` consumer callback for any additional handling. It also stores a set of default parameters, which basically represent the current pose opacity and screen rectangle. + +There are two methods two submit a piece of text for rendering: `accept` for standard strings, and `acceptScrolling*` for screens that go out of the rectangle, scrolling back and forth on the screen at a rate of roughly one unit per second (see the accessibility settings for an example). `accept` takes in, at most, five parameters: the alignment of the X position (`TextAlignment#LEFT` is like normal, `CENTER` the center of the text, `RIGHT` the end of the text), the X position for the alignment, Y position, parameters to override, and the text. `acceptScrolling` takes in, at most, seven parameters: the text, the starting X position center aligned, the leftmost X position, the rightmost X position, the topmost Y position, the bottommost Y position, and the parameters to override. + +```java +// In some method with GuiGraphics graphics +ActiveTextCollector collector = graphics.textRenderer( + // Render hover and click events + HoveredTextEffects.TOOLTIP_AND_CURSOR; +); + +collector.accept( + // Align the text to the center + TextAlignment.CENTER, + // Start X (in this case the center position) + 20, + // Start Y + 0, + // The parameters to use + collector.defaultParameters(), + // The text to display + Component.literal("Hello world!") +); +``` + +- `net.minecraft.client.gui` + - `ActiveTextCollector` - A helper for rendering text with certain parameters and alignments. + - `GuiGraphics` now takes in the mouse XY + - `textRenderer*` - Methods for constructing the helper for submit text in their appropriate location. + - `$HoveredTextEffects` - An enum that defines the text effects to apply when using the text collector. +- `net.minecraft.client.gui.components` + - `AbstractButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `renderWidget` is now final + - Use `renderContents` instead to submit elements + - `renderDefaultSprite` should be called in `renderContents` to blit the default sprite + - `renderString` -> `renderDefaultLabel`, not one-to-one + - `AbstractSliderButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `AbstractStringWidget` + - `visitLines` - Handles submitting text elements to the screen. + - `setColor`, `getColor` are removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `setComponentClickHandler` - Set the handler for when a component with the provided style is clicked. + - `AbstractWidget` + - `renderScrollingString` -> `renderScrollingStringOverContents`, not one-to-one + - `getAlpha` - Gets the alpha of the widget. + - `$WithInactiveMessage` - A widget that can change the message to display when inactive. + - `Button` is now abstract + - `$Plain` replicates the previous behavior + - `ChatComponent` + - `MESSAGE_BOTTOM_TO_MESSAGE_TOP` - The height of a chat component. + - `render` now takes in a `Font` and a `boolean` for whether to change the curse on insertions + - `captureClickableText` - Captures the clickable text to submit. + - `handleChatQueueClicked` replaced by `QUEUE_EXPAND_ID`, not one-to-one + - `getClickedComponentStyleAt` -> `$ChatGraphicsAccess#handleMessage`, not one-to-one + - `getMessageTagAt` -> `$ChatGraphicsAccess#handleTag`, `handleTagIcon`; not one-to-one + - `getWidth`, `getHeight`, `getScale` are now private + - `$AlphaCalculator` - Calculates the alpha for a given chat line. + - `$ChatGraphicsAccess` - An interface for handling the submission of the chat input. + - `$LineConsumer` no longer takes in the first three `int`s + - `FittingMultilineTextWidget#setColor` is removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `MultiLineLabel` + - `render`, `getStyle` -> `visitLines`, not one-to-one + - `$Align` -> `TextAlignment` + - `MultiLineTextWidget#setColor`, `configureStyleHandling` are removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `SplashRenderer` now takes in a `Component` instead of a `String` + - `SpriteIconButton#renderSprite` - Submits the sprite icon. + - `StringWidget#setColor` is removed + - Use the `ActiveTextCollector` in `visitLines` instead + - `TabButton` now extends `AbstractWidget$WithInactiveMessage` instead of `AbstractWidget` + - `renderString` -> `renderLabel`, now private, not one-to-one +- `net.minecraft.client.gui.screens.inventory.BookViewScreen#getClickedComponentStyleAt` -> `visitText`, now private, not one-to-one + +#### Shared Text Areas Debugger + +A new debug has been added that draws the bounding box each glyph, including the empty glyph. The color shifts slightly between each glyph for ease of differentiation, and changes entirely depending on if there is some combination of a click or hover event. + +- `net.minecraft.SharedConstants#DEBUG_ACTIVE_TEXT_AREAS` - A flag for the debugger drawing the bounds and effects of each glyph. +- `net.minecraft.client.gui.Font` + - `prepareText` now has an overload of whether to render something in the empty areas + - `$GlyphVisitor` + - `acceptGlyph` now takes in a `TextRenderable$Styled` instead of a `TextRenderable` + - `acceptEmptyArea` - Accepts an empty area to draw to the screen. + - `$PreparedTextBuilder` now takes in whether to include the empty areas for rendering +- `net.minecraft.client.gui.font` + - `ActiveArea` - Defines the bounds and style of the area to draw. + - `EmptyArea` - An area with nothing within it. + - `PlainTextRenderable` now implements `TextRenderable$Styled` instead of `TextRenderable` + - `width`, `height`, `ascent` - The bounds of the object. + - `TextRenderable$Styled` - A text renderable that defines some active area for its bounds. +- `net.minecraft.client.gui.font.glyphs.BakedGlyph#createGlyph` now returns a `TextRenderable$Styled` + +#### JSpecify Annotations + +Mojang has moved from using a mix of their own annotations to those available in JSpecify when required. As such, instead of all fields, methods, and parameters being marked as nonnull by default, it is replaced by `NullMarked`, which considers a type usage non-null unless explictly annotated as `Nullable`, barring some special cases. + +- `com.mojang.blaze3d.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed +- `com.mojang.math.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed +- `net.minecraft.FieldsAreNonnullByDefault`, `MethodsReturnNonnullByDefault` are removed + +#### Slot Sources + +Slot sources are an expansion upon the previous contents drop system in shulker boxes allowing any loot table to pulls its entries from some container slots. This can be used in any location where a `LootContext` is enabled, though it is currently only implemented as a loot pool entry. + +In vanilla, a slot source works by having some `LootContextArg`, which points to some loot context param value, return an object that implements `SlotProvider`. Currently, this refers to any `Container` or `Entity` implementation. The `SlotProvider` is then used by `SlotSource#provide` to construct a `SlotCollection`: a stream of deep copied `ItemStack`s. The stacks stored in the collection are then passed to the output of the pool. As this is all done in one of the `SlotSource#provide` implementations, it can reference anything (not just `SlotProvider`) as long as it can transform that data into the `SlotCollection`. + +```java +// A slot source whose 'slots' are the elements +// within an item tag. +public record TagSlotSource(TagKey tag) implements SlotSource { + + public static final MapCodec MAP_CODEC = TagKey.codec(Registries.ITEM) + .fieldOf("tag").xmap(TagSlotSource::new, TagSlotSource::tag); + + @Override + public SlotCollection provide(LootContext ctx) { + // Get the holder set for the tag + Optional> holderSetOpt = ctx.getResolver() + .lookup(Registries.ITEM).flatMap(getter -> getter.get(this.tag)); + + // Stream the elements and map to a SlotCollection + return holderSetOpt.map(holderSet -> + // `Item#getDefaultInstance` returns a new copy, so it can be used. + // If the ItemStack already exists, then `ItemStack#copy` should be + // called on each. + (SlotCollection) () -> holderSet.stream().map(holder -> holder.value().getDefaultInstance()) + ).orElse(SlotCollection.EMPTY); + } + + @Override + public MapCodec codec() { + // The codec used to serialize the slot source + return MAP_CODEC; + } +} + +// The map codec needs to be registered to the slot source type registry +Registry.register( + BuiltInRegistries.SLOT_SOURCE_TYPE + Identifier.withNamespaceAndPath("examplemod", "tag"), + TagSlotSource.MAP_CODEC +); +``` + +```json5 +// An example loot table +{ + // ... + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + // Use the slot source loot pool + "type": "minecraft:slots", + "slot_source": { + // Our slot source + "type": "examplemod:tag", + "tag": "minecraft:planks" + } + } + ] + } + // ... + ] +} +``` + +- `net.minecraft.advancements.criterion.SlotsPredicate#matches` now takes in a `SlotProvider` instead of an `Entity` +- `net.minecraft.core.registries.BuiltInRegistries#SLOT_SOURCE_TYPE`, `Registries#SLOT_SOURCE_TYPE` - Slot source type registry. +- `net.minecraft.world.Container` now extends `SlotProvider` + - `getSlot` - Gets an access for a single item. +- `net.minecraft.world.entity` + - `Entity` now implements `SlotProvider` + - `SlotAccess` + - `NULL` is removed + - `forContainer` -> `forListElement`, not one-to-one + - `SlotProvider` - An object that provides some access to its internal storage via slots. +- `net.minecraft.world.item.slot` + - `CompositeSlotSource` - A composite of multiple slot sources. + - `ContentsSlotSource` - Gets the slot contents. + - `EmptySlotSource` - An empty slot source. + - `FilteredSlotSource` - Filters the provided slot source pased on the item predicate. + - `GroupSlotSource` - Groups multiple slot sources together into one concatenated collection. + - `LimitSlotSource` - Limits the provided slot source to a maximum size. + - `RangeSlotSource` - Gets the desired range of slots. + - `SlotCollection` - A collection of slots to grab the item copies from. + - `SlotSource` - Given a loot context, returns a collection of slots to provide. + - `SlotSources` - The slot sources provided by vanilla. + - `TransformedSlotSource` - Transforms the provided slot source. +- `net.minecraft.world.level.storage.loot.ContainerComponentManipulator#getSlots` - Gets the slots of a data component on the stack. +- `net.minecraft.world.level.storage.loot.entries` + - `LootPoolEntries#SLOTS` - A pool that uses slots from a source. + - `SlotLoot` - A pool that gets its items from some slot source. + +#### Zombie Nautilus Variant + +Zombie nautilus are the newest addition to the variant datapack registry objects, taking in the familiar model and texture override along with the spawn conditions: + +```json5 +// A file located at: +// - `data/examplemod/zombie_nautilus_variant/example_zombie_nautilus.json` +{ + // Points to a texture at `assets/examplemod/textures/entity/nautilus/example_zombie_nautilus.png` + "asset_id": "examplemod:entity/nautilus/example_zombie_nautilus", + // Defines the `ZombieNautilusVariant$ModelType` that's used to select what entity model to render the zombie nautilus variant with + "model": "warm", + "spawn_conditions": [ + // The conditions for this variant to spawn + { + "priority": 0 + } + ] +} +``` + +- `net.minecraft.core.component.DataComponents#ZOMBIE_NAUTILUS_VARIANT` - The variant of the zombie nautilus. +- `net.minecraft.core.registries.Registries#ZOMBIE_NAUTILUS_VARIANT` - The registry key for the zombie nautilus variant. +- `net.minecraft.network.syncher.EntityDataSerializers#ZOMBIE_NAUTILUS_VARIANT` - The variant of the zombie nautilus. +- `net.minecraft.world.entity.animal.nautilus` + - `ZombieNautilusVariant` - A variant of a zombie nautilus. + - `ZombieNautilusVariants` - All vanilla zombie nautilus variants. + +#### `OptionEnum` Removal + +`OptionEnum` has been removed in favor of simply calling the `OptionInstance$Enum` constructor with the desired values and codec. As such, most `byId` methods have been replaced with some codec and the translatable entry is now stored as a `Component` than the translation key string. + +- `net.minecraft.client` + - `AttackIndicatorStatus` no longer implements `OptionEnum` + - `byId` -> `LEGACY_CODEC`, not one-to-one + - `getKey` -> `caption`, not one-to-one + - `CloudStatus` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `InactivityFpsLimit` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `OptionInstance#forOptionEnum` is removed + - `PrioritizeChunkUpdate` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `byId` -> `LEGACY_CODEC`, not one-to-one +- `net.minecraft.client.sounds.MusicManager$MusicFrequency` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one +- `net.minecraft.server.level.ParticleStatus` no longer implements `OptionEnum` + - `getKey` -> `caption`, not one-to-one + - `byId` -> `LEGACY_CODEC`, not one-to-one +- `net.minecraft.util.OptionEnum` is removed +- `net.minecraft.world.entity.HumanoidArm` no longer implements `OptionEnum` + - `BY_ID` is now private + - `getKey` -> `caption`, not one-to-one +- `net.minecraft.world.entity.player.ChatVisbility` no longer implements `OptionEnum` + - `byId` -> `LEGACY_CODEC`, not one-to-one + - `getKey` -> `caption`, not one-to-one + +#### Specific Logic Changes + +- `net.minecraft.client.renderer.entity.EntityRenderState#lightCoords` now defaults to 0xF000F0. +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen#keyPressed` no longer returns `true` if the key is not handled by the screen, instead returning `false`. +- `net.minecraft.util.Mth#clampedLerp` parameters have been reordered for both overloads. The methods now take in the step, the original value, and the next value; instead of the original value, next value, and the step value. + +#### Tag Changes + +- `minecraft:biome` + - `plays_underwater_music` is removed + - Replaced by `BackgroundMusic#underwaterMusic` environment attribute + - `has_closer_water_fog` is removed + - Replaced by `EnvironmentAttributes#WATER_FOG_END_DISTANCE` + - `increased_fire_burnout` is removed + - Replaced by `EnvironmentAttributes#INCREASED_FIRE_BURNOUT` + - `snow_golem_melts` is removed + - Replaced by `EnvironmentAttributes#SNOW_GOLEM_MELTS` + - `without_patrol_spawns` is removed + - Replaced by `EnvironmentAttributes#CAN_PILLAGER_PATROL_SPAWN` + - `spawns_coral_variant_zombie_nautilus` +- `minecraft:block` + - `can_glide_through` +- `minecraft:entity_type` + - `burn_in_daylight` + - `can_float_while_ridden` + - `can_wear_nautilus_armor` + - `nautilus_hostiles` +- `minecraft:item` + - `camel_husk_food` + - `zombie_horse_food` + - `nautilus_bucket_food` + - `nautilus_food` + - `nautilus_taming_items` + - `spears` + - `enchantable/lunge` + - `enchantable/sword` -> `enchantable/melee_weapon`, `enchantable/sweeping` +- `minecraft:timeline` + - `universal` + - `in_overworld` + - `in_nether` + - `in_end` + +#### List of Additions + +- `com.mojang.blaze3d.GraphicsWorkarounds#isAmd` - Whether the GPU's vendor is AMD. +- `com.mojang.blaze3d.opengl` + - `GlConst#GL_POINTS` - Defines the points primitive as the type to render. + - `GlTimerQuery` - The OpenGL implementation of querying an object, typically the time elapsed. +- `com.mojang.blaze3d.platform.InputConstants#MOUSE_BUTTON_*` - The inputs of a mouse click, represented by numbers as they may have different intended purposes. +- `com.mojang.blaze3d.systems` + - `CommandEncoder#timerQueryBegin`, `timerQueryEnd` - Handlers for keeping track of the time elapsed. + - `GpuQuery` - A query for an arbitrary object, such as the time elapsed. +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat` + - `POSITION_COLOR_LINE_WIDTH` - A vertex format that specifies the position, color, and line width. + - `POSITION_COLOR_NORMAL_LINE_WIDTH` - A vertex format that specifies the position, color, normal, and line width. + - `VertexFormat$Mode#POINTS` - A vertex mode that draws points. + - `VertexFormatElement#LINE_WIDTH` - A vertex element that takes in one float representing the width. +- `com.mojang.math` + - `OctahedralGroup` + - `BLOCK_ROT_*` - Constants representing the block rotations. + - `permutation` - Returns the symmetric group. + - `Quadrant#fromXYZAngles` - Gets the octahedral group that represents the three quadrant rotations. + - `SymmetricGroup3#inverse` - Returns the inverse group. +- `net.minecraft` + - `SharedConstants` + - `MAX_CLOUD_DISTANCE` - The maximum cloud range to be rendered by the player. + - `DEFAULT_RANDOM_TICK_SPEED` - The default random tick speed. + - `Util#localizedDateFormatter` - Returns the localized `DateTimeFormatter` for the given style. +- `net.minecraft.advancements.criterion` + - `DataComponentMatchers$Builder#any` - Matches whether there exists some data for the component. + - `SpearMobsTrigger` - A trigger that checks the number of entities the player has speared with a kinetic weapon. +- `net.minecraft.client` + - `GuiMessage` + - `splitLines` - Splits the component into lines with the desired width. + - `getTagIconLeft` - Gets the width of the content with an additional four pixel padding. + - `KeyMapping$Category#DEBUG` - The debug keyboard category. + - `MusicToastDisplayState` - An enum representing how the toast for music should be displayed. + - `NarratorStatus#LEGACY_CODEC` - A codec to deserialize the enum narrator status. + - `OptionInstance` + - `$IntRangeBase` + - `next` - Gets the next value. + - `previous` - Gets the previous value. + - `$SliderableEnum` - A slider that selects between enum options. + - `$SliderableValueSet` + - `next` - Gets the next value. + - `previous` - Gets the previous value. + - `Options` + - `keyToggleGui` - A key mapping that toggles the in-game gui. + - `keyToggleSpectatorShaderEffects` - A key mapping that toggles the shader effects tied to a camera entity. + - `keyDebug*`, `debugKeys` - Key mappings for the debug renderers. + - `weatherRadius` - Returns the radius of the weather particles to render in an area. + - `cutoutLeaves` - Whether leaves should render in cutout or solid. + - `vignette` - Whether a vignette should be applied to the screen. + - `improvedTransparency` - Whether to use the transparency post processor. + - `chunkSectionFadeInTime` - The amount of second that should be taken for a chunk to fade in when first rendered. + - `maxAnisotropyBit` - The bit value of the anisotrophic filtering level. + - `maxAnisotropyValue` - The ansiotrophic filtering level. +- `net.minecraft.client.animation.definitions.NautilusAnimation` - The animation definitions for the nautilus. +- `net.minecraft.client.data.models.ItemModelGenerators` + - `generateSpear` - Generates the spear item model. + - `generateItemWithTintedBaseLayer` - Generates a two layered item model whose base layer is tinted. +- `net.minecraft.client.data.models.model.ModelTemplates#SPEAR_IN_HAND` - A template for the spear in hand model. +- `net.minecraft.client.gui.components` + - `AbstractButton#setOverrideRenderHighlightedSprite` - Overrides whether to use the focused enabled/disabled sprite. + - `Checkbox#adjustWidth` - Sets the width of the widget using the message, font, and its initial X position. + - `CycleButton` + - `$Builder#withSprite` - Sets the supplier used to get the sprite based on the current button state. + - `$DisplayState` - How the button shoud be displayed. + - `$SpriteSupplier` - Gets the sprite location given the current button state. + - `EditBox#setInvertHighlightedTextColor` - Sets whether to invert the highlighted text color. + - `FocusableTextWidget` + - `getPadding` - Returns the text padding. + - `updateWidth` - Updates the width the text can take up. + - `updateHeight` - Update the height the text can take up. + - `$Builder` - Builds the component. + - `MultiLineTextWidget#getTextX`, `getTextY` - Gets the text position. + - `OptionsList` + - `addHeader` - Adds a header entry. + - `resetOption` - Resets the option value. + - `$AbstractEntry` - Defines the element within the selection list. + - `$HeaderEntry` - An entry that represents the header of a section. + - `$OptionInstanceWidget` - A record containing the widget and optionally the option instance. + - `ResettableOptionWidget` - A widget that can reset its value to a default. + - `SelectableEntry` - A utility for checking whether the mouse is in a specific region. +- `net.minecraft.client.gui.layouts.HeaderAndFooterLayout#MAGIC_PADDING` - A common padding between the elements. +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementTab#canScrollHorizontally`, `canScrollVertically` - Checks whether the tab data can be scrolled in a given direction. + - `AdvancementTabType#getWidth`, `getHeight` - Gets the width / height of the tab. +- `net.minecraft.client.gui.screens.debug.DebugOptionsScreen#getOptionList` - Returns the list of options for the debug screen. +- `net.minecraft.client.gui.screens.inventory` + - `AbstractMountInventoryScreen` - A screen representing a mount's inventory. + - `EffectsInInventory` + - `SPACING` - The spacing between effects. + - `SPRITE_SQUARE_SIZE` - The size of the effect icon. + - `NautilusInventoryScreen` - The screen for the nautilus inventory. +- `net.minecraft.client.gui.screens.options` + - `OptionsSubScreen#resetOption` - Resets the option value to its default. + - `VideoSettingsScreen#updateTransparencyButton` - Sets the transparency button to the current option value. +- `net.minecraft.client.gui.screens.packs.TransferableSelectionList$PackEntry#ICON_SIZE` - The size of the pack icon. +- `net.minecraft.client.gui.screens.recipebook.RecipeBookTabButton#select`, `unselect` - Handles tab display selection. +- `net.minecraft.client.input.InputQuirks#EDIT_SHORTCUT_KEY_LEFT`, `EDIT_SHORTCUT_KEY_RIGHT` -> `InputWithModifiers#hasControlDownWithQuirk`, not one-to-one +- `net.minecraft.client.model.HumanoidModel$ArmPose` + - `SPEAR` - The spear third person arm pose. + - `animateUseItem` - Modifies the `PoseStack` given the entity state, use time, arm, and stack. + - `affectsOffhandPose` - Whether the arm animation will affect the offhand pose. +- `net.minecraft.client.model.animal.nautilus` + - `NautilusArmorModel` - The armor model for a nautilus. + - `NautilusModel` - The model for a nautilus. + - `NautilusSaddleModel` - The saddle model for a nautilus. +- `net.minecraft.client.model.effects.SpearAnimations` - The animations performed when using a spear. +- `net.minecraft.client.model.geom` + - `ModelLayers` + - `*NAUTILUS*` - The model layers for the nautilus. + - `UNDEAD_HORSE*_ARMOR` - The armor model layers for the undead horse. + - `PartName` + - `INNER_MOUTH`, `LOWER_MOUTH` - Part names for a mouth. + - `SHELL` - Part name for a shell. + - `*_CORAL*` - Part names for the corals on a zombie nautilus. +- `net.minecraft.client.model.geom.builders.UVPair#pack`, `unpack*` - Handles packing/unpacking of a UV into a `long`. +- `net.minecraft.client.model.monster.nautilus.ZombieNautilusCoralModel` - The model for the warm variant of a zombie nautilus. +- `net.minecraft.client.model.monster.skeleton.SkeletonModel#createSingleModelDualBodyLayer` - Creates a parched layer definition. +- `net.minecraft.client.multiplayer` + - `ClientPacketListener#hasClientLoaded` - Whether the client is loaded. + - `MultiPlayerGameMode#piercingAttack` - Initiates a lunging attack. +- `net.minecraft.client.player.LocalPlayer#raycastHitResult` - Gets the hit result for the camera entity for the given partial tick. +- `net.minecraft.client.renderer` + - `DynamicUniforms` + - `CHUNK_SECTION_UBO_SIZE` - The uniform buffer object size for the chunk section. + - `writeChunkSections` - Writes a varargs of chunk sections to the uniform storage. + - `$ChunkSectionInfo` - The dynamic uniform for the chunk section. + - `GameRenderer` + - `updateCamera` - Calls the setup function for the camera. + - `getPanoramicScreenshotParameters` - Get the screenshot parameters for panoramic mode. + - `PanoramicScreenshotParameters` - The screenshot parameters for panoramic mode. + - `Sheets#CELESTIAL_SHEET` - The atlas for the celestial textures. +- `net.minecraft.client.renderer.blockentity.BlockEntityWithBoundingBoxRenderer#STRUCTURE_VOIDS_COLOR` - The void color for a structure. +- `net.minecraft.client.renderer.chunk.SectionRenderDispatcher$RenderSection` + - `getVisibility` - Returns the current alpha of the chunk. + - `setFadeDuration` - Sets the amount of time it should take for a chunk to fade in. + - `setWasPreviouslyEmpty`, `wasPreviouslyEmpty` - Handles whether the section did not previously exist. +- `net.minecraft.client.renderer.entity` + - `CamelHuskRenderer` - The entity renderer for a camel husk. + - `CamelRenderer#createCamelSaddleLayer` - Creates the saddle layer for the camel. + - `NautilusRenderer` - The entity renderer for a nautilus. + - `ParchedRenderer` - The entity renderer for a parched. + - `ZombieNautilusRenderer` - The entity renderer for a zombie nautilus. +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` + - `swingAnimationType` - The animation to play when swinging their hand. + - `ticksUsingItem` - How many ticks the item has been used for. + - `getUseItemStackForArm` - Returns the held item stack based on the arm. + - `LivingEntityRenderState#ticksSinceKineticHitFeedback` - The amount of ticks since this entity was hit with a kinetic weapon. + - `NautilusRenderState` - The entity render state of a nautilus. + - `UndeadRenderState` - The entity render state for an undead humanoid. +- `net.minecraft.client.renderer.item.ItemModelResolver#swapAnimationScale` - Gets the scale of the swap animation for the stack. +- `net.minecraft.client.renderer.state.LevelRenderState#gameTime` - The current game time. +- `net.minecraft.client.resources.SplashManager` component fields - The components for the special messages. +- `net.minecraft.client.resources.model` + - `BlockModelRotation#IDENTITY` - The identity rotation. + - `EquipmentClientInfo#NAUTILUS_*` - The layers for the nautilus. +- `net.minecraft.core.Vec3i` + - `multiply` - Multiplies each component with a provided scalar. + - `toMutable` - Returns a mutable `Vector3i`. +- `net.minecraft.data.AtlasIds#CELESTIAL_SHEET` - The atlas for the celestial textures. +- `net.minecraft.data.recipes.RecipeProvider#waxedChiseled` - The recipe for a waxed chiseled block. +- `net.minecraft.gametest.framework.GameTestHelper#getAbsoluteDirection` - Returns the absolute direction from the test relative direction. +- `net.minecraft.nbt.NbtAccounter` + - `defaultQuota` - An accounter with a maximum of 2 MiB allocated. + - `uncompressedQuota` - An accounter with a maximum of 100 MiB allocated. +- `net.minecraft.network.chat.MutableComponent#withoutShadow`, `Style#withoutShadow` - Removes the drop shadow from the text. +- `net.minecraft.network.protocol.game.ServerboundPlayerActionPacket$Action#STAB` - The player performed the stab action. +- `net.minecraft.network.syncher.EntityDataSerializers#HUMANOID_ARM` - The main hand of the humanoid. +- `net.minecraft.resources.Identifier#toShortString` - Returns the string of the location. Namespace is omitted if `minecraft`. +- `net.minecraft.server` + - `MinecraftServer` + - `getServerActivityMonitor` - Returns the monitor that sends the server activity notification. + - `getStopwatches` - Returns a map of ids to timers. + - `ServerScoreboard#storeToSaveDataIfDirty` - Writes the data if dirty. +- `net.minecraft.server.commands.StopwatchCommand` - A command that starts or stops a stopwatch. +- `net.minecraft.server.dedicated.DedicatedServerProperties#managementServerAllowedOrigins` - The origins a request from the management server can come from. +- `net.minecraft.server.jsonrpc.OutgoingRpcMethods#SERVER_ACTIVITY_OCCURRED` - A request made from the minecraft server about server activity occurring. +- `net.minecraft.server.jsonrpc.api.Schema` + - `BOOL_OR_INT_SCHEMA` - A schema for a field that can be either a boolean or integer. + - `typedCodec` - Returns the codec for the schema. + - `info` - Returns a copy of the schema. +- `net.minecraft.server.level` + - `ChunkMap#getChunkDataFixContextTag` - Returns the datafix tag for the chunk data. + - `ServerLevel` + - `getDayCount` - Gets the number of days that has passed. + - `canSpreadFireAround` - Whether fire can spread at the given block position. +- `net.minecraft.server.network` + - `EventLoopGroupHolder` - A holder for managing the event loop and channels for communicating with some end, whether local or socket-based. + - `ServerGamePacketListenerImpl#resetFlyingTicks` - Resets how long the player has been flying. +- `net.minecraft.server.notifications` + - `NotificationService#serverActivityOccurred` - Notifies the management server that activity has occurred. + - `ServerActivityMonitor` - The monitor that sends the server activity notification +- `net.minecraft.util` + - `ARGB` + - `srgbToLinearChannel` - Converts the sRGB value into a linear color space. + - `linearToSrgbChannel` - Converts the linear value into a sRGB color space. + - `meanLinear` - Computes the mean using the linear color space for four values, then converting it back into sRGB. + - `addRgb` - Adds the RGB channels, using the alpha from the first value. + - `subtractRgb` - Subtracts the RGB channels, using the alpha from the first value. + - `multiplyAlpha` - Multiplies the alpha value into the provided ARGB value. + - `linearLerp` - Linearly interpolates the color by converting into the linear color space. + - `white`, `black` - Colors with the provided alpha. + - `alphaBlend` - Blends two colors along with their alpha value. + - `vector4fFromARGB32` - Converts an ARGB value to four floats. + - `Ease` - A utility full of easing functions. + - `ExtraCodecs` + - `NON_NEGATIVE_LONG`, `POSITIVE_LONG` - Longs with the listed constraints. + - `longRange` - A long codec that validates whether it is between the provided range. + - `STRING_RGB_COLOR`, `STRING_ARGB_COLOR` - A codec allowing for an (A)RGB value expressed in hex form as a string. + - `MAX_PROPERTY_NAME_LENGTH`, `MAX_PROPERTY_VALUE_LENGTH`, `MAX_PROPERTY_SIGNATURE_LENGTH`, `MAX_PROPERTIES` - Constants related to serializing the property map. + - `Mth` + - `cube` - Cubes a number. + - `chessboardDistance` - Computes the absolute maximum difference between two pairs of coordinates; the larger axis difference is returned. + - `SpecialDates` - A utility containing the dates that Mojang changes some behavior or rendering for. + - `TriState` + - `CODEC` - The codec for the tristate. + - `from` - Turns a boolean into a tristate. +- `net.minecraft.util.profiling.jfr.JvmProfiler#onClientTick` - Runs on client tick, taking in the current FPS. +- `net.minecraft.util.profiling.jfr.event.ClientFpsEvent` - An event that keeps track of the client FPS. +- `net.minecraft.util.profiling.jfr.stats.FpsStat` - A record containing the client FPS. +- `net.minecraft.world` + - `LockCode#canUnlock` - Whether the given player can unlock this code. + - `Stopwatch` - A record that holds the creation time and amount of time that has elapsed. + - `Stopwatches` - A tracker for starting, managing, and stopping stopwatches. +- `net.minecraft.world.effect` + - `MobEffects#BREATH_OF_THE_NAUTILUS` - Prevents the user from losing air underwater. + - `MobEffectUtil#shouldEffectsRefillAirsupply` - Whether the entity has an effect that refills the air supply while under a liquid. +- `net.minecraft.world.entity` + - `Entity` + - `getHeadLookAngle` - Calculates the view vector of the head rotation. + - `updateDataBeforeSync` - Updates the data stored in the entity before syncing to the client. + - `computeSpeed` - Computes last known speed and position of the entity. + - `getKnownSpeed` - Gets the last known speed of the entity. + - `hasMovedHorizontallyRecently` - If the last known speed's horizontal distance is larger than 0, more specifically the margin of error. + - `EntityProcessor` - A post processor for an entity when loading. + - `EntityEvent#KINETIC_HIT` - An event fired when an entity is hit with a kinetic weapon. + - `HumanoidArm#STREAM_CODEC` - The network codec for the arm enum. + - `LivingEntity` + - `DEFAULT_KNOCKBACK` - The default knockback applied to an entity on hit. + - `itemSwapTicker` - The amount of time taken when swapping items. + - `recentKineticEnemies` - The attackers that have recently attacked with a kinetic weapon. + - `lungeForwardMaybe` - Apply the lunge effects. + - `causeExtraKnockback` - Applies an multiplicative force to the knockback. + - `wasRecentlyStabbed`, `rememberStabbedEntity` - Handles enemies that were stabbed with a kinetic weapon. + - `stabAttack` - Handles when a mob is stabbed by this entity. + - `onAttack` - Handles when this entity has attacked another entity. + - `getTicksUsingItem` - Returns the number of ticks this item has been used for. + - `getTicksSinceLastKineticHitFeedback` - The number of ticks that has passed since this entity was last hit with a kinetic weapon. + - `shouldTravelInFluid` - If this entity should travel in the given fluid. + - `travelInWater` - Moves an entity as if they were in water. + - `Mob#sunProtectionSlot` - The equipment slot that protects the entity from the sun. + - `NeutralMob#level` - Returns the level the entity is in. + - `PlayerRideableJumping#getPlayerJumpPendingScale` - Returns the scalar to apply to the entity on player jump. +- `net.minecraft.world.entity.ai.attributes.Attributes#DEFAULT_ATTACK_SPEED` - The default attack speed. +- `net.minecraft.world.entity.ai.memory.MemoryModuleType` + - `CHARGE_COOLDOWN_TICKS` - The number of cooldown ticks after a charge attack. + - `ATTACK_TARGET_COOLDOWN` - The number of cooldown ticks before attacking a target. +- `net.minecraft.world.entity.ai.sensing.TemptingSensor#forAnimal` - A sensor that special cases animal entities for check if the desired item is food. +- `net.minecraft.world.entity.animal.camel` + - `Camel` + - `getDashingSound`, `getDashReadySound` - Camel dashing sounds. + - `getStandUpSound`, `getSitDownSound` - Camel sit/stand sounds. + - `getSaddleSound` - Camel saddle sound. + - `CamelHusk` - The camel husk entity. +- `net.minecraft.world.entity.animal.equine.AbstractHorse#isMobControlled` - Whether a mob can control this horse. +- `net.minecraft.world.entity.animal.nautilus` + - `AbstractNautilus` - The core of the nautilus entity. + - `Nautilus` - The nautilus entity. + - `NautilusAi` - The brain of a nautilus. + - `ZombieNautilus` - The zombie nautilus entity. + - `ZombieNautilusAi` - The brain of a zombie nautilus. +- `net.minecraft.world.entity.decoration.HangingEntity#hasLevelCollision` - Whether this entity is colliding with a block or the border in a given bounds. +- `net.minecraft.world.entity.monster.skeleton.Parched` - The parched entity. +- `net.minecraft.world.entity.monster.zombie.Husk$HuskGroupData` - The group data for the husk. +- `net.minecraft.world.entity.player.Player` + - `cannotAttackWithItem` - Checks whether the player cannot attack with the item. + - `getItemSwapScale` - Returns the scalar to use for the item swap animation. + - `resetOnlyAttackStrengthTicker` - Resets the attack strength ticker. + - `openNautilusInventory` - Opens the inventory of the interacted nautilus. + - `applyPostImpulseGraceTime`, `isInPostImpulseGraceTime` - Handles the grace time between impulses. +- `net.minecraft.world.food.FoodData#hasEnoughFood` - Whether the current food level is greater than 6 hunger (or three full hunger bars). +- `net.minecraft.world.inventory` + - `AbstractMountInventoryMenu` - The inventory menu for a mount. + - `NautilusInventoryMenu` - The inventory menu of a nautilus. +- `net.minecraft.world.item` + - `HoneycombItem#WAXED_RECIPES` - A map of waxed block to their recipe categories and name. + - `Item$Properties` + - `spear` - Adds the spear components. + - `nautilusArmor` - Adds the nautilus armor components. + - `ItemStack#matchesIgnoringComponents` - Whether the stack matches ignoring all components that match the predicate. + - `ItemUseAnimation` + - `TRIDENT` - The trident use animation. + - `hasCustomArmTransform` - Whether the animation provides a custom transform to the arm. +- `net.minecraft.world.item.enchantment` + - `Enchantment#doLunge` - Applies the post piercing attack effect. + - `EnchantmentEffectComponents#POST_PIERCING_ATTACK` - The effect to apply after a piercing attack. + - `EnchantmentHelper#doLungeEffects` - Applies the effect on lunge. + - `LevelBasedValue$Exponent` - Applies an exponent given the base and power. +- `net.minecraft.world.item.enchantment.effects` + - `ApplyEntityImpulse` - An entity effect that adds an impulse in the direction of the look angle. + - `ApplyExhaustion` - An entity effect that applies food exhaustion to the player if they are using the enchanted item. + - `ScaleExponentially` - A value effect that multiplies the value by a number raised to some exponent. +- `net.minecraft.world.level` + - `Chunk#isValid` - Whether the chunk pos is within the maximum allowed coordinate world (within the 30 million block radius). + - `CollisionGetter` + - `noEntityCollision` - Whether the entity is not colliding with another entity in the given bounds. + - `noBorderCollision` - Whether the entity is not colliding with the world border in the given bounds. + - `Level#isInValidBounds` - Whether the block position is not outside the maximum allowed coordinate world (build height for Y axis, 30 million block radius for XZ axis). + - `MoonPhase` - An enum representing the phases of the moon. +- `net.minecraft.world.level.border.WorldBorder$MovingBorderExtent#getPreviousSize` - Gets the previous size of the border. +- `net.minecraft.world.level.chunk.storage` + - `IOWorker#STORE_EMPTY` - A supplied `null` tag. + - `LegacyTagFixer` - An interface that handles how to upgrade a tag, like for the chunk. + - `SimpleRegionStorage` + - `isOldChunkAround` - Whether the chunk from a previous version still exists in this version. + - `injectDatafixingContext` - When the context is not `null`, adds it to the given tag. + - `markChunkDone` - Marks a chunk as finished for upgrading to the current version. + - `chunkScanner` - Gets the access used to scan chunks. +- `net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler#LAST_MONOLYTH_STRUCTURE_DATA_VERSION` - Returns the last data version containing glitched monolyths. +- `net.minecraft.world.level.storage.loot.LootContextArg` - An argument for a loot context to query. +- `net.minecraft.world.level.storage.loot.functions.DiscardItem` - A loot function that discards the loot, returning an empty stack. +- `net.minecraft.world.phys.Vec3` + - `offsetRandomXZ` - Offsets the point by a random amount in the XZ direction. + - `rotation` - Computes the rotation of the vector. + - `applyLocalCoordinatesToRotation` - Adds the components relative to the current rotation of the vector. + - `isFinite` - Returns whether all components of the vector are finite (not NaN or infinity) values. +- `net.minecraft.world.scores` + - `Scoreboard` + - `packPlayerTeams` - Packs the player teams into a serializable format. + - `packObjectives` - Packs the objectives into a serializable format. + - `packDisplaySlots` - Packs the display slots into a serializable format. + - `ScoreboardSaveData` + - `getData`, `setData` - Handles the packed scoreboard. + - `Packed$EMPTY` - Represents an empty scoreboard. +- `net.minecraft.world.waypoints.Waypoint$Icon#copyFrom` - Copies the icon color and style from another icon. + +#### List of Changes + +- `com.mojang.blaze3d.platform.Lighting#updateLevel` now takes in a `DimensionType$CardinalLightType` instead of a boolean for whether the level is the nether or not +- `com.mojang.blaze3d.systems.GpuDevice#createTexture` now has an overload that takes in a supplied label instead of the raw string +- `com.mojang.blaze3d.vertex.VertexConsumer` + - `addVertex`, `addVertexWith2DPose` now take in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) + - `putBulkData` no longer takes the final `boolean` to read the buffer data to determine the initial color +- `com.mojang.math` + - `OctahedralGroup` + - `fromXYAngles` -> `Quadrant#fromXYAngles` + - `permute` -> `SymmetricGroup3#permuteAxis` + - `SymmetricGroup3` + - `permutation` -> `permute` + - `permuteVector` -> `OctahedralGroup#rotate` + - `Transformation` now takes in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) + - This also applies to the argument getter methods +- `net.minecraft` + - `FileUtil#isValidStrictPathSegment` -> `containsAllowedCharactersOnly`, now private + - Replaced by `isValidPathSegment` + - `Minecraft` + - `disconnectWithProgressScreen` now takes in a `boolean` of whether to stop the sound engine + - `disconnect` now takes in a `boolean` of whether to stop the sound engine + - `SharedConstants` + - `DEBUG_WATER` -> `DebugScreenEntries#VISUALIZE_WATER_LEVELS`, not one-to-one + - `DEBUG_HEIGHTMAP` -> `DebugScreenEntries#VISUALIZE_HEIGHTMAP`, not one-to-one + - `DEBUG_COLLISION` -> `DebugScreenEntries#VISUALIZE_COLLISION_BOXES`, not one-to-one + - `DEBUG_SUPPORT_BLOCKS` -> `DebugScreenEntries#VISUALIZE_ENTITY_SUPPORTING_BLOCKS`, not one-to-one + - `DEBUG_LIGHT` -> `DebugScreenEntries#VISUALIZE_BLOCK_LIGHT_LEVELS`, `VISUALIZE_SKY_LIGHT_LEVELS`; not one-to-one + - `DEBUG_SKY_LIGHT_SECTIONS` -> `DebugScreenEntries#VISUALIZE_SKY_LIGHT_SECTIONS`, not one-to-one + - `DEBUG_SOLID_FACE` -> `DebugScreenEntries#VISUALIZE_SOLID_FACES`, not one-to-one + - `DEBUG_CHUNKS` -> `DebugScreenEntries#VISUALIZE_CHUNKS_ON_SERVER`, not one-to-one +- `net.minecraft.advancements.criterion.EntityFlagsPredicate` now takes in optional booleans for if the entity is in water or fall flying + - The associated `$Builder` methods have also been added +- `net.minecraft.client` + - `Camera` + - `setup` now takes in a `Level` instead of a `BlockGetter` + - `get*` has been replaced by their record alternatives (e.g. `getEntity` -> `entity`) + - `Vector3f` return values are replaced with `Vector3fc` + - `GraphicsStatus` -> `GraphicsPreset`, not one-to-one + - `KeyMapping` now has an overload that takes in the sort order + - `MouseHandler#lastClickTime` -> `lastClick`, now private, not one-to-one + - `OptionInstance$OptionInstanceSliderButton` now implements `ResettableOptionWidget` + - `Options` + - `graphicsMode` -> `graphicsPreset`, `applyGraphicsPreset` + - `showNowPlayingToast` -> `musicToast`, not one-to-one +- `net.minecraft.client.data.models` + - `EquipmentAssetProvider#humanoidAndHorse` -> `humanoidAndMountArmor` + - `ItemModelGenerators` + - `getSpans` -> `getSideFaces`, not one-to-one + - `$SpanFacing` -> `$SideDirection`, not one-to-one + - `$Span` -> `$SideFace`, not one-to-one + - `ItemModelOutput#accept` now has an overload that takes in the `ClientItem$Properties` +- `net.minecraft.client.gui` + - `Font#NO_SHADOW` -> `Style#NO_SHADOW` + - `GuiGraphics` + - `textHighlight` now takes in a `boolean` of whether to render the background rectangle + - `submitOutline` -> `renderOutline` +- `net.minecraft.client.gui.components` + - `AbstractButton#handleCursor` -> `handleCursor`, now protected + - `AbstractSliderButton` + - `HANDLE_WIDTH` is now protected + - `canChangeValue`, `setValue` are now protected + - `AbstractWidget#message` is now protected + - `CycleButton` now implements `ResettableOptionWidget` + - `builder` now has an overload to take in a supplied default value + - `booleanBuilder` now takes in a boolean to choose which component to default to + - `$Builder` now takes in a supplied default value + - `displayOnlyValue(boolean)` -> `displayState`, not one-to-one + - `FocusableTextWidget` constructor is now package private, use `builder` instead + - `OptionsList` now passes in an `$AbstractEntry` to the generic rather than an `$Entry` + - `addSmall` now has an overload that takes in an `OptionInstance` + - `$Entry` now extends `$AbstractEntry` + - `$OptionEntry` class is removed + - `big` -> `$Entry#big` + - `small` -> `$Entry#small` + - `StringWidget#clipText` is now public static, taking in the `Font` +- `net.minecraft.client.gui.components.debug` + - `DebugScreenEntryList` + - `toggleF3Visible` -> `toggleDebugOverlay` + - `setF3Visible` -> `setOverlayVisible` + - `isF3Visible` -> `isOverlayVisible` + - `DebugScreenEntryStatus#IN_F3` -> `IN_OVERLAY` +- `net.minecraft.client.gui.components.debugchart.AbstractDebugChart#COLOR_GREY` -> `CommonColors#TEXT_GRAY` +- `net.minecraft.client.gui.components.toasts.ToastManager` + - `createNowPlayingToast` -> `initializeMusicToast`, now private, not one-to-one + - `removeNowPlayingToast` -> `setMusicToastDisplayState`, not one-to-one +- `net.minecraft.client.gui.navigation.ScreenRectangle#transform*` methods now take in the interface, 'read only' variants of its arguments (e.g., `Vector3f` -> `Vector3fc`) +- `net.minecraft.client.gui.render.state.*` now take in the interface, 'read only' variants for its `pose` (e.g., `Vector3f` -> `Vector3fc`) + - `GuiTextRenderState` now takes in whether to draw the empty space around each glyph +- `net.minecraft.client.gui.screens` + - `DeathScreen` now takes in the `LocalPlayer` + - `Screen` now has an overload that takes in the `Minecraft` instance and `Font` to use + - `minecraft` is now final + - `font` is now final + - `init(Minecraft, int, int)` -> `init(int, int)` + - `resize(Minecraft, int, int)` -> `init(int, int)` + - `handleComponentClicked` -> `ChatScreen#handleComponentClicked`, now private + - `handleClickEvent` has been moved to their associated classes instead of one super interface (e.g., `BookViewScreen#handleClickEvent`) +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementsScreen#renderWindow` now takes in the mouse XY `int`s + - `AdvancementTab#drawTab` now takes in the mouse XY `int`s +- `net.minecraft.client.gui.screens.debug.DebugOptionsScreen$OptionList` is now public +- `net.minecraft.client.gui.screens.inventory` + - `AbstractCommandBlockEditScreen#populateAndSendPacket` no longer takes in the `BaseCommandBlock` + - `AbstractContainerScreen#renderSlots`, `renderSlot` now take in the mouse XY `int`s + - `CreativeModeInventoryScreen#renderTabButton` now takes in the mouse XY `int`s + - `EffectsInInventory#renderEffects` -> `render` + - `HorseInventoryScreen` now extends `AbstractMountInventoryScreen` + - `MinecartCommandBlockEditScreen` now takes in a `MinecartCommandBlock` instead of a `BaseCommandBlock` +- `net.minecraft.client.gui.screens.multiplayer.ServerSelectionList$OnlineServerEntry` now implements `SelectableEntry` +- `net.minecraft.client.gui.screens.packs.TransferableSelectionList$PackEntry` now implements `SelectableEntry` +- `net.minecraft.client.gui.screens.recipebook` + - `RecipeBookComponent#initFilterButtonTextures` -> `getFilterButtonTextures`, not one-to-one + - `RecipeBookTabButton` now implements `ImageButton` instead of `StateSwitchingButton` + - The constructor now takes in the XY position along with the `Button$OnPress` consumer +- `net.minecraft.client.gui.screens.worldselection.WorldSelectionList$WorldListEntry` is no longer static, now implements `SelectableEntry` +- `net.minecraft.client.model` + - `AnimationUtils` + - `animateCrossbowCharge` now takes in a `float` instead of an `int` + - `animateZombieArms` now takes in an `UndeadRenderState` instead of two `float`s + - `HumanoidModel` + - `setupAttackAnimation` no longer takes in a `float` + - `getArm` is now public from protected +- `net.minecraft.client.model.geom.ModelPart#getExtentsForGui` now takes in a `Consumer` instead of a set +- `net.minecraft.client.model.geom.builders.UVPair` is now a record +- `net.minecraft.client.multiplayer` + - `MultiPlayerGameMode#isAlwaysFlying` -> `isSpectator` + - `ServerStatusPinger#pingServer` now takes in an `EventLoopGroupHolder` +- `net.minecraft.client.renderer` + - `CloudRenderer#render` now takes in the game time `long` + - `DynamicUniforms#writeTransform`, `$Transform` no longer take in the line width `float` + - `GameRenderer#setPanoramicMode` -> `setPanoramicScreenshotParameters`, not one-to-one + - `GlobalSettingsUniform#update` now takes in the `Camera` and whether to use Rotated Grid Super Sampling (RGSS) + - `ItemBlockRenderTypes#setFancy` -> `setCutoutLeaves` + - `ItemInHandRenderer` no longer takes in the `ItemRenderer` + - `LevelRenderer#isSectionCompiled` -> `isSectionCompiledAndVisible` + - `RenderPipelines` + - `LINE_STRIP` -> `LINES` or `LINES_TRANSLUCENT`, not one-to-one + - `DEBUG_LINE_STRIP` -> `DEBUG_POINTS`, not one-to-one + - `RenderType` + - `LINE_STRIP`, `lineStrip` -> `RenderTypes#LINES`, `LINES_TRANSLUCENT`, `linesTranslucent`; not one-to-one + - `debugLineStrip` -> `debugPoint`, not one-to-one + - `SkyRenderer` now takes in the `TextureManager` and `AtlasManager` + - `extractRenderState` now takes in a `Camera` instead of the camera position + - `renderSunMoonAndStars` now takes in a `MoonPhase` instead of an `int` + - `UniformValue` + - `$IVec3Uniform` now takes in a `Vector3ic` instead of a `Vector3i` + - `$Vec2Uniform` now takes in a `Vector2fc` instead of a `Vector2f` + - `$Vec3Uniform` now takes in a `Vector3fc` instead of a `Vector3f` + - `$Vec4Uniform` now takes in a `Vector4fc` instead of a `Vector4f` + - `WeatherEffectRenderer#tickRainParticles` now takes in an `int` for the weather radius + - `WorldBorderRenderer#extract` now takes in a `float` for the partial tick +- `net.minecraft.client.renderer.blockentity` + - `BannerRenderer#getExtents` now takes in a `Consumer` instead of a set + - `BedRenderer#getExtents` now takes in a `Consumer` instead of a set + - `BellRenderer#BELL_RESOURCE_LOCATION` -> `BELL_TEXTURE` + - `DecoratedPotRenderer#getExtents` now takes in a `Consumer` instead of a set + - `EnchantTableRenderer#BOOK_LOCATION` -> `BOOK_TEXTURE` + - `ShulkerBoxRenderer#getExtents` now takes in a `Consumer` instead of a set + - `TestInstanceRenderer` no longer takes in the `BlockEntityRendererProvider$Context` +- `net.minecraft.client.renderer.blockentity.state.BlockEntityWithBoundingBoxRenderState$InvisibleBlockType$STRUCUTRE_VOID` -> `STRUCTURE_VOID` +- `net.minecraft.client.renderer.chunk.ChunkSectionLayer#textureView` -> `texture`, not one-to-one +- `net.minecraft.client.renderer.entity.EntityRenderDispatcher` no longer takes in the `ItemRenderer` +- `net.minecraft.client.renderer.entity.layers` + - `CarriedBLockLayer` no longer takes in the `BlockRenderDispatcher` + - `IronGolemFlowerLayer` no longer takes in the `BlockRenderDispatcher` + - `ItemInHandLayer#submitArmWithItem` now takes in the held `ItemStack` +- `net.minecraft.client.renderer.entity.state` + - `ArmedEntityRenderState` + - `*HandItem` -> `*HandItemState`, `*HandItemStack`; not one-to-one + - `extractArmedRenderState` now takes in the partial tick `float` + - `HorseRenderState#bodyArmorItem` -> `EquineRenderState#bodyArmorItem` + - `HumanoidRenderState` + - `attackTime` -> `ArmedEntityRenderState#attackTime` + - `ticksUsingItem` is now a float + - `IllagerRenderState` now extends `UndeadRenderState` + - `ticksUsingItem` is now a float + - `ZombieRenderState` now extends `UndeadRenderState` + - `ZombifiedPiglinRenderState` now extends `UndeadRenderState` +- `net.minecraft.client.renderer.fog.FogRenderer#setupFog` no longer takes in the `boolean` +- `net.minecraft.client.renderer.fog.environment` + - `AtmosphericFogEnvironment` now extends `FogEnvironment` instead of `AirBasedFogEnvironment` + - `FogEnvironment#setupFog` no longer takes in the `Entity` and `BlockPos`, instead the `Camera` +- `net.minecraft.client.renderer.item.ClientItem$Properties` now takes in a float for changing the scale of the swap animation +- `net.minecraft.client.renderer.special.SpecialModelRenderer#getExtents` now takes in a `Consumer` instead of a set +- `net.minecraft.client.renderer.state.SkyRenderState#moonPhase` is now a `MoonPhase` instead of an `int` +- `net.minecraft.client.resources.SplashManager` + - `prepare` now returns a list of `Component`s instead of strings + - `apply` now takes in a list of `Component`s instead of strings +- `net.minecraft.client.resources.model.BlockModelRotation` is now a class + - `by` -> `get`, not one-to-one +- `net.minecraft.client.resources.sounds` + - `RidingHappyGhastSoundInstance` -> `RidingEntitySoundInstance`, not one-to-one + - `RidingMinecartSoundInstance` now extends `RidingEntitySoundInstance` instead of `AbstractTickableSoundInstance` + - The constructor now takes in the `SoundEvent`, volume min and max, and amplifier + - `SimpleSoundInstance#forMusic` no longer takes in the volume +- `net.minecraft.client.sounds` + - `SoundEngine` no longer takes in the `MusicManager` + - `updateCategoryVolume` -> `refreshCategoryVolume` + - `setVolume` -> `updateCategoryVolume`, not one-to-one + - `SoundManager` no longer takes in the `MusicManager` + - `updateSourceVolume` -> `refreshCategoryVolume` + - `setVolume` -> `updateCategoryVolume`, not one-to-one +- `net.minecraft.gametest.framework.GameTestHelper` + - `spawn` now has an overload that takes in the `EntitySpawnReason` or three `int`s for the position + - `assetTrue`, `assetFalse`, `assertValueEqual` now has an overload that takes in a `String` instead of a `Component` + - `assertEntityData` now has an overload that takes in the `AABB` bounding box + - `getRelativeBounds` is now public + - `assertEntityPosition` -> `assertEntityPresent`, not one-to-one +- `net.minecraft.nbt` + - `CompoundTag#remove` now returns the removed tag + - `NbtUtils#getDataVersion` now has an overload that only takes in the `CompoundTag` +- `net.minecraft.network` + - `Connection` + - `NETWORK_WORKER_GROUP` -> `EventLoopGroupHolder#NIO`, not one-to-one + - `NETWORK_EPOLL_WORKER_GROUP` -> `EventLoopGroupHolder#EPOLL`, not one-to-one + - `LOCAL_WORKER_GROUP` -> `EventLoopGroupHolder#LOCAL`, not one-to-one + - `connectToServer`, `connect` now take in an `EventLoopGroupHolder` instead of a `boolean` + - `FriendlyByteBuf` + - `writeVector3f` now takes in a `Vector3fc` instead of a `Vector3f` + - `writeQuaternion` now takes in a `Quaternionfc` instead of a `Quaternionf` + - `DEFAULT_NBT_QUOTA` -> `NbtAccounter#DEFAULT_NBT_QUOTA` +- `net.minecraft.network.codec` + - `ByteBufCodecs` + - `VECTOR3F` now uses a `Vector3fc` instead of a `Vector3f` + - `QUATERNIONF` now uses a `Quaternionfc` instead of a `Quaternionf` + - `StreamCodec#composite` now has ten and twelve parameter variants +- `net.minecraft.network.chat` + - `ComponentUtils#mergeStyles` now has an overload that takes in and returns a `Component` + - `MutableComponent` is now final +- `net.minecraft.network.protocol.game` + - `ClientboundHorseScreenOpenPacket` -> `ClientboundMountScreenOpenPacket` + - `ClientGamePacketListener#handleHorseScreenOpen` -> `handleMountScreenOpen` + - `GamePacketTypes#CLIENTBOUND_HORSE_SCREEN_OPEN` -> `CLIENTBOUND_MOUNT_SCREEN_OPEN` +- `net.minecraft.network.numbers` + - `FixedFormat` is now a record + - `StyledFormat` is now a record +- `net.minecraft.network.syncher.EntityDataSerializers` + - `VECTOR3` now uses a `Vector3fc` instead of a `Vector3f` + - `QUATERNION` now uses a `Quaternionfc` instead of a `Quaternionf` +- `net.minecraft.server` + - `MinecraftServer` + - `isAllowedToEnterPortal` -> `ServerLevel#isAllowedToEnterPortal` + - `isSpawningMonsters` -> `ServerLevel#isSpawningMonsters` + - `isPvpAllowed` -> `ServerLevel#isPvpAllowed` + - `isCommandBlockEnabled` -> `ServerLevel#isCommandBlockEnabled` + - `isSpawnerBlockEnabled` -> `ServerLevel#isSpawnerBlockEnabled` + - `getGameRules` -> `ServerLevel#getGameRules` + - `isEpollEnabled` -> `useNativeTransport` + - `ServerScoreboard` no longer implements its own saved data type, instead using the packed `ScoreboardSaveData` + - `TYPE` -> `ScoreboardSavedData#TYPE` +- `net.minecraft.server.jsonrpc` + - `IncomingRpcMethod` now takes in two generics for the parameters to the request and the result response + - `$Builder` now has constructors for parameterless and parameter functions, replacing `$Factory` + - `response`, `param` now take in their `Schema`s + - `OutgoingRpcMethod$Factory` now takes in the generic params and result +- `net.minecraft.server.jsonrpc.api` + - `MethodInfo`, `$Named` now takes in two generics for the parameters to the request and the result response + - `PARAMS_CODEC` -> `paramsTypedCodec`, now private, not one-to-one + - `MAP_CODEC` -> `typedCodec`, now package-private, not one-to-one + - `ParamInfo` now takes in a generic for the parameter + - `CODEC` -> `typedCodec`, not one-to-one + - `ResultInfo` now takes in a generic for the result response + - `CODEC` -> `typedCodec`, not one-to-one + - `Schema` now takes in a generic for the type it represents + - The constructor now takes in a list of types instead of an optional, an non-optional property map, non-oprional enuma values, and the codec to serialize the type + - `ofTypes` now has an overload that takes in a list of types + - `SchemaComponent` now takes in a generic for the type it represents +- `net.minecraft.server.jsonrpc.security.AuthenticationHandler` now implements `ChannelDuplexHandler` instead of `ChannelInboundHandlerAdapter` + - The constructor now takes in a string set of allowed origins + - `$SecurityCheckResult#allowed` now has an overload that specifies whether the token was sent through the websocket protocol +- `net.minecraft.server.level` + - `ChunkMap` now extends `SimpleRegionStorage` instead of `ChunkStorage` + - `ServerLevel#drop` no longer returns a `boolean` +- `net.minecraft.server.network.ServerConnectionListener` + - `SERVER_EVENT_GROUP` -> `EventLoopGroupHolder#NIO`, not one-to-one + - `SERVER_EPOLL_EVENT_GROUP` -> `EventLoopGroupHolder#EPOLL`, not one-to-one +- `net.minecraft.stats.ServerStatsCounter` now takes in a `Path` instead of a `File` + - `parseLocal` -> `parse`, not one-to-one + - `toJson` now returns a `JsonElement` instead of a `String` +- `net.minecraft.util` + - `ARGB#lerp` -> `srgbLerp` + - `ExtraCodecs` now use the interface, 'read only' variants for its generic (e.g., `Vector3f` -> `Vector3fc`) + - `Mth` + - `easeInOutSine` -> `Ease#inOutSine` + - `sin`, `cos` now takes in a `double` instead of a `float` + - `absMax` now has overloads that uses `int`s or `float`s + - `TriState` now implements `StringRepresentable` +- `net.minecraft.util.profiling.jfr.Percentiles#evaluate` now has an overload that takes in an `int[]` +- `net.minecraft.util.profiling.jfr.parse.JfrStatsResult` now takes in an FPS stat + - `tickTimes` -> `serverTickTimes` +- `net.minecraft.util.profiling.jfr.stats.TimedStatSummary#summary` now returns an optional of the `TimeStatSummary` +- `net.minecraft.util.worldupdate.WorldUpgrader` + - `$AbstractUpgrader` no longer takes in a generic + - `createStorage` now returns a `SimpleRegionStorage` instead of the generic + - `tryProcessOnePosition` now takes in a `SimpleRegionStorage` instead of the generic + - `$DimensionToUpgrade` no longer takes in a generic, instead using `SimpleRegionStorage` +- `net.minecraft.world.RandomSequences` no longer takes in the world seed + - `codec` -> `CODEC` + - `get`, `reset` now takes in the world seed +- `net.minecraft.world.entity` + - `Avatar#DATA_PLAYER_MAIN_HAND` now uses a `HumanoidArm` generic instead of a byte + - `Entity#hasImpulse` -> `needsSync` + - `EntityType#loadEntityRecursive` now takes in an `EntityProcessor` instead of a `Function` + - `LivingEntity#invulnerableDuration` -> `INVULNERABLE_DURATION` + - `Mob#playAttackSound` -> `LivingEntity#playAttackSound` + - `NeutralMob` + - `TAG_ANGER_TIME` -> `TAG_ANGER_END_TIME`, not one-to-one + - `getRemainingPersistentAngerTime` -> `getPersistentAngerEndTime`, not one-to-one + - `setRemainingPersistentAngerTime` -> `setTimeToRemainAngry`, `setPersistentAngerEndTime`; second is not one-to-one + - `getPersistentAngerTarget`, `setPersistentAngerTarget` now deal with `EntityReference`s +- `net.minecraft.world.entity.ai.sensing.SensorType#*_TEMPTATIONS` -> `FOOD_TEMPTATIONS`, not one-to-one +- `net.minecraft.world.entity.ai.util` + - `GoalUtils` + - `mobRestricted` now takes in a `double` instead of an `int` + - `isRestricted` now has an overload that takes in a `Vec3` + - `LandRandomPos` + - `getPosAway` now has an overload that takes in an additional `double` for the start/end radians + - `generateRandomPosTowardDirection` now takes in a `double` instead of an `int` + - `RandomPos` + - `generateRandomDirectionWithinRadians` now takes in `double`s for the start/end radians + - `generateRandomPosTowardDirection` now takes in a `double` instead of an `int` +- `net.minecraft.world.entity.animal.equine.AbstractHorse#getInventorySize` -> `AbstractMountInventoryMenu#getInventorySize` +- `net.minecraft.world.entity.monster.Monster#checkMonsterSpawnRules` now expanded its type generic to extends `Mob` instead of `Monster` +- `net.minecraft.world.entity.monster.skeleton.Bogged#*_ATTACK_INTERVAL` -> `AbstractSkeleton#INCREASED_*_ATTACK_INTERVAL` +- `net.minecraft.world.entity.monster.zombie` + - `Husk#checkHuskSpawnRules` -> `Monster#checkSurfaceMonsterSpawnRules`, not one-to-one + - `Zombie` + - `doUnderWaterConversion` now takes in the `ServerLevel` + - `convertToZombieType` now takes in the `ServerLevel` +- `net.minecraft.world.entity.npc.villager` + - `AbstractVillager` + - `updateTrades` now takes in the `ServerLevel` + - `addOffersFromItemListings` now takes in the `ServerLevel` + - `Villager#shouldRestock` now takes in the `ServerLevel` + - `VillagerTrades$ItemListing#getOffer` now takes in the `ServerLevel` +- `net.minecraft.world.entity.player.Player` + - `openMinecartCommandBlock` now takes in a `MinecartCommandBlock` instead of a `BaseCommandBlock` + - `sweepAttack` -> `doSweepAttack`, now private, not one-to-one + - `respawn` -> `LocalPlayer#respawn` + - `CLIENT_LOADED_TIMEOUT_TIME` -> `ServerGamePacketListenerImpl#CLIENT_LOADED_TIMEOUT_TIME` + - `clientLoadedTimeoutTimer`, `tickClientLoadTimeout` -> `ServerGamePacketListenerImpl#tickClientLoadTimeout` + - `hasClientLoaded` -> `ServerGamePacketListenerImpl#hasClientLoaded` + - `setClientLoaded` -> `ServerGamePacketListenerImpl#markClientLoaded`, `markClientUnloadedAfterDeath`, `restartClientLoadTimerAfterRespawn`; not one-to-one +- `net.minecraft.world.entity.projectile.Projectile` constructor is now `protected` instead of package private +- `net.minecraft.world.entity.vehicle.VehicleEntity#shouldSourceDestroy` is now `protected` instead of package private +- `net.minecraft.world.entity.vehicle.minecart` + - `AbstractMinecart` now takes in the `ServerLevel` + - `MinecartCommandBlock$MinecartCommandBase` is now package-private +- `net.minecraft.world.inventory.HorseInventoryMenu` now extends `AbstractMountInventoryMenu` +- `net.minecraft.world.item.component.ItemAttributeModifiers#compute` now takes in the `Attribute` holder +- `net.minecraft.world.item.enchantment.effects.PlaySoundEffect` now takes in a list of sound events instead of a single +- `net.minecraft.world.level` + - `BaseCommandBlock` + - `performCommand` now takes in a `ServerLevel` instead of a `Level` + - `onUpdated` now takes in a `ServerLevel` + - `createCommandSourceStack` now takes in a `ServerLevel` + - `$CloseableCommandBlockSource` now takes in a `ServerLevel`, with its constructor protected + - `CollisionGetter#noBlockCollision` now has an overload that takes in an additional `boolean` of whether to check liquid collisions. + - `Level#getGameTime` -> `LevelAccessor#getGameTime` + - `LevelAccessor#getCurrentDifficultyAt` -> `ServerLevelAccessor#getCurrentDifficultyAt` + - `LevelTimeAccess#getMoonPhase` now returns a `MoonPhase` instead of an `int` +- `net.minecraft.world.level.biome` + - `AmbientAdditionsSettings` is now a record + - `AmbientMoodSettings` is now a record + - `AmbientParticleSettings` is now a record +- `net.minecraft.world.level.block.entity.BaseContainerBlockEntity#canUnlock` -> `sendChestLockedNotifications`, not one-to-one +- `net.minecraft.world.level.border` + - `BorderChangeListener#onLerpSize` now takes in an additional `long` for the game time + - `WorldBorder` can now take in the `WorldBorder$Settings` + - `getMin*`, `getMax*` now have an overload that takes in the partial tick `float` + - `lerpSizeBetween` now takes in an additional `long` for the game time + - `applySettings` -> `applyInitialSettings`, not one-to-one + - The original behavior can be replicated by passing the settings into the constructor + - `$BorderExtent#getMin*`, `getMax*` now takes in the partial tick `float` +- `net.minecraft.world.level.chunk.storage` + - `RecreatingSimpleRegionStorage` now takes in a supplied `LegacyTagFixer` + - `SimpleRegionStorage` now takes in a supplied `LegacyTagFixer` + - `write` now has an overload that takes in a supplied `CompoundTag` + - `upgradeChunkTag` now has an overload that takes in a a nullable tag comntext +- `net.minecraft.world.level.dimension.DimensionType` + - `MOON_PHASES` is now an array of `MoonPhase`s and private + - `moonPhase` now returns a `MoonPhase` instead of an `int` +- `net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler` now implements `LegacyTagFixer` + - The constructor now takes in the `DataFixer` + - `removeIndex` -> `LegacyTagFixer#markChunkDone` + - `updateFromLegacy` now private + - `getLegacyStructureHandler` now takes in the `DataFixer`, a supplied `DimensionDataStorage`, and returns a supplied `LegacyTagFixer` +- `net.minecraft.world.level.levelgen.structure.structures.NetherFortressPieces$StartPiece` fields are now package-private +- `net.minecraft.world.level.saveddata.SavedDataType` no longer takes in a `SavedData$Context`, removing the function argument constructor +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` no longer takes in a `SavedData$Context` + - `FileNameDateFormatter#create` -> `FORMATTER` + - `LevelStorageSource` + - `UNCOMPRESSED_NBT_QUOTA` -> `NbtAccounter#UNCOMPRESSED_NBT_QUOTA`, now `public` + - `$LevelDirectory#corruptedDataFile`, `rawDataFile` now take in a `ZonedDateTime` instead of a `LocalDateTime` +- `net.minecraft.world.level.storage.loot.LootContext` + - `$BlockEntityTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` + - `$EntityTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` + - `$ItemStackTarget` now implements `LootContextArg$SimpleGetter` + - `getParam` -> `contextParam` +- `net.minecraft.world.level.storage.loot.functions` + - `CopyComponentsFunction` + - `$*Source` -> `$DirectSource`, not one-to-one + - `$Source` -> `LootContextArg$Getter`, not one-to-one + - `CopyNameFunction#copyName` now takes in a `LootContextArg` instead of a `$Source` + - `$Source` -> `LootContextArg`, not one-to-one + - `FilteredFunction` now takes in an `Optional` pass and fail `LootItemFunction` instead of just a modifier + - The function can now be builder through a `$Builder` via `filtered` +- `net.minecraft.world.phys.Vec3` now takes in a `Vector3fc` instead of a `Vector3f` +- `net.minecraft.world.phys.shapes.Shapes#rotateHorizontal`, `rotateAll`, `rotateAttachFace` now have overloads to take in the `OctahedralGroup` +- `net.minecraft.world.scores` + - `Score` now has a public constructor for the `$Packed` value + - `MAP_CODEC` -> `Score$Packed` ands its `$Packed#MAP_CODEC` + - `Scoreboard$PackedScore#score` now takes in a `Score$Packed` instead of a `Score` + - `ScoreboardSavedData` now takes in a `ScoreboardSaveData$Packed` instead of a `Scoreboard` + - `FILE_ID` merged into type + - `loadFrom` -> `ServerScoreboard#load` + - `pack` -> `ServerScoreboard#store`, now private, not one-to-one + +#### List of Removals + +- `com.mojang.blaze3d.vertex.VertexFormat$Mode#LINE_STRIP` +- `net.minecraft.Util#lastOf` +- `net.minecraft.client` + - `Minecraft#useFancyGraphics` + - `GuiMessage#icon` + - `StringSplitter` + - `formattedIndexByWidth`, `componentStyleAtWidth` + - `splitLines(FormattedText, int, Style, FormattedText)` +- `net.minecraft.client.gui.Font#wordWrapHeight(String, int)` +- `net.minecraft.client.gui.components` + - `CycleButton` + - `onOffBuilder()` + - `$Builder#withInitialValue` + - `StateSwitchingButton` +- `net.minecraft.client.gui.screens.inventory` + - `EffectsInInventory#renderTooltip` + - `InventoryScreen#renderEntityInInventory` +- `net.minecraft.client.gui.screens.packs.PackSelectionScreen#clearSelected` +- `net.minecraft.client.player.LocalPlayer#USING_ITEM_SPEED_FACTOR` +- `net.minecraft.client.renderer` + - `ItemModelGenerator#createOrExpandSpan` + - `GpuWarnlistManager#dismissWarningAndSkipFabulous`, `isSkippingFabulous` + - `RenderPipelines` + - `DEBUG_STRUCTURE_QUADS`, `DEBUG_SECTION_QUADS` + - `SkyRenderer#initTextures` +- `net.minecraft.client.renderer.fog.environment` + - `AirBasedFogEnvironment` + - `DimensionOrBossFogEnvironment` + - `FogEnvironment#onNotApplicable` +- `net.minecraft.client.resources.model.BlockModelRotation#actualRotation` +- `net.minecraft.gametest.framework.GameTestHelper#setNight`, `setDayTime` +- `net.minecraft.network.FriendlyByteBuf#readDate`, `writeDate` +- `net.minecraft.server` + - `MinecraftServer#hasGui` + - `ServerScoreboard#createData`, `addDirtyListener` +- `net.minecraft.server.jsonrpc.IncomingRpcMethod$Factory` +- `net.minecraft.server.jsonrpc.methods.IllegalMethodDefinitionException` +- `net.minecraft.server.jsonrpc.security.AuthenticationHandler#AUTH_HEADER` +- `net.minecraft.util` + - `DebugBuffer` + - `LazyLoadedValue` +- `net.minecraft.util.thread.NamedThreadFactory` +- `net.minecraft.world.entity.Mob#isSunBurnTick` +- `net.minecraft.world.entity.animal.armadillo.ArmadilloAi#getTemptations` +- `net.minecraft.world.entity.animal.axolotl.AxolotlAi#getTemptations` +- `net.minecraft.world.entity.animal.camel.CamelAi#getTemptations` +- `net.minecraft.world.entity.animal.equine.ZombieHorse#checkZombieHorseSpawnRules` + - Use `Monster#checkMonsterSpawnRules` instead +- `net.minecraft.world.entity.animal.goat.GoatAi#getTemptations` +- `net.minecraft.world.entity.animal.sniffer.SnifferAi#getTemptations` +- `net.minecraft.world.entity.player.Player#playNotifySound` +- `net.minecraft.world.entity.raid.Raid#TICKS_PER_DAY` +- `net.minecraft.world.level` + - `BaseCommandBlock` + - `getLevel` + - `getUsedBy`, `getPosition` + - `Level#TICKS_PER_DAY` +- `net.minecraft.world.level.border.WorldBorder$Settings#toWorldBorder` + - Use the `WorldBorder` constructor instead +- `net.minecraft.world.level.chunk.storage` + - `ChunkStorage` + - `RecreatingChunkStorage` +- `net.minecraft.world.level.saveddata.SavedData$Context` +- `net.minecraft.world.phys.Vec3#fromRGB24` + +### Step 10: 1.21.11 -> 26.1 + +## Minecraft 1.21.11 -> 26.1 Mod Migration Primer + +This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.11 to 26.1. This does not look at any specific mod loader, just the changes to the vanilla classes. + +This primer is licensed under the [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/), 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: + +- @Shnupbups for some grammatical fixes +- @cassiancc for information about Java 25 IDE support +- @boq for information regarding IME support +- @lolothepro for a typo + +### 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](https://misode.github.io/versions/?id=26.1&tab=changelog). + +### Java 25 and Deobfuscation + +26.1 introduces two new changes into the general pipeline. + +First, the Java Development Kit has been upgraded from 21 to 25. Vanilla makes use of these new features, such as [JEP 447](https://openjdk.org/jeps/447), which allows statements before `super` within constructors. For users within the modding scene, please make sure to update accordingly, or take advantage of your IDE or build tool features. Microsoft's OpenJDK can be found [here](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-25). + +You may need to update your IDE to support Java 25. If using Eclipse, you will need at least either 2025-12, or 2025-09 with the Java 25 Support marketplace plugin. If using IntelliJ IDEA, you will need at least 2025.2. + +Vanilla has also returned to being deobfuscated, meaning that all value types now have the official names provided by Mojang. There are still some things that are not captured due to the Java compilation process, such as inlining primitive and string constants, but the majority are now provided. This will only have a change for users or mod loaders who used a different value type mapping set from the official mappings. + +### Loot Type Unrolling + +Loot pool entries, item functions, item conditions, nbt providers, number providers, score providers, int providers, and float providers no longer use a wrapping object type to act as the registered instance. Now, the registries directly take in the `MapCodec` used for the serialization and deserialization process. As such, the `*Type` classes or records that held the codec have been removed. Additionally, `getType` is now renamed to `codec`, taking in the registered `MapCodec`. + +```java +// The following is an example with LootItemFunctions, but can roughly apply to the other instances as well + +public record NoopItemFunction() implements LootItemFunction { + public static final NoopItemFunction INSTANCE = new NoopItemFunction(); + // The map codec used as the registry object + public static final MapCodec MAP_CODEC = MapCodec.unit(INSTANCE); + + // Replaces getType + @Override + public MapCodec codec() { + // Return the registry object + return MAP_CODEC; + } +} + +// Register the map codec to the appropriate registry +Registry.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, Identifier.fromNamespaceAndPath("examplemod", "noop"), NoopItemFunction.MAP_CODEC); +``` + +- `net.minecraft.core.registries.BuiltInRegistries`, `Registries` + - `LOOT_POOL_ENTRY_TYPE` now holds a `LootPoolEntryContainer` map codec instead of a `LootPoolEntryType` + - `LOOT_FUNCTION_TYPE` now holds a `LootItemFunction` map codec instead of a `LootItemFunctionType` + - `LOOT_CONDITION_TYPE` now holds a `LootItemCondition` map codec instead of a `LootItemConditionType` + - `LOOT_NUMBER_PROVIDER_TYPE` now holds a `NumberProvider` map codec instead of a `LootNumberProviderType` + - `LOOT_NBT_PROVIDER_TYPE` now holds a `NbtProvider` map codec instead of a `LootNbtProviderType` + - `LOOT_SCORE_PROVIDER_TYPE` now holds a `ScoreboardNameProvider` map codec instead of a `LootScoreProviderType` + - `FLOAT_PROVIDER_TYPE` now holds a `FloatProvider` map codec instead of a `FloatProviderType` + - `INT_PROVIDER_TYPE` now holds a `IntProvider` map codec instead of a `IntProviderType` +- `net.minecraft.util.valueproviders` now renames `CODEC` fields to `MAP_CODEC` + - `FloatProvider` subtypes are now all records + - `IntProvider` subtypes, except for `WeightedListInt`, are now all records + - `FloatProvider` is now an `interface` from a `class` + - `CODEC` -> `FloatProviders#CODEC` + - `codec` -> `FloatProviders#codec` + - `getType` -> `codec`, not one-to-one + - `getMinValue` -> `min` + - `getMaxValue` -> `max` + - `FloatProviders` - All vanilla float providers to register. + - `FloatProviderType` interface is removed + - Singleton fields have all been removed, use map codecs in each class instead + - `codec` -> `FloatProvider#codec` + - `IntProvider` is now an `interface` from a `class` + - `CODEC` -> `IntProviders#CODEC` + - `NON_NEGATIVE_CODEC` -> `IntProviders#NON_NEGATIVE_CODEC` + - `POSITIVE_CODEC` -> `IntProviders#POSITIVE_CODEC` + - `codec` -> `IntProviders#codec` + - `validateCodec` -> `IntProviders#validateCodec` + - `getMinValue` -> `minInclusive` + - `getMaxValue` -> `maxInclusive` + - `getType` -> `codec`, not one-to-one + - `IntProviders` - All vanilla int providers to register. + - `IntProviderType` interface is removed + - Singleton fields have all been removed, use map codecs in each class instead + - `codec` -> `IntProvider#codec` +- `net.minecraft.world.level.storage.loot.entries` now renames `CODEC` fields to `MAP_CODEC` + - `LootPoolEntries` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot pool entries. + - `LootPoolEntryContainer#getType` -> `codec`, not one-to-one + - `LootPoolEntryType` record is removed +- `net.minecraft.world.level.storage.loot.functions` now renames `CODEC` fields to `MAP_CODEC` + - `LootItemFunction#getType` -> `codec`, not one-to-one + - `LootItemFunctions` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot item functions. + - `LootItemFunctionType` record is removed +- `net.minecraft.world.level.storage.loot.predicates` now renames `CODEC` fields to `MAP_CODEC` + - `LootItemCondition#getType` -> `codec`, not one-to-one + - `LootItemConditions` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the loot item conditions. + - `LootItemConditionType` record is removed +- `net.minecraft.world.level.storage.loot.providers.nbt` now renames `CODEC` fields to `MAP_CODEC` + - `LootNbtProviderType` record is removed + - `NbtProvider` now implements `LootContextUser` + - `getType` -> `codec`, not one-to-one + - `NbtProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the nbt providers. + - `LootItemConditionType` record is removed +- `net.minecraft.world.level.storage.loot.providers.number` now renames `CODEC` fields to `MAP_CODEC` + - `LootNumberProviderType` record is removed + - `NumberProvider#getType` -> `codec`, not one-to-one + - `NumberProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the number providers. +- `net.minecraft.world.level.storage.loot.providers.score` now renames `CODEC` fields to `MAP_CODEC` + - `LootScoreProviderType` record is removed + - `ScoreProvider` now implements `LootContextUser` + - `getType` -> `codec`, not one-to-one + - `ScoreProviders` singleton fields have all been removed + - The map codecs in each class should be used instead + - `bootstrap` - Registers the score providers. + +### Validation Overhaul + +The validation handler used to collect and then report problems with data-generated content has been overhauled. This is not, and has never been a replacement for field validation. The validation handler is specifically for more easily handling validation between multiple pieces of information that may not be exposed to a single field, such as whether a loot provider can be used for the given context params. + +All validated objects implement either `Validatable`, or `CriterionTriggerInstance` specifically for advancement criteria. Both of these methods provide one method: `validate`, which is used to check the validity of an object. `validate` takes in a `ValidationContext`, which essentially holds the `ProblemReporter` used to collect issues, the current context params, and a reference resolver. `CriterionTriggerInstance` provides a `ValidationContextSource`, but this can be transformed to a `ValidationContext` using one of the `context` methods, providing the context params to check against. If the specific object cannot be validated, then `ValidationContext#reportProblem` is called, detailing the specific issue. + +```java +// For some object that implements Validatable + +@Override +public void validate(ValidationContext ctx) { + // Check if a specific condition is validated. + if (this.foo() != this.bar()) { + // If not, report that there is an issue. + ctx.reportProblem(() -> "'Foo' does not equal 'bar'."); + } +} +``` + +If the object itself does not have any issues, but rather the specific fields, then the reporter can follow the stack trace while checking the individual elements using one of the `ValidationContext#for*` methods, performing something similar. + +```java +// For some object that implements Validatable +// Let's assume it has a list of children objects. + +@Override +public void validate(ValidationContext ctx) { + for (int i = 0; i < this.children.size(); i++) { + // Get specific context for child in list + var childCtx = ctx.forIndexedField("children", i); + // Check if a specific condition is validated. + if (this.foo() != this.bar()) { + // If not, report that there is an issue. + childCtx.reportProblem(() -> "'Foo' does not equal 'bar'."); + } + } +} +``` + +`Validatable` also provides some static utilities for checking other `Validatable` fields. + +```java +// For some object that implements Validatable +// Assume some child object also implements Validatable + +@Override +public void validate(ValidationContext ctx) { + Validatable.validate(ctx, "child", this.child); +} +``` + +After `Validatable` is implemented on all required objects, the validation can then be called depending on where it is used (typically after deserialization or before serialization). The call stack for these is typically the following: + +```java +// For some Validatable validatable +// Let's assume we have access to the HolderGetter.Provider provider. +// The parameter itself is optional if not available. + +// Create the problem collector and validation context. +// The context params should only include the ones that are being provided. +ProblemReporter reporter = new ProblemCollector.Collector(); +ValidationContext ctx = new ValidationContext(reporter, LootContextParamSets.ALL_PARAMS, provider); + +// Call the validator +validatable.validate(ctx); +``` + +This can also be appended to the end of codecs via `Codec#validate`: + +```java +public record ExampleObject() implements Validatable { + public static final Codec CODEC = MapCodec.unitCodec( + ExampleObject::new + ).validate( + // Supply the validator along with the context params to check against. + // This method does not have access to the registry provider. + Validatable.validatorForContext(LootContextParamSets.ALL_PARAMS) + ); + + @Override + public void validate(ValidationContext ctx) { + // ... + } +} +``` + +- `net.minecraft.advancements.CriterionTriggerInstance#validate` now takes in a `ValidationContextSource` instead of a `CriterionValidator` +- `net.minecraft.advancements.criterion` + - `ContextAwarePredicate` now implements `Validatable` + - `CriterionValidator` -> `ValidationContextSource` and `Validatable` + - `Validatable` contains the `validate*` methods + - `ValidationContextSource` holds the context and reporters +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect` now implements `Validatable` + - `conditionCodec` is replaced by calling `validate` after load + - `TargetedConditionalEffect` now implements `Validatable` +- `net.minecraft.world.level.storage.loot` + - `IntRange` now implements `LootContextUser` + - `getReferencedContextParams` replaced by `validate` + - `LootContext$VisitedEntry` generic must now extend `Validatable` + - `LootContextUser` now implements `Validatable` + - `LootDataType` generic must now extend `Validatable` + - The constructor now takes in a `$ContextGetter` instead of a `$Validator` + - `runValidation` now takes in the `ValidationContextSource` instead of a `ValidationContext` + - Also has an overload taking in a `HolderLookup` instead of a key-value pair + - `createSimpleValidator`, `createLootTableValidator`, `$Validator` replaced by `Validatable` + - `$ContextGetter` - Gets the `ContextKeySet` for some value. + - `LootPool` now implements `Validatable` + - `LootTable` now implements `Validatable` + - `Validatable` - An interface which handles the validation of its instance within the given context. + - `ValidationContext` + - `forField` - Creates a context for a given field. + - `forIndexedField` - Creates a context for a given entry in a list. + - `forMapField` - Creates a context for a given key in a map. + - `setContextKeySet` is removed + - `ValidationContextSource` - The source for the defined context where the validation is taking place. +- `net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer` now implements `Validatable` +- `net.minecraft.world.level.storage.loot.functions` + - `SetAttributesFunction$Modifier` now implements `LootContextUser` + - `SetStewEffectFunction$EffectEntry` now implements `LootContextUser` + +### Datapack Villager Trades + +Villager trades has now become a data-generated registry from its original map-based setup. While basic impressions make it seem like that system is more limited, it is actually just as extensible, though in a rather convoluted way because the trades are functionally a loot table itself to determine what `MerchantOffer`s a trader can provide. For the purposes of understanding, this section will go over the basics of the trade rewrite, along with how each previous item listing can be converted to a `VillagerTrade`. + +#### Understanding the Trade Format + +All trades are expressed as `VillagerTrade`s, which at its core determines what a trader `wants` and what it `gives` in return. Each trade can also provide modifiers to the item itself or its cost, or whether the specific trade can be made at all with the given condition. Each trade also specifies the number of trades that can be made, how much xp to give, or the price multiple that is multiplied with the user's reputation. A `VillagerTrade` is then turned into a `MerchantOffer` via `getOffer`, taking in the `LootContext`, typically with a context param of `LootContextParamSets#VILLAGER_TRADE`, providing the trader itself (`THIS_ENTITY`) and its position (`ORIGIN`). + +The trades themselves are within `data//villager_trade/`. Typically the path contains the profession and level the trade is for, such as `examplemod:example_profession/1/example_trade` + +```json5 +// For some villager trade 'examplemod:example_profession/1/example_trade' +// JSON at 'data/examplemod/villager_trade/example_profession/1/example_trade.json' +{ + // The stack the trader wants. + "wants": { + // The item of the stack. + "id": "minecraft:apple", + // A number provider used to determine how much + // of the item that it wants. Once the count is + // determined, any additional cost on the `gives` + // stack (via `ADDITIONAL_TRADE_COST` component) + // is added to the count before being clamped to + // the max stack size. + // If not specified, defaults to 1. + "count": { + "type": "minecraft:uniform", + "min": 1, + "max": 5 + }, + // Any components that stack should have. The stack + // must have the exact components specified. + // If not specified, then no components will be + // checked, meaning that this is ignored. + "components": { + // Map of registry key to component value. + "minecraft:custom_name": "Apple...?" + } + }, + // An additional stack the trader wants. + // If not specified, the trader only checks `wants`. + "additional_wants": { + "id": "minecraft:emerald" + }, + // The stack template the trader gives in return. + "gives": { + // The item of the stack. + "id": "minecraft:golden_apple", + // A number [1, 99]. + // If not specified, defaults to 1. + "count": 1, + // The components to apply to the stack. + // If not specified, just applies the default + // item components. + "components": { + "minecraft:custom_name": "Not an Apple" + } + }, + // A number provider to determine how many times + // the trade can be performed by the player before + // the trader restocks. The value will always be at + // least 1. + // If not specified, defaults to 4. + "max_uses": { + "type": "minecraft:uniform", + "min": 1, + "max": 20 + }, + // A number provider to determine the price multiplier + // to apply to the cost of the item based on the player's + // reputation with the trader and the item demand, + // calculated from how many times the player has performed + // the trade. This should generally be a small number as + // the maximum reputation a user can have per trader is 150, + // though it's more likely to have a reputation of 25 at most. + // However, the trade must always have a minimum of one item, + // even if the reputation discount multiplied with the reputation + // indicates 100% or more off. + // If not specified, defaults to 0. + "reputation_discount": { + "type": "minecraft:uniform", + "min": 0, + "max": 0.05 + }, + // A number provider to determine the amount of experience + // the player obtains from performing the trade with the trader. + // This is typically around 5-30 xp for vanilla trades. + // If not specified, defaults to 1. + "xp": { + "type": "minecraft:uniform", + "min": 10, + "max": 20 + }, + // A loot item condition that determines whether the + // trader can provide the trade to the player. + // If not specified, defaults to always true. + "merchant_predicate": { + // This trade can only be performed by villagers + // from a desert or snow village. + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "predicates": { + "minecraft:villager/variant": [ + "minecraft:desert", + "minecraft:snow" + ] + } + } + }, + // A list of loot item functions that modify the item + // offered from `gives` to the player. + // If not specified, `gives` is not modified. + "given_item_modifiers": [ + { + // Chooses a random enchantment from the provided tag + "function": "minecraft:enchant_randomly", + // If this is true, the trade cost increases the + // number of `wants` items required. + "include_additional_cost_component": true, + "only_compatible": false, + "options": "#minecraft:trades/desert_common" + } + ], + // Can either be an enchantment id, such as "minecraft:protection", + // or a list of enchantment ids, such as ["minecraft:protection", "minecraft:smite", ...], + // or an enchantment tag, such as "#minecraft:trades/desert_common". + // When provided, if the `gives` item after modifiers contains an + // enchantment in this list, then the number of `wants` items required + // is multiplied by 2. + // If not specified, does nothing. + "double_trade_price_enchantments": "#minecraft:trades/desert_common" +} +``` + +#### The Trades of a Trader + +Every trader can make many trades, typically choosing from a specified pool known as a `TradeSet`. Trade sets themselves are a separate datapack registry that consumes `VillagerTrade`s. Each set of trades determines how many trades can be offered and if the same trade can be chosen more than once. The trades that are offered are computed within `AbstractVillager#addOffersFromTradeSet`, first calling `TradeSet#calculateNumberOfTrades` to get the number of offers, and then using either `AbstractVillager#addOffersFromItemListings` or `AbstractVillager#addOffersFromItemListingsWithoutDuplicates` to choose the offers to use. + +Note that if duplicate trades are allowed, there is a potential race condition where if all trades' `merchant_predicate`s fail, then the offers will loop forever. This is because the method always assumes that there will be one trade that can be made. + +The trade sets are within `data//trade_set/`. Typically the path contains the profession and level the trade is for, such as `examplemod:example_profession/level_1.json` + +```json5 +// For some trade set 'examplemod:example_profession/level_1' +// JSON at 'data/examplemod/villager_trade/trade_set/level_1.json' +{ + // Can either be a villager trade id, such as "examplemod:example_profession/1/example_trade", + // or a list of trade ids, such as ["examplemod:example_profession/1/example_trade", "minecraft:farmer/1/wheat_emerald", ...], + // or an trade tag, such as "#examplemod:example_profession/level_1". + // This is the set of trades that can be offered by the trader. + // This should always be a villager trade tag so allow other users + // to easily add their own trades to a trader. + "trades": "#examplemod:example_profession/level_1", + // A number provider that determines the number of offers that can be + // made by the trader. + "amount": { + "type": "minecraft:uniform", + "min": 1, + "max": 5 + }, + // Whether the same trade can be used to make multiple offers. + // If not specified, defaults to false. + "allow_duplicates": true, + // An identifier that determines the unique random instance to + // user when determining the offers. + // If not specified, uses the level random. + "random_sequence": "examplemod:example_profession/level_1" +} +``` + +Where the villager trade tag could be: + +```json5 +// For some tag 'examplemod:example_profession/level_1' +// JSON at 'data/examplemod/tags/villager_trade/example_profession/level_1.json' +{ + "values": [ + "examplemod:example_profession/1/example_trade" + ] +} +``` + +This also means trades can be easily added to existing trade sets by adding to the associated tag: + +```json5 +// For some tag 'minecraft:farmer/level_1' +// JSON at 'data/minecraft/tags/villager_trade/farmer/level_1.json' +{ + "values": [ + "examplemod:example_profession/1/example_trade" + ] +} +``` + +Meanwhile, adding to a new `VillagerProfession` is done by mapping the level int to the trade set key in `tradeSetsByLevel`: + +```java +public static final VillagerProfession EXAMPLE = Registry.register( + BuiltInRegistries.VILLAGER_PROFESSION, + Identifier.fromNamespaceAndPath("examplemod", "example_profession"), + new VillagerProfession( + Component.literal(""), + p -> true, + p -> true, + ImmutableSet.of(), + ImmutableSet.of(), + null, + // A map of profession level to trade set keys + Int2ObjectMap.ofEntries( + Int2ObjectMap.entry( + // The profession level + 1, + // The trade set id + ResourceKey.create(Registries.TRADE_SET, Identifier.fromNamespaceAndPath("examplemod", "example_profession/level_1")) + ) + ) + ) +); +``` + +#### Item Listing Conversions + +With all this in mind, we can now convert item listings to their new data-generated villager trades. + +##### Emeralds <-> Items + +For the following trades: + +```java +public static final VillagerTrades.ItemListing ITEM_TO_EMERALD = new VillagerTrades.EmeraldForItems( + // The item the trader wants. + Items.WHEAT, + // The number of items the trader wants. + 20, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 2, + // The number of emeralds given in return. + 1 +); + +public static final VillagerTrades.ItemListing EMERALD_TO_ITEM = new VillagerTrades.ItemsForEmeralds( + // The item the trader will give in return. + Items.BREAD, + // The number of emeralds the trader wants. + 1, + // The number of items the trader will give. + 6, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 1, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.05f +); +``` + +Their equivalent would be: + +```json5 +// For some villager trade 'examplemod:item_to_emerald' +// JSON at 'data/examplemod/villager_trade/item_to_emerald.json' +{ + "gives": { + // The number of emeralds given in return. + "count": 1, + "id": "minecraft:emerald" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + // `EmeraldForItems` hardcoded this to 0.05 + "reputation_discount": 0.05, + "wants": { + // The number of items the trader wants. + "count": 20, + // The item the trader wants. + "id": "minecraft:wheat" + }, + // The amount of experience given for the trade. + "xp": 2 +} + + +// For some villager trade 'examplemod:emerald_to_item' +// JSON at 'data/examplemod/villager_trade/emerald_to_item.json' +{ + "gives": { + // The number of items the trader will give. + "count": 6, + // The item the trader will give in return. + "id": "minecraft:bread" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + "id": "minecraft:emerald", + // The number of emeralds the trader wants. + "count": 1 + }, + // The amount of experience given for the trade. + "xp": 1 +} +``` + +##### Items and Emeralds -> Items + +For the following trade: + +```java +public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_ITEM = new VillagerTrades.ItemsAndEmeraldsToItems( + // The item the trader wants. + Items.COD, + // The number of items the trader wants. + 6, + // The number of emeralds the trader additionally wants. + 1, + // The item the trader will give in return. + Items.COOKED_COD, + // The number of items the trader will give. + 6, + // The maximum number of times the trade can be made + // before restock. + 16, + // The amount of experience given for the trade. + 1, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.05f +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:item_emerald_to_item' +// JSON at 'data/examplemod/villager_trade/item_emerald_to_item.json' +{ + // The emeralds the trader additionally wants. + "additional_wants": { + "id": "minecraft:emerald", + }, + "gives": { + // The number of items the trader will give. + "count": 6, + // The item the trader will give in return. + "id": "minecraft:cooked_cod" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 16, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + // The number of items the trader wants. + "count": 6, + // The item the trader wants. + "id": "minecraft:cod" + }, + // The amount of experience given for the trade. + "xp": 1 +} +``` + +##### Emeralds -> Dyed Armor + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_DYED_ARMOR = new VillagerTrades.DyedArmorForEmeralds( + // The item the trader will give in return and dye. + Items.LEATHER_HELMET, + // The number of emeralds the trader wants. + 5, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 5 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_dyed_armor' +// JSON at 'data/examplemod/villager_trade/emerald_to_dyed_armor.json' +{ + "given_item_modifiers": [ + { + // Sets the random dye(s) on the armor. + "function": "minecraft:set_random_dyes", + "number_of_dyes": { + "type": "minecraft:sum", + "summands": [ + 1.0, + { + "type": "minecraft:binomial", + "n": 2.0, + "p": 0.75 + } + ] + } + }, + { + // Checks that the dye was successfully applied + // to the item. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:leather_helmet", + "predicates": { + "minecraft:dyed_color": {} + } + }, + // If it fails, discards the offer. + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // The item the trader will give in return and dye. + "id": "minecraft:leather_helmet" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 5, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 5 +} +``` + +##### Emeralds -> Enchanted Item + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_BOOK = new VillagerTrades.EnchantBookForEmeralds( + // The amount of experience given for the trade. + 30, + // The minimum level used when selecting the stored enchantments on the book. + 3, + // The maximum level used when selecting the stored enchantments on the book. + 3, + // A tag containing the list of available enchantments to select from for the book. + EnchantmentTags.TRADES_DESERT_SPECIAL +); + +public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_ITEM = new VillagerTrades.EnchantedItemForEmeralds( + // The item the trader will give in return and try to enchant. + Items.FISHING_ROD, + // The base number of emeralds the trader wants. + 3, + // The maximum number of times the trade can be made + // before restock. + 3, + // The amount of experience given for the trade. + 10, + // The price multiplier to apply to the offer, given + // reputation and demand. + 0.2f +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_enchanted_book' +// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_book.json' +{ + // The trader expects a book to write the enchantment to. + "additional_wants": { + "id": "minecraft:book" + }, + // Trade cost for emeralds increased when in the double trade price + // tag. + "double_trade_price_enchantments": "#minecraft:double_trade_price", + "given_item_modifiers": [ + { + "function": "minecraft:enchant_with_levels", + "include_additional_cost_component": true, + "levels": { + "type": "minecraft:uniform", + // The minimum level used when selecting the stored enchantments on the book. + "min": 3, + // The maximum level used when selecting the stored enchantments on the book. + "max": 3 + }, + // The list of available enchantments to select from for the book. + "options": [ + "minecraft:efficiency" + ] + }, + { + // Make sure the enchantment was added successfully with the given level. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:enchanted_book", + "predicates": { + "minecraft:stored_enchantments": [ + { + "levels": { + // The minimum level used when selecting the stored enchantments on the book. + "min": 3, + // The maximum level used when selecting the stored enchantments on the book. + "max": 3 + } + } + ] + } + }, + // Discard on failure + "on_fail": { + "function": "minecraft:discard" + } + } + ], + // The trader gives the enchanted book. + "gives": { + "count": 1, + "id": "minecraft:enchanted_book" + }, + // The maximum number of times the trade can be made + // before restock was hardcoded to 12. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.2. + "reputation_discount": 0.2, + "wants": { + "count": { + "type": "minecraft:sum", + "summands": [ + // A hardcoded computation based on the min and max + // level of the enchantment. + 11.0, + { + "type": "minecraft:uniform", + "max": 35.0, + "min": 0.0 + } + ] + }, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 30 +} + +// For some villager trade 'examplemod:emerald_to_enchanted_item' +// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_item.json' +{ + "given_item_modifiers": [ + { + // Applies the enchantment to the given equipment. + "function": "minecraft:enchant_with_levels", + "include_additional_cost_component": true, + "levels": { + "type": "minecraft:uniform", + "max": 20, + "min": 5 + }, + "options": "#minecraft:on_traded_equipment" + }, + { + // Checks to make sure the enchantment was applied. + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:fishing_rod", + "predicates": { + "minecraft:enchantments": [ + {} + ] + } + }, + // On fail, give nothing. + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // The item the trader will give in return and try to enchant. + "id": "minecraft:fishing_rod" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 3, + // The price multiplier to apply to the offer, given + // reputation and demand. + "reputation_discount": 0.2, + "wants": { + "count": { + "type": "minecraft:sum", + "summands": [ + // The base number of emeralds the trader wants. + 3, + { + // The variation based on the enchantment level. + // Originally, this would be the value used in the + // item function, but since they are now isolated, + // these values could differ. + "type": "minecraft:uniform", + "max": 20, + "min": 5 + } + ] + }, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 10 +} +``` + +##### Items and Emeralds -> Potion Effect Item + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_SUSPICIOUS_STEW = new VillagerTrades.SuspiciousStewForEmerald( + // The effect applied by the suspicious stew. + MobEffects.NIGHT_VISION, + // The number of ticks the effect should be active for. + 100, + // The amount of experience given for the trade. + 15 +); + +public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_TIPPED_ARROW = new VillagerTrades.TippedArrowForItemsAndEmeralds( + // The item the trader additionally wants. + Items.ARROW, + // The number of items the trader additionally wants. + 5, + // The item the trader will give in return. + Items.TIPPED_ARROW, + // The number of items the trader will give. + 5, + // The number of emeralds the trader wants. + 2, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 30 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_suspicious_stew' +// JSON at 'data/examplemod/villager_trade/emerald_to_suspicious_stew.json' +{ + "given_item_modifiers": [ + { + "effects": [ + { + // The effect applied by the suspicious stew. + "type": "minecraft:night_vision", + // The number of ticks the effect should be active for. + "duration": 100 + } + // Vanilla merges all suspicious stew offers + // into one since this function picks one + // stew effect at random. + ], + "function": "minecraft:set_stew_effect" + } + ], + "gives": { + "count": 1, + "id": "minecraft:suspicious_stew" + }, + // The maximum number of times the trade can be made + // before restock, hardcoded to 12. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 15 +} + +// For some villager trade 'examplemod:item_emerald_to_tipped_arrow' +// JSON at 'data/examplemod/villager_trade/item_emerald_to_tipped_arrow.json' +{ + "additional_wants": { + // The number of items the trader additionally wants. + "count": 5, + // The item the trader additionally wants. + "id": "minecraft:arrow" + }, + "given_item_modifiers": [ + { + // Applies a random potion effect from the tradable potions. + // Original implementation just picked any potion at random. + "function": "minecraft:set_random_potion", + "options": "#minecraft:tradeable" + } + ], + "gives": { + // The number of items the trader will give. + "count": 5, + // The item the trader will give in return. + "id": "minecraft:tipped_arrow" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 2, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 30 +} +``` + +##### Emeralds -> Treasure Map + +For the following trade: + +```java +public static final VillagerTrades.ItemListing EMERALD_TO_TREASURE_MAP = new VillagerTrades.TreasureMapForEmeralds( + // The number of emeralds the trader wants. + 8, + // A tag containing a list of treasure structures to find the nearest of. + StructureTags.ON_TAIGA_VILLAGE_MAPS, + // The translation key of the map name. + "filled_map.village_taiga", + // The icon used to decorate the treasure location found on the map. + MapDecorationTypes.TAIGA_VILLAGE, + // The maximum number of times the trade can be made + // before restock. + 12, + // The amount of experience given for the trade. + 5 +); +``` + +The equivalent would be: + +```json5 +// For some villager trade 'examplemod:emerald_to_treasure_map' +// JSON at 'data/examplemod/villager_trade/emerald_to_treasure_map.json' +{ + "additional_wants": { + // An item the trader additionally wants, hardcoded to compass. + "id": "minecraft:compass" + }, + "given_item_modifiers": [ + { + // Finds a treasure structure to display on the map. + + // The icon used to decorate the treasure location found on the map. + "decoration": "minecraft:village_taiga", + // A tag containing a list of treasure structures to find the nearest of. + "destination": "minecraft:on_taiga_village_maps", + "function": "minecraft:exploration_map", + "search_radius": 100 + }, + { + // Sets the name of the map. + + "function": "minecraft:set_name", + "name": { + // The translation key of the map name. + "translate": "filled_map.village_taiga" + }, + "target": "item_name" + }, + { + // Check to make sure a structure was found. + + "function": "minecraft:filtered", + "item_filter": { + "items": "minecraft:filled_map", + "predicates": { + "minecraft:map_id": {} + } + }, + "on_fail": { + "function": "minecraft:discard" + } + } + ], + "gives": { + "count": 1, + // Returns a map filled with the treasure location. + "id": "minecraft:map" + }, + // The maximum number of times the trade can be made + // before restock. + "max_uses": 12, + // The price multiplier to apply to the offer, given + // reputation and demand, hardcoded to 0.05. + "reputation_discount": 0.05, + "wants": { + // The number of emeralds the trader wants. + "count": 8, + "id": "minecraft:emerald" + }, + // The amount of experience given for the trade. + "xp": 5 +} +``` + +##### Villager Variants + +Some traders would provide different options depending on the villager type it was as one giant map of item listings. Now, each type has its own individual villager trade, using a `merchant_predicate` to check whether the offer can be made to the specific villager type: + +```json5 +// For some villager trade 'examplemod:villager_type_item' +// JSON at 'data/examplemod/villager_trade/villager_type_item.json' +{ + // ... + "merchant_predicate": { + // Check the entity. + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "predicates": { + // Villager type must be desert for this trade to be chosen. + "minecraft:villager/variant": "minecraft:desert" + } + } + }, + // ... +} +``` + +- `net.minecraft.core.registries.Registries` + - `TRADE_SET` - A key to the registry holding a list of trades. + - `VILLAGER_TRADE` - A key to the registry holding a single trade. +- `net.minecraft.tags.VillagerTradeTags` - Tags for villager trades. +- `net.minecraft.world.entity.npc.villager` + - `AbstractVillager#addOffersFromItemListings` -> `addOffersFromTradeSet`, taking in a key for the trade set rather than the `$ItemListing`s and number of offers; not one-to-one + - `VillagerProfession` now takes in a map of trader level to `TradeSet` + - `getTrades` - Returns the trades set key for the given level. + - `VillagerTrades` has been split into many different classes and implementations + - `TRADES`, `EXPERIMENTAL_TRADES`, `WANDERING_TRADER_TRADES` is now represented by the `VillagerProfession#tradeSetsByLevel` + - As they are now datapack entries, they are stored in their respective datapacks + - `TRADES`, `EXPERIMENTAL_TRADES` are represented by `data/minecraft/trade_set//*` + - `WANDERING_TRADER_TRADES` are represented by `data/minecraft/trade_set/wandering_trader/*` + - `$DyedArmorForEmeralds` -> `VillagerTrades#dyedItem`, `addRandomDye`; not one-to-one + - `$EmeraldForItems` -> `VillagerTrade`, not one-to-one + - `$EmeraldsForVillagerTypeItem` -> `VillagerTrades#registerBoatTrades`, see usage, not one-to-one + - `$EnchantBookForEmeralds` -> `VillagerTrades#enchantedBook`, not one-to-one + - `$EnchantedItemForEmeralds` -> `VillagerTrades#enchantedItem`, not one-to-one + - `$ItemListing` -> `VillagerTrade` + - `$ItemsAndEmeraldsToItems` -> `VillagerTrade` with `additionalWants` + - `$ItemsForEmeralds` -> `VillagerTrade`, not one-to-one + - `$SuspiciousStewForEmerald` -> `VillagerTrade` with `SetStewEffectFunction` + - `$TippedArrowForItemsAndEmeralds` -> `VillagerTrade` with `SetRandomPotionFunction` + - `$TreasureMapForEmeralds` -> `VillagerTrades$VillagerExplorerMapEntry`, see usage, not one-to-one + - `$TypeSpecificTrade` -> `VillagerTrades#villagerTypeRestriction`, `villagerTypeHolderSet`; not one-to-one +- `net.minecraft.world.item.enchantment.providers.TradeRebalanceEnchantmentProviders` interface is removed + - Replaced by `TradeRebalanceVillagerTrades`, `TradeRebalanceRegistries` +- `net.minecraft.world.item.trading` + - `TradeCost` - An `ItemStack` that is being traded to some trader. + - `TradeRebalanceVillagerTrades` - All trades part of the trade rebalance datapack. + - `TradeSet` - A set of trades that can be performed by a trader at some level. + - `TradeSets` - All vanilla trades sets for some trader at some level. + - `VillagerTrade` - A trade between the trader and the player. + - `VillagerTrades` - All vanilla trades. +- `net.minecraft.world.level.storage.loot.parameters.LootContextParamSets#VILLAGER_TRADE` - A loot context when a villager trade is taking place, containing the trade origin and the trading entity. + +### `Level#random` field now protected + +The `Level#random` field is now `protected` instead of `public`. As such, uses should transition to using the public `getRandom` method. + +```java +// For some Level level +RandomSource random = level.getRandom(); +``` + +- `net.minecraft.world.level.Level#random` field is now `protected` instead of `public` + - Use `getRandom` method instead + +### Data Component Initializers + +Data components have begun their transition from being moved off the raw object and onto the `Holder` itself. This is to properly handle objects that are not available during construction, such as datapack registry objects for items. Currently, this is only implemented for `Item`s, but the system allows for any registry object, given its wrapped-holder, to store some defined data components. + +Data components are attached to their holders through the `DataComponentInitializers`. During object construction, `DataComponentInitializers#add` is called, providing the `ResourceKey` identifier of the registry object, along with a `DataComponentInitializers$Initializer`. The initializer takes in three parameters: the builder for the component map, the full registries `HolderLookup$Provider`, and the key passed to `DataComponentInitializers#add`. The initializer functions like a consumer, also allowing for additional initializers to be chained via `$Initializer#andThen` or to easily add a component via `$Initializer#add`. + +```java +// For some custom registry object +public ExampleObject(ResourceKey id) { + // Register the data component initializer + BuiltInRegistries.DATA_COMPONENT_INITIALIZERS.add( + // The identifier for the registry object + id, + // The initializer function, taking in a component builder, + // the registries context, and the id + (components, context, key) -> components + .set(DataComponents.MAX_DAMAGE, 1) + .set(DataComponents.DAMAGE_TYPE, context.getOrThrow(DamageTypes.SPEAR)) + ); +} +``` + +From there, the data components are initialized or reinitialized whenever `ReloadableServerResources#loadResources` is called (on datapack reload). The datapack objects are loaded first, then the components are set on the `Holder$Reference`s. From there, the components can be gathered via `Holder#components`. + +```java +// For some Holder EXAMPLE_HOLDER +DataComponentMap components = EXAMPLE_HOLDER.components(); +``` + +#### Items + +Since components are now initialized during resource reload, `Item$Properties` provides two methods to properly delay component initialization until such data components are loaded: `delayedComponent` and `delayedHolderComponent`. `delayedComponent` takes in the component type and a function that takes in the `HolderLookup$Provider` and returns the component value. `delayedHolderCOmponent` delegates to `delayedComponent`, taking in a `ResourceKey` and setting the registry object as the component value. + +```java +public static final Item EXAMPLE_ITEM = new Item( + new Item.Properties() + .delayedComponent( + // The component type whose construction + // should be lazily initialized. + DataComponents.JUKEBOX_PLAYABLE, + // A function that takes in the registries + // and returns the component value. + context -> new JukeboxPlayable(context.getOrThrow( + JukeboxSongs.THIRTEEN + )) + ) + .delayedHolderComponent( + // The component type which has a + // holder value type. + DataComponents.DAMAGE_TYPE + // The resource key for a registry + // object of the associated holder + // generic type. + DamageTypes.SPEAR + ) + // ... +); +``` + +#### Recipes + +Since data components now hold the true values from being lazily initialized after resource reload, `Recipe#assemble` no longer takes in the `HolderLookup$Provider`. Instead, it assumes that the recipe has all the required data stored passed into the recipe, either on a stack or directly. + +- `net.minecraft.core` + - `Holder` + - `areComponentsBound` - Whether the components have been bound to the holder. + - `components` - The components of the object stored on the holder. + - `direct`, `$Direct` now can take in the `DataComponentMap` + - `$Reference#bindComponents` - Stores the components on the holder reference. + - `Registry#componentLookup` - Gets the lookup of component to holders. + - `WritableRegistry#bindTag` -> `bindTags`, now taking in a map of keys to holder lists instead of one mapping +- `net.minecraft.core.component` + - `DataComponentInitializers` - A class that handles initializing the data components for component-attached objects. + - `DataComponentLookup` - A lookup that maps the component type to the holders that use it. + - `DataComponentMap$Builder#addValidator` - Adds a validator for the components on the object. + - `DataComponentPatch` + - `get` now takes in a `DataComponentGetter` and returns the raw component value + - `$Builder#set` now has an overload that takes in an iterable of `TypedDataComponent`s + - `DataComponents` + - `DAMAGE_TYPE` now is a holder-wrapped `DamageType` instead of `EitherHolder`-wrapped + - `PROVIDES_TRIM_MATERIAL` now is a holder-wrapped `TrimMaterial` instead of `ProvidesTrimMaterial` + - `CHICKEN_VARIANT` now is a holder-wrapped `ChickenVariant` instead of `EitherHolder`-wrapped + - `ZOMBIE_NAUTILUS_VARIANT` now is a holder-wrapped `ZombieNautilusVariant` instead of `EitherHolder`-wrapped + - `PROVIDES_BANNER_PATTERNS` is now a `HolderSet` instead of a `TagKey` +- `net.minecraft.core.registries` + - `BuiltInRegistries#DATA_COMPONENT_INITIALIZERS` - A list of data components attached to registry entries. + - `Registries#componentsDirPath` - The path directory for the components in a registry. +- `net.minecraft.data.PackOutput#createRegistryComponentPathProvider` - The path provider for the components registry report. +- `net.minecraft.data.info.ItemListReport` -> `RegistryComponentsReport`, not one-to-one +- `net.minecraft.resources` + - `NetworkRegistryLoadTask` - A load task that handles registering registry objects and tags from the network, or else from a resource. + - `RegistryDataLoader` + - `$PendingRegistration` -> `RegistryLoadTask$PendingRegistration` + - `$RegistryData` now takes in a `RegistryValidator` instead of a `boolean` + - `$RegistryLoadTask` -> `RegistryLoadTask`, not one-to-one + - `RegistryValidator` - An interface that validates the entries in a registry, storing all errors in a map. + - `ResourceManagerRegistryLoadTask` - A load task that handles registering registry objects and tags from the local resource manager. +- `net.minecraft.server.ReloadableServerResources#updateStaticRegistryTags` -> `updateComponentsAndStaticRegistryTags`, not one-to-one +- `net.minecraft.world.item` + - `EitherHolder` class is removed + - `Item` + - `CODEC_WITH_BOUND_COMPONENTS` - An item codec that validates that the components are bound. + - `$Properties` + - `delayedComponent` - Sets the component lazily, providing the `HolderLookup$Provider` to get any dynamic elements. + - `delayedHolderComponent` - Sets the component lazily for some holder-wrapped registry object. + - `ItemStack#validateComponents` is now `private` from `public` + - `JukeboxPlayable` now holds a holder-wrapped `JukeboxSong` instead of an `EitherHolder`-wrapped variant + - `JukeboxSong#fromStack` no longer takes in the `HolderLookup$Provider` + - `SpawnEggItem` + - `spawnEntity` is now `static` + - `byId` now returns an optional holder-wrapped `Item` instead of a `SpawnEggItem` + - `eggs` is removed + - `getType` is now `static` + - `spawnOffspringFromSpawnEgg` is now `static` +- `net.minecraft.world.item.component` + - `BlocksAttacks` now holds an optional holder set-wrapped `DamageType` instead of a `TagKey` + - `DamageResistant` now holds a holder set `DamageType` instead of a `TagKey` + - `InstrumentComponent` now holds a holder-wrapped `Instrument` instead of an `EitherHolder`-wrapped variant + - `unwrap` is removed + - `ProvidesTrimMaterial` now holds a holder-wrapped `TrimMaterial` instead of an `EitherHolder`-wrapped variant +- `net.minecraft.world.item.crafting` + - `Recipe#assemble` no longer takes in the `HolderLookup$Provider` + - `SmithingTrimRecipe#applyTrim` no longer takes in the `HolderLookup$Provider` +- `net.minecraft.world.item.equipment.trim.TrimMaterials#getFromIngredient` is removed +- `net.minecraft.world.level.storage.loot.functions.SetInstrumentFunction`, `#setInstrumentOptions` now takes in a holder set-wrapped `Instrument` instead of a `TagKey` +- `net.minecraft.world.timeline.Timeline#validateRegistry` - Validates that each time marker was only defined once. + +### Item Instances and Stack Templates + +`ItemStack`s now have an immutable instance known as an `ItemStackTemplate`. Similar to the `ItemStack`, it contains the holder-wrapped `Item`, the number of items it represents, and a `DataComponentPatch` of the components to apply to the stack. The template can be transformed to a stack via `create`, or `apply` if adding additional data components. An `ItemStack` can likewise be turned into a template via `ItemStackTemplate#fromNonEmptyStack`. Templates are now used in place of `ItemStack`s were immutability is required (e.g., advancements, recipes, etc.). They provide a regular `CODEC`, a `MAP_CODEC`, and a `STREAM_CODEC` for network communication. + +```java +ItemStackTemplate apple = new ItemStackTemplate( + // The item of the stack + Items.APPLE.builtInRegistryHolder(), + // The number of items held + 5, + // The components applied to the stack + DataComponentPatch.builder() + .set(DataComponents.ITEM_NAME, Component.literal("Apple?")) + .build() +); + +// Turn the template into a stack +ItemStack stack = apple.create(); + +// Creating a template from a non-empty stack +ItemStackTemplate fromStack = ItemStackTemplate.fromNonEmptyStack(stack); +``` + +To help standardize accessing the general components between the two, both the template and the stack implement `ItemInstance`, which provides access to the standard holder method checks, the count, and the `DataComponentGetter`. The common interface also means that if it doesn't matter whether the stack is mutable or not, then the `ItemInstance` can be used as the type. + +```java +// Both are item instances +ItemInstance stack = new ItemStack(Items.APPLE); +ItemInstance template = new ItemStackTemplate(Items.APPLE); + +// Get the holder or check something +Holder item = stack.typeHolder(); +template.is(Items.APPLE); + +// Get the number of items in the stack or template +int stackCount = stack.count(); +int templateCount = template.count(); + +// Get the component values +Identifier stackModel = stack.get(DataComponents.ITEM_MODEL); +Identifier templateModel = template.get(DataComponents.ITEM_MODEL); +``` + +#### Recipe Builders + +Due to the addition of `ItemStackTemplate`s, `RecipeBuilder`s have changed slightly in their implementation. First, the builder no longer stores an `Item` for the result, instead defining the `defaultId` as the resource key recipe. As such, this allows for a more clear method of defining custom recipes that do not export an `Item`. + +Of course, the change to this new format just has `defaultId` return `RecipeBuilder#getDefaultRecipeId` with the `ItemInstance` (either a stack or template), like so: + +```java +public class ExampleRecipeBuilder implements RecipeBuilder { + + // The result of the recipe + private final ItemStackTemplate result; + + public ExampleRecipeBuilder(ItemStackTemplate result) { + this.result = result; + } + + @Override + public ResourceKey> defaultId() { + // Get the default recipe id from the result + return RecipeBuilder.getDefaultRecipeId(this.result); + } + + // Implement everything else below + // ... +} +``` + +- `net.minecraft.advancements` + - `Advancement$Builder#display` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `DisplayInfo` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `getIcon` now returns an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.advancements.criterion` + - `AnyBlockInteractionTrigger#trigger` now takes in an `ItemInstance` instead of an `ItemStack` + - `ItemPredicate` now implements a predicate of `ItemInstance` instead of `ItemStack` + - `ItemUsedOnLocationTrigger#trigger` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.client.particle.BreakingItemParticle$ItemParticleProvider#getSprite` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.commands.arguments.item` + - `ItemInput` is now a record + - `serialize` is removed + - `createItemStack` no longer takes in the `boolean` to check the size + - `ItemParser#parse` now returns an `ItemResult` instead of an `ItemParser$ItemResult` + - `$ItemResult` merged into `ItemInput` +- `net.minecraft.core.component.predicates` + - `BundlePredicate` now deals with an iterable of `ItemInstance`s rather than `ItemStack`s + - `ContainerPredicate` now deals with an iterable of `ItemInstance`s rather than `ItemStack`s +- `net.minecraft.core.particles.ItemParticleOption` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - There is also an overload for a regular `Item` + - `getItem` now returns an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.data.recipes` + - `RecipeBuilder` + - `getResult` is removed + - `defaultId` - The default identifiers for the recipe made with this builder. + - `getDefaultRecipeId` now takes in an `ItemInstance` instead of an `ItemLike` + - `RecipeProvider` + - `oreSmelting`, `oreBlasting` now take in a `CookingBookCategory` + - `oreCooking` no longer takes in the `RecipeSerializer` and now takes in a `CookingBookCategory` + - `cookRecipes`, `simpleCookingRecipe` no longer take in the `RecipeSerializer` + - `shapeless` now takes in an `ItemStackTemplate` instead of an `ItemStack` + - `ShapedRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - Both constructors are `private` + - `ShapelessRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of an `ItemStack` + - `SimpleCookingRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - `generic` no longer takes in the `RecipeSerializer` and now takes in a `CookingBookCategory` + - `blasting`, `smelting` now take in a `CookingBookCategory` + - `SingleItemRecipeBuilder` now takes in an `ItemStackTemplate` for the result, with the `ItemLike` moved to an overload + - The `ItemStackTemplate` constructor is made `private` + - `SmithingTransformRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of an `Item` + - `TransmuteRecipeBuilder` now takes in an `ItemStackTemplate` for the result instead of a `Holder` + - The constructor is `private` + - `transmute` now has an overload that takes in the `ItemStackTemplate` for the result + - `addMaterialCountToOutput`, `setMaterialCount` - Handles the size of the result stack based on the number of materials used. +- `net.minecraft.network.chat.HoverEvent$ShowItem` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.server.dialog.body.ItemBody` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.entity.LivingEntity` + - `dropFromEntityInteractLootTable` now takes in an `ItemInstance` instead of an `ItemStack` for the tool + - `dropFromShearingLootTable` now takes in an `ItemInstance` instead of an `ItemStack` for the tool +- `net.minecraft.world.item` + - `BundleItem#getSelectedItemStack` -> `getSelectedItem`, now returning an `ItemStackTemplate` instead of an `ItemStack` + - `Item` + - `getCraftingRemainder` now returns an `ItemStackTemplate` instead of an `ItemStack` + - `$Properties#craftRemainder` now has an overload that takes in the `ItemStackTemplate` + - `ItemInstance` - A typed item instance that can query the item, the size, and its components. + - `ItemStack` now implements `ItemInstance` + - `SINGLE_ITEM_CODEC`, `STRICT_CODEC`, `STRING_SINGLE_ITEM_CODEC`, `SIMPLE_ITEM_CODEC` are removed + - `getMaxStackSize` -> `ItemInstance#getMaxStackSize` + - `ItemStackTemplate` - A record containing the immutable components of a stack: the item, count, and components. +- `net.minecraft.world.item.component` + - `BundleContents` now takes in a list of `ItemStackTemplate`s instead of `ItemStack`s + - `items` now returns a list of `ItemStackTemplate`s instead of an iterable of `ItemStack`s + - `itemsCopy` is removed + - `getSelectedItem` - Returns the stack template of the selected item, or `null` if no item is selected. + - `ChargedProjectile` is now a record + - The constructor takes in a list of `ItemStackTemplate`s instead of `ItemStack`s + - `of` -> `ofNonEmpty` + - `getItems` -> `itemCopies` + - `ItemContainerContents` + - `stream` -> `allItemsCopyStream` + - `nonEmptyStream` -> `nonEmptyItemCopyStream` + - `nonEmptyItems`, `nonEmptyItemsCopy` -> `nonEmptyItems`, now returning an iterable of `ItemStackTemplate`s instead of `ItemStack`s + - `UseRemainder` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `$Factory#create` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `BlastingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `CampfireCookingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `ShapedRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `ShapelessRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SingleItemRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `result` now returns an `ItemStackTemplate` instead of an `ItemStack` + - `$Factory#create` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmeltingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmithingTransformRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `SmokingRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `StonecutterRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `TransmuteRecipe` now takes in an `ItemStackTemplate` instead of an `ItemStack` for the result + - `TransmuteResult` -> `ItemStackTemplate`, not one-to-one + - `isResultUnchanged` is removed + - `apply` -> `TransmuteRecipe#createWithOriginalComponents`, not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay$ItemStackSlotDisplay` now takes in an `ItemStackTemplate` instead of an `ItemStack` +- `net.minecraft.world.item.enchantment.EnchantmentHelper#getItemEnchantmentLevel` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.world.level.block.Block` + - `dropFromBlockInteractLootTable` now takes in an `ItemInstance` instead of an `ItemStack` + - `getDrops` now takes in an `ItemInstance` instead of an `ItemStack` +- `net.minecraft.world.level.block.entity.DecoratedPotBlockEntity#createdDecoratedPotItem` -> `createdDecoratedPotInstance` + - `createDecoratedPotTemplate` creates the `ItemStackTemplate` instead of the `ItemStack` +- `net.minecraft.world.level.storage.loot` + - `LootContext$ItemStackTarget` now implements an `ItemInstance` generic for the argument getter instead of the `ItemStack` + - `LootContextArg$ArgCodecBuilder#anyItemStack` now requires a function taking in an `ItemInstance` context key instead of an `ItemStack` context key +- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#TOOL` is now an `ItemInstance` context key instead of an `ItemStack` context key + +### Serializer Records and Recipe Info + +Recipes have been slightly reworked in their implementation. First, `RecipeSerializer` is now a record taking in the `MapCodec` and `StreamCodec` used to serialize and deserialize the recipe. As such, `Serializer` classes have been removed in their entirety, replaced with providing the codecs to the record during registration: + +```java +// Assume some ExampleRecipe implements Recipe +// We'll say there's also only one INSTANCE +public static final RecipeSerializer EXAMPLE_RECIPE = new RecipeSerializer<>( + // The map codec for reading the recipe to/from disk. + MapCodec.unit(INSTANCE), + // The stream codec for reading the recipe to/from the network. + StreamCodec.unit(INSTANCE) +); +``` + +Second, some common data regarding the recipe settings and book information have been sectioned into separate objects. These objects are passed into the recipe as part of the constructor and used to more cleanly handle similar implementations across all recipes. + +Vanilla provides four of these common object classes, split into two separate categories. `Recipe$CommonInfo` is used for general recipe settings. Meanwhile, `Recipe$BookInfo` is used for recipe book information, with `CraftingRecipe$CraftingBookInfo` for crafting recipes, and `AbstractCookingRecipe$CookingBookInfo` for cooking recipes (e.g., smelting, blasting, etc.). The common object classes provide methods for constructing the codecs as required, which can then be passed into the relevant recipe codec. + +These classes are typically passed through the `Recipe` subclasses, used as boilerplate to implement abstract methods. None of the data in these objects are directly available outside the implementation itself, only through the methods defined in the `Recipe` interface. Because of this, classes like `NormalCraftingRecipe`, `CustomRecipe`, `SimpleSmithingRecipe`, and `SingleItemRecipe`, and `AbstractCookingRecipe` can be used to create a new recipe implementation by implementing a few methods. + +Note that these common info classes are a design philosophy, which you can choose to implement if desired. It's only when building off existing recipe subtypes that you are required to make use of them. + +- `net.minecraft.data.recipes` + - `CustomCraftingRecipeBuilder` - A recipe builder that creates an arbitrary crafting recipe from some common and crafting book information. + - `RecipeBuilder` + - `determineBookCategory` -> `determineCraftingBookCategory` + - `createCraftingCommonInfo` - Creates the common recipe info. + - `createCraftingBookInfo` - Creates the crafting book info. + - `RecipeUnlockAdvancementBuilder` - An advancement builder for unlocking a recipe. + - `SpecialRecipeBuilder`, `special` now takes in a supplied `Recipe` instead of a function of `CraftingBookCategory` to `Recipe` + - `unlockedBy` - The criteria required to unlock the recipe advancement. +- `net.minecraft.world.item.crafting` + - `AbstractCookingRecipe` now takes in the `Recipe$CommonInfo` and `$CookingBookInfo` instead of the group and `CookingBookCategory` + - `$Factory#create` now takes in the `Recipe$CommonInfo` and `$CookingBookInfo` instead of the group and `CookingBookCategory` + - `$Serializer` replaced by `cookingMapCodec`, `cookingStreamCodec` + - `$CookingBookInfo` - A record containing the common cooking information for the recipe book. + - `BannerDuplicateRecipe` now takes in the banner `Ingredient` and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `BlastingRecipe` now takes in the `Recipe$CommonInfo` and `$AbstractCookingRecipeCookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `BookCloningRecipe` now takes in the `Ingredient` source and material, the `MinMaxBounds$Int`s defining the generations that can be copied, and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `ALLOWED_BOOK_GENERATION_RANGES`, `DEFAULT_BOOK_GENERATION_RANGES` - Ranges for the book generation cloning. + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `CampfireCookingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `CraftingRecipe$CraftingBookInfo` - A record containing the common crafting information for the recipe book. + - `CustomRecipe` no longer takes in anything to its constructor + - `$Serializer` is removed, replaced by its implementation's codecs + - `DecoratedPotRecipe` now takes in the `Ingredient` patterns for each side along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `DyeRecipe` now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `Ingredient` target and dye and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkRocketRecipe` now takes in the `Ingredient` shell, fuel, and star along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkStarFadeRecipe` now takes in the `Ingredient` target and dye along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `FireworkStarRecipe` now takes in the `$Shape` to `Ingredient` map; the `Ingredient` trail, twinkle, fuel, and dye; along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `MapCloningRecipe` replaced with `TransmuteRecipe` + - `MapExtendingRecipe` now extends `CustomRecipe` instead of `ShapedRecipe` + - The constructor now takes in the `Ingredient` map and material along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `NormalCraftingRecipe` - A class that defines the standard implementation for a crafting recipe. + - `Recipe` + - `showNotification`, `group` are no longer default + - `$BookInfo` - The information for the recipe book. + - `$CommonInfo` - The common information across all recipes. + - `RecipeSerializer` is now a record containing the `MapCodec` and `StreamCodec` + - The registered entries have been moved to `RecipeSerializers` + - `register` is removed + - `RecipeSerializers` - All vanilla serializers for recipes. + - `RepairItemRecipe` no longer takes in anything + - `INSTANCE` - The recipe serializer singleton. + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `ShapedRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `ShapelessRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `ShieldDecorationRecipe` now takes in the `Ingredient` banner and target along with the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `SimpleSmithingRecipe` - A class that defines the standard implementation of a smithing recipe. + - `SingleItemRecipe` now takes in the `Recipe$CommonInfo` instead of the group + - `commonInfo` - The common information for the recipe. + - `$Factory#create` now takes in the `Recipe$CommonInfo` instead of the group + - `$Serializer` -> `simpleMapCodec`, `simpleStreamCodec`; not one-to-one + - `SmeltingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `SmithingTransformRecipe` now extends `SimpleSmithingRecipe` instead of implementing `SmithingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `SmithingTrimRecipe` now extends `SimpleSmithingRecipe` instead of implementing `SmithingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one + - `SmokingRecipe` now takes in the `Recipe$CommonInfo` and `AbstractCookingRecipe$CookingBookInfo` instead of the group and `CookingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `StonecutterRecipe` now takes in the `Recipe$CommonInfo` instead of the group + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `TippedArrowRecipe` -> `ImbueRecipe`, not one-to-one + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `Ingredient` source and material and the `ItemStackTemplate` result instead of the `CraftingBookCategory` + - `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER` - Serializers for the recipe. + - `TransmuteRecipe` now extends `NormalCraftingRecipe` instead of implementing `CraftingRecipe` + - The constructor now takes in the `Recipe$CommonInfo` and `CraftingRecipe$CraftingBookInfo` along with the `MinMaxBounds$Ints` and `boolean` handling the material count and adding it to the result instead of the group and `CraftingBookCategory` + - `$Serializer` -> `MAP_CODEC`, `STREAM_CODEC`, `SERIALIZER`; not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay` + - `$OnlyWithComponent` - A display only with the contents having the desired components. + - `$WithAnyPotion` - A display with the contents having any potion contents component. +- `net.minecraft.world.level.storage.loot.functions.SmeltItemFunction#smelted` now can take in whether to use the input material count + +### Dye Component + +Specifying whether an item can be used as a dye material is now handled through the `DYE` data component. The component specifies a `DyeColor`, which can be set via `Item$Properties#component`: + +```java +public static final Item EXAMPLE_DYE = new Item(new Item.Properties().component( + DataComponents.DYE, DyeColor.WHITE +)); +``` + +However, a dye material's behavior is not fully encompassed by the component alone. In most cases, the component is used in conjunction with some other tag or subclass to get the desired behavior. + +#### Entities and Signs + +Dying sheeps and signs are handled purely through the `DyeItem` subclass, checking if the item has the `DYE` component. + +Dying the collars of wolfs and cats, on the other hand, can be any item, assuming it has the `DYE` component. Additionally, the item must be in the `ItemTags#WOLF_COLLAR_DYES` or `ItemTags#CAT_COLLAR_DYES` tag, respectively. + +#### Dye Recipes + +The `DyeRecipe`, formerly named `ArmorDyeRecipe`, can take any target ingredient and apply the colors of the dye ingredients to obtain the desired result with the associated `DYED_COLOR` component. Any item can be considered a dye; however, those without the `DYE` component will default to `DyeColor#WHITE`. Armor makes used of `RecipeProvider#dyedItem` to allow any item in the `ItemTags#DYES` tag to dye armor. However, bundles and shulker boxes have their color components as different items, meaning instead the default recipes are tied directly to the vanilla `DyeItem`, meaning a separate recipe will need to be generated for applying dyes to those items. + +The loom, firework star, and firework star face recipes on the other hand expect any dye material to have the `DYE` component. The loom has an additional requirement of the item being in the `ItemTags#LOOM_DYES` tag. + +- `net.minecraft.core.component.DataComponents#DYE` - Represents that an item can act as a dye for the specific color. +- `net.minecraft.data.recipes.RecipeProvider` + - `dyedItem` - Creates a dyed item recipe. + - `dyedShulkerBoxRecipe` - Creates a dyed shulker box recipe. + - `dyedBundleRecipe` - Creates a dyed bundle recipe. +- `net.minecraft.world.item` + - `BundleItem` + - `getAllBundleItemColors`, `getByColor` are removed + - `DyeColor#VALUES` - A list of all dye colors. + - `DyeItem` no longer takes in the `DyeColor` + - `getDyeColor`, `byColor` are removed +- `net.minecraft.world.item.component.DyedItemColor#applyDyes` now takes in a list of `DyeColor`s instead of `DyeItem`s + - An overload can also take in a `DyedItemColor` component instead of the `ItemStack` +- `net.minecraft.world.item.crafting.ArmorDyeRecipe` -> `DyeRecipe`, not one-to-one +- `net.minecraft.world.item.crafting.display.SlotDisplay$DyedSlotDemo` - A display for demoing dying an item. +- `net.minecraft.world.level.block` + - `BannerBlock#byColor` is removed + - `ShulkerBoxBlock#getBlockByColor`, `getColoredItemStack` are removed + +### World Clocks and Time Markers + +World clocks are objects that represent some time that increases every tick from when the world first loads. These clocks are used as timers to properly handle timing-based events (e.g., the current day, sleeping). Vanilla provides two world clocks: one for `minecraft:overworld` and one for `minecraft:the_end`. + +Creating a clock is rather simple: just an empty, datapack registry object in `world_clock`. + +```json5 +// For some world clock 'examplemod:EXAMPLE_CLOCK' +// JSON at 'data/examplemod/world_clock/EXAMPLE_CLOCK.json' +{} +``` + +From there, you can query the clock state through the `ClockManager` via `Level#clockManager` or `MinecraftServer#clockManager`: + +```java +// For some Level level +// Assume we have some ResourceKey EXAMPLE_CLOCK + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Query the clock time +long ticksPassed = level.clockManager().getTotalTicks(clock); +``` + +If accessing the clock from the server, you can also modify the state of the clock: + +```java +// For some ServerLevel level +// Assume we have some ResourceKey EXAMPLE_CLOCK + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Get the server clock manager +ServerClockManager clockManager = level.clockManager(); + +// Set the total number of ticks that have passed +clockManager.setTotalTicks(clock, 0L); + +// Add the a certain value to the number of ticks +clockManager.addTicks(clock, 10L); + +// Pause the clock +clockManager.setPaused( + clock, + // `true` to pause. + // `false` to unpause. + true +); +``` + +#### Marking Timelines + +On its own, world clocks are rather limited in scope as you have to keep track of the number of ticks that have passed. However, when used with timelines, specific recurring times can be marked to handle timing-based events. + +As a refresher, `Timeline`s are a method of modifying attributes based on some `WorldClock`. Currently, all vanilla timelines use the `minecraft:overworld` world clock to keep track of their timing, via the `clock` field. All timelines must define a clock it uses; however, be aware that clocks to not support any synchronization by default, meaning that updating the time on one clock will not affect the other. + +```json5 +// For some timeline 'examplemod:example_timeline' +// In `data/examplemod/timeline/example_timeline.json +{ + // Uses the custom clock. + // Any changes to the clock time will only affect + // timelines using this clock. + // e.g., `minecraft:overworld` will not be changed. + "clock": "examplemod:example_clock", + // Perform actions on a 24,000 tick interval. + "period_ticks": "24000", + // ... +} + + +// For some timeline 'examplemod:example_timeline_2' +// In `data/examplemod/timeline/example_timeline_2.json +{ + // Uses the same clock as the one above. + // Changes to the clock time will affect both + // timelines. + "clock": "examplemod:example_clock", + // Perform actions on a 1,000 tick interval. + "period_ticks": "1000", + // ... +} + +// For some timeline 'examplemod:example_overworld' +// In `data/examplemod/timeline/example_overworld.json +{ + // Uses the vanilla overworld clock. + // Changes to the clock time will not affect + // the above timelines as they use a different + // clock. + "clock": "minecraft:overworld", + // Perform actions on a 6,000 tick interval. + "period_ticks": "6000", + // ... +} +``` + +Timelines can also define time markers, which is just some identifier for a time within the timeline period for a world clock. These are commonly used within commands (e.g. `/time set`), to check if a certain time has passed (e.g. village sieges), or to skip to the given time (e.g. waking up from sleep). Time markers are defined in `time_markers`, specifying the `ticks` within the period and whether it can be `show_in_commands`. As time markers are identified by their world clock, timelines using the same world clock cannot define the same time markers. + +```json5 +// For some timeline 'examplemod:example_timeline' +// In `data/examplemod/timeline/example_timeline.json +{ + // The identifier of the clock. + "clock": "examplemod:example_clock", + // Perform actions on a 24,000 tick interval. + "period_ticks": "24000", + // The markers within the period specified by the timeline + "time_markers": { + // A marker + "examplemod:example_marker": { + // The number of ticks within the period + // that this marker represents. + // e.g., 5000, 29000, 53000, etc. + "ticks": 5000, + // When true, allows the time marker to be + // suggested in the command. If false, + // the time marker can still be used in the + // command, it just won't be suggested. + "show_in_commands": true + } + } + // ... +} +``` + +Once the time markers are defined, they are registered for a world clock in the `ServerClockManager`, allowing them to be used given the `ResourceKey`. + +```java +// For some ServerLevel level +// Assume we have some ResourceKey EXAMPLE_CLOCK +// Assume we have some ResourceKey EXAMPLE_MARKER + +// Get the clock reference +Holder.Reference clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK); + +// Get the server clock manager +ServerClockManager clockManager = level.clockManager(); + +// Check if the time is at the specified marker +// This should be used when checking for a specific time event every tick +boolean atMarker = clockManager.isAtTimeMarker(clock, EXAMPLE_MARKER); + +// Skip to the time specified by the marker +// If the world clock is at 3000, sets the clock time to 5000 +// If the world clock is at 6000, sets the clock time to 29000 +// Returns whether the time was set, which is always true if the marker +// exists for the clock. +boolean timeSet = clockManager.skipToTimeMarker(clock, EXAMPLE_MARKER); +``` + +- `net.minecraft.client.ClientClockManager` - Manages the ticking of the world clocks on the client side. +- `net.minecraft.client.gui.components.debug.DebugEntryDayCount` - Displays the current day of the Minecraft world. +- `net.minecraft.client.multiplayer` + - `ClientLevel` + - `setTimeFromServer` no longer takes in the `long` day time nor the `boolean` of whether to tick the day time + - `$ClientLevelData#setDayTime` is removed + - `ClientPacketListener#clockManager` - Gets the client clock manager. +- `net.minecraft.client.renderer.EndFlashState#tick` now takes in the end clock time instead of the game time +- `net.minecraft.commands.arguments.ResourceArgument` + - `getClock` - Gets a reference to the world clock given the string resource identifier. + - `getTimeline` - Gets a reference to the timeline given the string resource identifier. +- `net.minecraft.core.registries.Registries#WORLD_CLOCK` - The registry identifier for the world clock. +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` + - `$TimeOfDay` -> `$ClockTime`, not one-to-one + - `$Timelines` - A test environment that uses a list of timelines. +- `net.minecraft.network.protocol.game.ClientboundSetTimePacket` now takes in a map of clocks to their network states instead of the day time `long` and `boolean` +- `net.minecraft.server` + - `MinecraftServer` + - `forceTimeSynchronization` -> `forceGameTimeSynchronization`, not one-to-one + - `clockManager` - The server clock manager. +- `net.minecraft.server.level.ServerLevel` + - `setDayTime`, `getDayCount` are removed + - `setEnvironmentAttributes` - Sets the environment attribute system to use. +- `net.minecraft.world.attribute.EnvironmentAttributeSystem$Builder#addTimelineLayer` now takes in the `ClockManager` instead of a `LongSupplier` +- `net.minecraft.world.clock` + - `ClockManager` - A manager that gets the total number of ticks that have passed for a world clock. + - `ClockNetworkState` - The current state of the clock to sync over the network. + - `ClockState` - The current state of the clock, including the total number of ticks and whether the clock is paused. + - `ClockTimeMarker` - A marker that keeps track of a certain period of time for a world clock. + - `ClockTimeMarkers` - All vanilla time markers. + - `PackedClockStates` - A map of clocks to their states, compressed for storage or other use. + - `ServerClockManager` - Manages the ticking of the world clocks on the server side. + - `WorldClock` - An empty record that represents a key for timing some location. + - `WorldClocks` - All vanilla world clocks. +- `net.minecraft.world.level` + - `Level` + - `getDayTime` -> `getOverworldClockTime`, not one-to-one + - `clockManager` - The clock manager. + - `getDefaultClockTime` - Gets the clock time for the current dimension. + - `LevelReader#getEffectiveSkyBrightness` - Gets the sky brightness with the current darkening factor. +- `net.minecraft.world.level.dimension.DimensionType` now takes in a default, holder-wrapped `WorldClock` +- `net.minecraft.world.level.storage` + - `LevelData#getDayTime` is removed + - `ServerLevelData` + - `setDayTime` is removed + - `setClockStates`, `clockStates` - Handles the current states of the world clocks. +- `net.minecraft.world.level.storage.loot.predicates.TimeCheck` now takes in a holder-wrapped `WorldClock` + - `time` now takes in a holder-wrapped `WorldClock` + - `$Builder` now takes in a holder-wrapped `WorldClock` +- `net.minecraft.world.timeline` + - `AttributeTrack#bakeSampler` now takes in a holder-wrapped `WorldClock` + - `AttributeTrackSampler` now takes in a holder-wrapped `WorldClock`, and a `ClockManager` instead of a `LongSupplier` for the day time getter + - `Timeline` now takes in a holder-wrapped `WorldClock` along with a map of time markers to their infos + - `#builder` now takes in a holder-wrapped `WorldClock` + - `getPeriodCount` - Gets the number of times a period has occurred within the given timeframe. + - `getCurrentTicks` now takes in the `ClockManager` instead of the `Level` + - `getTotalTicks` now takes in the `ClockManager` instead of the `Level` + - `clock` - Returns the holder-wrapped `WorldClock`. + - `registerTimeMarkers` - Registers all `ClockTimeMarker` defined in this timeline. + - `createTrackSampler` now takes in a `ClockManager` instead of a `LongSupplier` for the day time getter + - `$Builder#addTimeMarker` - Adds a time markers at the given tick, along with whether the marker can be suggested in commands. + - `Timelines#DAY` -> `OVERWORLD_DAY` + +### Splitting the Primary Level Data into Saved Data + +Some of the `WorldData` settings have been moved into `SavedData`, allowing for levels / dimensions to have more customizability. This addition also brings along some changes to how `SavedData` is referenced and queried. + +#### Saved Data Changes + +`SavedDataType` now identifies some `SavedData` using an `Identifier`, which is resolved against the data folder. This change allows subdirectories within the data folder, as the data storage will first create all missing parent directories before attempting to write the file. + +```java +public class ExampleData extends SavedData { + + public static final SavedDataType TYPE = new SavedDataType<>( + // The identifier for the saved data to resolve against + // Data can be found in: + // `/dimensions///data/examplemod/example/data.dat` + Identifier.fromNamespaceAndPath("examplemod", "example/data"), + // The constructor to create a new saved data + ExampleData::new, + // The codec to serialize the new saved data + MapCodec.unitCodec(ExampleData::new), + // The data fixer type + // Either some patched enum value or null depending on mod loader implementation. + null + ); +} +``` + +The `SavedData` can then be queried through the `SavedDataStorage`, renamed from `DimensionDataStorage`. This was renamed because the `MinecraftServer` instance now has its own data storage for global instances in addition to the levels. This means that any global saved data should be stored on the server instance rather than the overworld. + +```java +// Given a MinecraftServer server +ExampleData data = server.getDataStorage().computeIfAbsent(ExampleData.TYPE); + + +// Given a ServerLevel level +ExampleData data = level.getDataStorage().computeIfAbsent(ExampleData.TYPE); +``` + +#### Additional Saved Data + +The following information is now stored as saved data: + +- Custom boss events +- Ender dragon fight +- Game rules +- Wandering trader spawning +- Weather +- World generation settings + +Of these, only the ender dragon fight is on a per-level / dimension basis. The rest are still stored and accessed through the server data storage. Custom boss events, on the other hand, remain unique as it is up to the implementer to determine what players are part of the event. + +- `net.minecraft.client.Minecraft#doWorldLoad` now takes in the optional `GameRules` +- `net.minecraft.client.gui.screens.worldselection` + - `CreateWorldCallback` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` and the optional `GameRules` instead of the `PrimaryLevelData` + - `EditGameRulesScreen` -> `AbstractGameRulesScreen` + - Implementations in `.screens.options.InWorldGameRulesScreen` and `WorldCreationGameRulesScreen` + - `WorldOpenFlows` + - `createLevelFromExistingSettings` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` and the optional `GameRules` instead of the `WorldData` + - `loadWorldStem` now takes in the `LevelStorageSource$LevelStorageAccess` +- `net.minecraft.client.server.IntegratedServer` now takes in the optional `GameRules` +- `net.minecraft.server` + - `MinecraftServer` now takes in the optional `GameRules` + - `getGlobalGameRules` - Gets the game rules for the overworld dimension. + - `getWorldGenSettings` - Gets the generation settings for the world. + - `getWeatherData` - Gets the weather data for the server. + - `getDataStorage` - Gets the saved data storage for the server. + - `getGameRules` - Gets the game rules for the server. + - `WorldStem` now takes in the `LevelDataAndDimensions$WorldDataAndGenSettings` instead of the `WorldData` +- `net.minecraft.server.bossevents` + - `CustomBossEvent` now takes in a `UUID` for the identifier along with a `Runnable` for the callback + - `getTextId` -> `customId` + - `addOfflinePlayer` is removed + - `getValue` -> `value` + - `getMax` -> `max` + - `load` now takes in the `UUID` identifier along with a `Runnable` for the callback + - `CustomBossEvents` now extends `SavedData` + - `create` now takes in a `RandomSource` + - `save`, `load` -> `TYPE`, not one-to-one +- `net.minecraft.server.dedicated.DedicatedServer` now takes in the optional `GameRules` +- `net.minecraft.server.level` + - `ChunkMap#getChunkDataFixContextTag` now takes in an optional `Identifier` instead of a `ResourceKey` + - `ServerBossEvent` now takes in an `UUID` for the id + - `setDirty` - Marks the boss event as dirty for saving. + - `ServerLevel` no longer takes in the `RandomSequences` + - `setWeatherParameters` -> `MinecraftServer#setWeatherParameters` + - `getWeatherData` - Gets the weather data for the server. + - `getRandomSequence` -> `MinecraftServer#getRandomSequence` + - `getRandomSequences` -> `MinecraftServer#getRandomSequences` +- `net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner` now takes in the `SavedDataStorage` instead of the `ServerLevelData` + - `MIN_SPAWN_CHANCE` is now `public` from `private` +- `net.minecraft.world.entity.raid.Raids#TYPE_END`, `getType` are removed +- `net.minecraft.world.level` + - `Level#prepareWeather` is removed + - `LevelSettings` is now a record + - The constructor now takes in the `$DifficultySettings` instead of just the `Difficulty` + - `withDifficultyLock` - The settings with whether the difficulty is locked. + - `copy` - Copies the settings. + - `$DifficultySettings` - The settings for the difficulty. +- `net.minecraft.world.level.dimension.DimensionType` now takes in a `boolean` for whether the dimension can have an ender dragon fight +- `net.minecraft.world.level.dimension.end` + - `DragonRespawnAnimation` -> `DragonRespawnStage`, not one-to-one + - `EndDragonFight` -> `EnderDragonFight`, not one-to-one +- `net.minecraft.world.level.gamerules.GameRuleMap` now extends `SavedData` + - `TYPE` - The saved data type. + - `reset` - Resets the rule to its default value. +- `net.minecraft.world.level.levelgen.WorldGenSettings` is now a final class instead of a record, extending `SavedData` + - `encode`, `decode` replaced with `TYPE` + - `of` - Constructs the generation settings. +- `net.minecraft.world.level.saveddata` + - `SavedDataType` now takes in an `Identifier` instead of a string for the id + - `WanderingTraderData` - The saved data for the wandering trader. + - `WeatherData` - The saved data for the weather. +- `net.minecraft.world.level.storage` + - `DimensionDataStorage` -> `SavedDataStorage`, not one-to-one + - `LevelData#isThundering`, `isRaining`, `setRaining` now in `WeatherData` + - `LevelDataAndDimensions` now takes in a `$WorldDataAndGenSettings` instead of the `WorldData` + - `$WorldDataAndGenSettings` - Holds the world data and generation settings. + - `LevelResource` is now a record + - `PrimaryLevelData` fields have been moved to their respective saved data classes + - `PLAYER` -> `OLD_PLAYER` + - `SINGLEPLAYER_UUID` - A string that represents the UUID of the player in a singleplayer world. + - `WORLD_GEN_SETTINGS` -> `OLD_WORLD_GEN_SETTINGS` + - `writeLastPlayed` - Writes the last played player. + - `writeVersionTag` - Writes the data version tag. + - `ServerLevelData` + - `setThundering`, `getRainTime`, `setRainTime`, `setThunderTime`, `getThunderTime`, `getClearWeatherTime`, `setClearWeatherTime` moved to `WeatherData` + - `getWanderingTraderSpawnDelay`, `setWanderingTraderSpawnDelay`, `getWanderingTraderSpawnChance`, `setWanderingTraderSpawnChance`, `getWanderingTraderId`, `setWanderingTraderId` moved to `WanderingTraderData` + - `getLegacyWorldBorderSettings`, `setLegacyWorldBorderSettings` replaced by `WorldBorder` + - `getScheduledEvents` -> `MinecraftServer#getScheduledEvents` + - `getGameRules` replaced by `GameRuleMap` + - `WorldData` + - `getCustomBossEvents`, `setCustomBossEvents` replaced by `CustomBossEvents` + - `createTag` no longer takes in the `RegistryAccess` + - `getGameRules` replaced by `GameRuleMap` + - `getLoadedPlayerTag` -> `getSinglePlayerUUID`, not one-to-one + - `endDragonFightData`, `setEndDragonFightData` replaced by `EnderDragonFight` + - `worldGenOptions` replaced by `WorldGenSettings` saved data +- `net.minecraft.world.level.timers.TimerQueue` now extends `SavedData` + - The constructor now takes in the `$Packed` events instead of the `TimerCallbacks` and `Stream` of event data + - `store` replaced by `CODEC`, `TYPE`, `codec` + - `loadEvent`, `storeEvent` replaced by `$Event$Packed#codec` + - `$Event` is now a record + - `$Packed` - The packed event data. + - `$Packed` - The packed time queue. + +### Even More Rendering Changes + +#### Materials and Dynamic Layer Selection + +Block and item models now no longer specify what `RenderType` or `ChunkSectionLayer` they belong to. Instead, this is computed when loading the model, determing the associated layer for each quad. This means that `ItemBlockRenderTypes` is removed, with setting the `RenderType` for an item removed altogether. + +To determine what layer a quad or face gets set to, the `Transparency` of the texture is computed. Specifically, it checks that, for the UV area mapped to the quad, if there are any pixels that are transparent (have an alpha of 0), or translucent (have an alpha that is not 0 or 255). For the `ChunkSectionLayer`, `ChunkSectionLayer#TRANSLUCENT` is used if there is a translucent pixel, else `CUTOUT` is used if there is a transparent pixel, else `SOLID`. For the item `RenderType`, `Sheets#translucentItemSheet` and `translucentBlockItemSheet` for block items are used if there is a translucent pixel, or `cutoutItemSheet` and `cutoutBlockItemSheet` for block items. The `Transparency` also affects using `MipmapStrategy#AUTO`, using `CUTOUT` instead of `MEAN` as the default if there is a transparent pixel. + +One can influence a quad's `Transparency` through the `Material` texture defined by the model JSON. A `Material` specifies the texture's `sprite`, which represents the relative path to the texture, and optionally `force_translucent`, which forces any quad using this texture to use `Transparency#TRANSLUCENT` (transparent is false while translucent is true): + +```json5 +// For some model `examplemod:example_model` +// In: `assets/examplemod/models/example_model.json` +{ + "parent": "minecraft:block/template_glass_pane_post", + "textures": { + // A Material can be a simple texture reference + // Points to `assets/minecraft/textures/block/glass_pane_top.png` + "edge": "minecraft:block/glass_pane_top", + // Or it can be an object + "pane": { + // The relative texture reference for faces using this key + // Points to `assets/minecraft/textures/block/glass.png` + "sprite": "minecraft:block/glass", + // When true, sets all faces using this texture key to + // always have a transparent pixel. + "force_translucent": true + } + } + // ... +} +``` + +This change also defines the rendering order, where all solid quads are rendered first, followed by cutout quads, and finally translucent quads, sorted by distance from the camera. + +#### Materials and Sprites + +As you may have noticed, `Material`s were originally used to define some texture in an atlas. The addition of materials in texture JSONs have changed the naming of these classes. `Material`s now explicitly refer to texture references within model JSONs. This means that all references to the raw texture location have been replaced with `Material`, if unbaked, and `Material$Baked`, if baked. Additionally, the `SpriteGetter` is now `MaterialBaker`. + +As for the original `Material`, these are now known as sprites, where `Material` is renamed to `SpriteId`, and `MaterialSet` is renamed to `SpriteGetter`. + +#### Quad Particle Layers + +The `SingleQuadParticle$Layer`s have been split into `OPAQUE_*` and `TRANSLUCENT_*` layers, depending on if the particle texture used by the atlas contains a translucent pixel. Note that 'opaque' in this instance means cutout, where pixels with an alpha of less than 0.1 are discarded. If not creating a new layer, `$Layer#bySprite` can be used to determine what layer the particle texture should use. + +```java +public class ExampleParticle extends SingleQuadParticle { + + private final SingleQuadParticle.Layer layer; + + public SingleQuadParticle(ClientLevel level, double x, double y, double z, TextureAtlasSprite sprite) { + super(level, x, y, z, sprite); + this.layer = SingleQuadParticle.Layer.bySprite(sprite); + } + + @Override + protected SingleQuadParticle.Layer getLayer() { + return this.layer; + } +} +``` + +#### Block Models + +The pipeline for rendering individual block models outside of the general world context has been rewritten similarly to `ItemModel`s, where a 'block model' updates some render state, which then submits its elements for rendering. As such, most of the block model classes have been either rewritten or reorganized to a degree. + +Due to the block model name being synonymous with the model JSONs in general, many classes were moved and rename to separate the model JSONs, from the block state JSONs, from the now block models. As such, geometry for models that originally had 'block' in the name were changed to 'cuboid': (e.g., `BlockModel` -> `CuboidModel`, `BlockModelWrapper` -> `CuboidItemModelWrapper`). Additionally, parts of the rendering process referring to the definitions within a block state JSON were changed from 'block' to 'block state' (e.g., `BlockModelPart` -> `BlockStateModelPart`, `BlockModelDefinition` -> `BlockStateModelDispatcher`). You can consider most of the 'block model' classes to be new, with those renamed replacing the `SpecialBlockModelRenderer` system. + +The block model system starts from the `ModelManager` after all models and definitions are loaded and resolved, ready to be baked. Block models are loaded through `BuiltInBlockModels#crateBlockModels`, which links some `BlockState` to a `BlockModel$Unbaked`. Similarly to item models, the unbaked instance defines the properties of how the block model should be constructed. These are stored within `LoadedBlockModels`, to which they are then subsequently baked after all JSONs into `BlockModel`s via `bake`. This `BlockState` to `BlockModel` map is then stored within the `BlockModelSet`, ready to be queried through `get`, or more commonly through `BlockModelResolver#update`, which calls in the model set. Any models not defined lazily resolve to a wrapper around the `BlockStateModel`. + +Vanilla provides six `BlockModel` implementations for common usage. There is `EmptyBlockModel`, which submit no elements, and as such renders nothing; and `BlockStateModelWrapper`, which wraps around and displays the associated `BlockStateModel`. Then, there are equivalents for changing the model based on some property switch (`SelectBlockModel`), a conditional `boolean` (`ConditionalBlockModel`), and composing multiple models together (`CompositeBlockModel`). Finally, there is the `SpecialBlockModelWrapper`, which submits its elements through the stored `SpecialModelRenderer`, the unified submitter between item and block models. + +```java +// As the block model system is hardcoded through its in-code bootstrap, +// this example will assume there exists some method to get access to the +// `BuiltInBlockModels$Builder` builder. + +// We will also assume we have some Block EXAMPLE_BLOCK_* to attach the models to. + +// Regular block model +builder.put( + // A factory that takes in the `BlockColors` and `BlockState` to return + // a `BlockModel$Unbaked`. + (colors, state) -> new BlockStateModelWrapper.Unbaked( + // The state to get the `BlockStateModel` of. + state, + // The tint layers for the model. + colors.getTintSources(state), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(new Transformation(new Matrix4f().translation(0.5f, 0.5f, 0.5f))) + ), + // The block to use this model for. Will loop through a construct one + // per state. + EXAMPLE_BLOCK_1 +); + +// Block model switched on some property +builder.put( + (colors, state) -> new SelectBlockModel.Unbaked( + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(), + // A record containing the property to switch on, along with the + // values when a specific block model should be selected. + new SelectBlockModel.UnbakedSwitch<>( + // The `SelectBlockModelProperty` to switch on. The property + // value is determined from the `BlockState` and its `BlockDisplayContext`. + (state, displayContext) -> state.getRenderShape(), + // The list of cases to determine what `BlockModel` to use. + List.of( + new SelectBlockModel.SwitchCase<>( + // The list of values this model applies to. + List.of(RenderShape.INVISIBLE), + // The model to use when this property is met. + new EmptyBlockModel.Unbaked() + ) + ), + // An optional fallback if no switch case matches the state's + // property. + Optional.of(new EmptyBlockModel.Unbaked()) + ) + ), + EXAMPLE_BLOCK_2 +); + +// Block model based on some conditional +builder.put( + (colors, state) -> new ConditionalBlockModel.Unbaked( + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty(), + // The `ConditionalBlockModelProperty` that determines the + // `boolean` from the `BlockState`. + BlockState::isSignalSource, + // The model to display when the property returns `true`. + new EmptyBlockModel.Unbaked(), + // The model to display when the property returns `false`. + new EmptyBlockModel.Unbaked() + ), + EXAMPLE_BLOCK_3 +); + +// A composite block model +builder.put( + (colors, state) -> new CompositeBlockModel.Unbaked( + // The first model to display. + new EmptyBlockModel.Unbaked(), + // The second model to display. + new EmptyBlockModel.Unbaked(), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty() + ), + EXAMPLE_BLOCK_4 +); + +// Special block model +builder.put( + (colors, state) -> new SpecialBlockModelWrapper.Unbaked( + // The unbaked `SpecialModelRenderer` used to submit elements for the + // model. + new BellSpecialRenderer.Unbaked(), + // An optional transformation to apply to the `PoseStack` before + // submitting the model. + Optional.empty() + ), + EXAMPLE_BLOCK_5 +); +``` + +During the feature submission process, block models are handled through the `BlockModelResolver` and `BlockModelRenderState`. This is similar to how other render states work. First, `BlockModelResolver#update` sets up the `BlockModelRenderState`. Setup is handled through either the basic path -- `BlockModelRenderState#setupModel`, add the model parts to the returned list, then `setupTints`, or through `setupSpecialModel` for the special renderers. Then, the render state submits its elements for rendering through `BlockModelRenderState#submit`. The render state also provides `submitOnlyOutline` which uses the outline render type, and `submitWithZOffset` which uses the sold entity forward Z-offset render type. + +```java +// BlockEntity example +public class ExampleRenderState extends BlockEntityRenderState { + // Hold the render state. + public final BlockModelRenderState exampleBlock = new BlockModelRenderState(); +} + +public class ExampleRenderer implements BlockEntityRenderer { + + // The display context for use in the block entity renderer. + public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create(); + private final BlockModelResolver blockResolver; + + public ExampleRenderer(BlockEntityRendererProvider.Context ctx) { + super(ctx); + // Get the model resolver. + this.blockResolver = ctx.blockModelResolver(); + } + + @Override + public void extractRenderState(ExampleBlockEntity blockEntity, ExampleRenderState state, float partialTick, Vec3 cameraPosition, ModelFeatureRenderer.CrumblingOverlay breakProgress) { + super.extractRenderState(blockEntity, state, partialTick, cameraPosition, breakProgress); + + // Update the model state. + this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT); + } + + @Override + public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) { + super.submit(state, pose, collector, camera); + + // Submit the model state for rendering. + state.exampleBlock.submit( + // The current pose stack, + pose, + // The node collector. + collector, + // The light coordinates. + state.lightCoords, + // The overlay coordinates. + OverlayTexture.NO_OVERLAY, + // The outline color. + 0 + ); + + + } +} + +// Entity example +public class ExampleRenderState extends EntityRenderState { + // Hold the render state. + public final BlockModelRenderState exampleBlock = new BlockModelRenderState(); +} + +public class ExampleRenderer extends EntityRenderer { + + // The display context for use in the entity renderer. + public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create(); + private final BlockModelResolver blockResolver; + + public ExampleRenderer(EntityRendererProvider.Context ctx) { + super(ctx); + // Get the model resolver. + this.blockResolver = ctx.getBlockModelResolver(); + } + + @Override + public void extractRenderState(ExampleEntity entity, ExampleRenderState state, float partialTick) { + super.extractRenderState(entity, state, partialTick); + + // Update the model state. + this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT); + } + + @Override + public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) { + super.submit(state, pose, collector, camera); + + // Submit the model state for rendering. + state.exampleBlock.submit( + // The current pose stack. + pose, + // The node collector. + collector, + // The light coordinates. + state.lightCoords, + // The overlay coordinates. + OverlayTexture.NO_OVERLAY, + // The outline color. + state.outlineColor + ); + } +} +``` + +#### Block Tint Sources + +`BlockColor` has been completely replaced by `BlockTintSource`, which sets the ARGB tint of a particular index based on the desired context. There are three contexts a tint source can provide: + +- `color` for the general context, used by `BlockModel`s +- `colorInWorld` for the world context, used by `ModelBlockRenderer#tesselateBlock` +- `colorAsTerrainParticle` for the particle context, used by the falling dust and terrain particle + +In addition, `BlockTintSource` provides a `relevantProperties` if the `Property`s of a `BlockState` are used to determine what color to tint. This is used by the `LevelRenderer` to determine whether a change in state requires a model to be re-rendered. + +`BlockTintSource`s are still registered to `BlockColors` via `register`, taking in a list of sources followed by the vararg of blocks. The `tintindex` specfied in the model JSON is used to index into the tint source list. + +```java +// Assume access to BlockColors colors +colors.register( + // The list of tints to apply to some block model. + List.of( + // "tintindex": 0 + (state) -> 0xFFFF0000, + // "tintindex": 1 + new BlockTintSource() { + + @Override + public int color(BlockState state) { + return 0xFF00FF00; + } + + @Override + public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) { + return 0xFF0000FF; + } + } + ), + // The blocks these tint sources will apply to. + EXAMPLE_BLOCK_1 +); +``` + +#### Removing the Old Block and Item Renderers + +Since `ItemModel`s and `BlockModel` are now fully handled through their own feature submission pipeline, `BlockRenderDispatcher` and `ItemRenderer` have been completely removed, replaced by the corresponding systems. + +#### Object Definition Transformations + +`ItemModel`s and `BlockModel`s can now take in an optional `Transformation`, which transforms how the model should be displayed. As such, the `$Unbaked#bake` methods now take in the parent `Matrix4fc` transformation, to which the transformation is multiplied to via `Transformation#compose`. For item models, this is known as a local transform separate from the model JSON item transform. The local transforms are always applied after the item transform. + +Note that adding support for transformations should always be done through `Transformation#compose` as the matrices passed around are mutable by nature. Assume any custom methods not performed through a vanilla interface should copy before performing any modifications. + +#### Quad Instance + +The brightness / tint color, lightmap, and overlay coordinates have been consolidated into a single object: `QuadInstance`. The mutable class sets its values through its associated `set*` methods, and can pull the information for each quad vertex via the `get*` methods. Brightness and tinting are stored together as the color, rather them being two separate values. + +`QuadInstance` does not replace all usecases, such as when adding a single vertex. It only updates methods for the `VertexConsumer`, splitting `putBulkData` into `putBlockBakedQuad` for quads in block models, and `putBakedQuad` for all other uses. + +In addition, mmany methods used to upload `BakedQuad`s to a buffer now take in a `BlockQuadOutput`. This has the same parameters as `VertexConsumer#putBlockBakedQuad`, and was added due to the section renderer uploading to a newly allocated `BufferBuilder` for use with the uber buffer. + +#### Gui Extractor + +GUI classes methods have gone through a massive renaming scheme, indicating that the submitted elements are 'extracted' into a general tree to be submitted and then rendered. As such, methods that began with `draw*` or `render*` are now prefixed with `extract*`, and potentially suffixed with `*RenderState` (e.g., `Renderable#render` -> `extractRenderState`, `AbstractContainerScreen#renderLabels` -> `extractLabels`, `AbstractWidget#renderWidget` -> `extractWidgetRenderState`). Some shorthands were also expanded, either by renamining or replacing the method with another (e.g., `AbstractContainerScreen#renderBg` replaced by `Screen#extractBackground`). + +`GuiGraphics` was also renamed to `GuiGraphicsExtractor` in the same fashion. The methods follow similar patterns to the rest of the GUI changes (e.g. `hline` -> `horizontalLine`), except that `draw*`, `render*`, and `submit*` prefixes along with `*RenderState` suffixes are removed (e.g. `renderOutline` -> `outline`, `submitEntityRenderState` -> `entity`). The only rename is that `*String*` method names are replaced with `*Text*`. + +#### Fluid Models + +Defining a fluid's textures and tint has now been moved out of the `FluidRenderer` (previously `LiquidBlockRenderer`) and into its own separate `FluidModel` record. Initially, given the small number of fluids, the unbaked variants (`FluidModel$Unbaked`) are stored as constants. Then, after `BlockModel` have been baked, the fluid models are baked via `FluidStateModelSet#bake`, linking a `Fluid` to its `FluidModel`. This map is then stored within the `FluidStateModelSet`, ready to be queried through `get`. + +A `FluidModel$Unbaked` has four arguments: three `Material`s for the still, flowing, and optional overlay textures; and one for the `BlockTintSource`. The tint is obtained via `BlockTintSource#colorInWorld`. During the baking process, it will determine the `ChunkSectionLayer` based on the transparency of the provided materials. + +```java +// As the fluid model system is hardcoded within its baking, this example +// will assume there exists some method to get modifiable access to the +// `Map` fluidModels returned by `FluidStateModelSet#bake`. + +// We will also assume we have some Fluid EXAMPLE_FLUID* to attach the models to. + +FluidModel.Unbaked exampleFluidModel = new FluidModel.Unbaked( + // The texture for the still fluid. + new Material( + // The relative identifier for the texture. + // Points to `assets/examplemod/textures/block/example_fluid_still.png` + Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_still"), + // When true, sets all faces using this texture key to + // always have a transparent pixel. + true + ), + // The texture for the flowing fluid. + new Material(Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_flowing")), + // If not null, the texture for the overlay when the side of the fluid is + // occluded by a `HalfTransparentBlock` or `LeavesBlock`. + null, + // If not null, the tint source to apply to the fluid's texture when in + // the world. + null +); + +// Assume we have access to the `MaterialBaker` materials. + +FluidModel exampleBakedFluidModel = exampleFluidModel.bake( + // The baker to grab the atlas sprites for the materials. + materials, + // A supplied debug name to properly report which models have + // missing textures. + () -> "examplemod:example_fluid_model" +); + +fluidModels.put( + // The fluid the model should be used by. + EXAMPLE_FLUID, + // The baked fluid model. + exampleBakedFluidModel +); +fluidModels.put(EXAMPLE_FLUID_FLOWING, exampleBakedFluidModel); +``` + +#### Name Tag Offsets + +`EntityRenderer#submitNameTag` has been renamed to `submitNameDisplay`, now optionally taking in the y offset from the name tag attachment. + +#### Tint Getter + +`BlockAndTintGetter` is now a client only interface attached to the `ClientLevel`. It previous uses were replaced with `BlockAndLightGetter` -- which `BlockAndTintGetter` now extends -- with the tint and lighting directions stripped. + +#### Pipeline Depth and Color + +Depth and color methods defined in the `RenderPipeline` have been consolidated into two state objects. + +The `DepthTestFunction`, write `boolean`, and the bias `float`s are now stored in `DepthStencilState`. `DepthTestFunction` has been replaced with a more generic `CompareOp`, which defines how to compare two numbers. Each function has an simple equivalent, with `NO_DEPTH_TEST` replaced by `CompareOp#ALWAYS_PASS`. The depth information can be added to the pipeline via `RenderPipeline$Builder#withDepthStencilState`. + +The optional `BlendFunction` and color / alpha `boolean`s are now stored in `ColorTargetState`. The `boolean`s are consolidated into an `int` using the lower four bits as flags: `1` is red, `2` is green, `4` is blue, and `8` is alpha. The color `boolean` uses `7` for red, green, and blue; the alpha `boolean` uses `8`; while both combined use `15`. The `LopicOp` is removed entirely. The color information can be added to the pipeline via `RenderPipeline$Builder#withColorTargetState`. + +```java +public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder() + .withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example")) + .withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + .withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example")) + .withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS) + .withShaderDefine("ALPHA_CUTOUT", 0.5) + .withSampler("Sampler0") + .withUniform("ModelOffset", UniformType.VEC3) + .withUniform("CustomUniform", UniformType.INT) + .withPolygonMode(PolygonMode.FILL) + .withCull(false) + // Sets the color target when writing the buffer data. + .withColorTargetState(new ColorTargetState( + // Specifies the functions to use when blending two colors with alphas together. + // Made up of the `SourceFactor` and `DestFactor`. + // First two are for RGB, the last two are for alphas. + // If the optional is empty, then blending is disabled. + Optional.of(BlendFunction.TRANSLUCENT), + // The mask determining what colors to write to the buffer. + // Represented as a four bit value + // 0001 - Write the red channel.. + // 0010 - Write the green channel. + // 0100 - Write the blue channel. + // 1000 - Write the alpha channel. + ColorTargetState.WRITE_RED | ColorTargetState.WRITE_GREEN | ColorTargetState.WRITE_BLUE | ColorTargetState.WRITE_ALPHA + )) + // Sets the depth stencil when writing the buffer data. + .withDepthStencilState(new DepthStencilState( + // Sets the depth test function to use when rendering objects at varying + // distances from the camera. + // Values: + // - ALWAYS_PASS (GL_ALWAYS) + // - LESS_THAN (GL_LESS) + // - LESS_THAN_OR_EQUAL (GL_LEQUAL) + // - EQUAL (GL_EQUAL) + // - NOT_EQUAL (GL_NOTEQUAL) + // - GREATER_THAN_OR_EQUAL (GL_GEQUAL) + // - GREATER_THAN (GL_GREATER) + // - NEVER_PASS (GL_NEVER) + CompareOp.LESS_THAN_OR_EQUAL, + // Whether to mask writing values to the depth buffer + false, + // The scale factor used to calculate the depth values for the polygon. + 0f, + // The unit offset used to calculate the depth values for the polygon. + 0f + )) + .build() +; +``` + +#### Blaze3d Backends + +`CommandEncoder`, `GpuDevice`, and `RenderPassBackend` has been split into the `*Backend` interface, which functions similarly to the previous interface, and the wrapper class, which holds the backend and provides delegate calls, performing any validation necessary. The `*Backend` interfaces now explicitly perform the operation without checking whether the operation is valid. + +#### Solid and Translucent Features + +Feature rendering has been further split into two passes: one for solid render types, and one for translucent render types. As such, most `render` methods now have a `renderSolid` and `renderTranslucent` method, respectively. Those which only render solid or translucent data only have one of the methods. + +#### Camera State + +The `Camera` has been updated similarly to other render state implementations where the camera is extracted to the `CameraRenderState` during `GameRenderer#renderLevel`, and that is passed around with the data required to either submit and render elements. + +Due to this change, `FogRenderer#setupFog` now returns the `FogData`, containing all the information needed to render the fog, instead of just its color, and storing that in `CameraRenderState#fogData`. + +- Some shaders within `assets/minecraft/shaders/core` now use `texture` over `texelFetch` + - `entity.vsh` + - `item.vsh` + - `rendertype_leash.vsh` + - `rendertype_text.vsh` + - `rendertype_text_background.vsh` + - `rendertype_text_intensity.vsh` +- `assets/minecraft/shaders/core` + - `block.vsh#minecraft_sample_lightmap` -> `sample_lightmap.glsl#sample_lightmap` + - `rendertype_crumbling` no longer takes in `texCoord2` (lightmap) + - `rendertype_entity_alpha`, `rendertype_entity_decal` merged into `entity.fsh` using a `DissolveMaskSampler` + - `rendertype_item_entity_translucent_cull` -> `item`, not one-to-one + - `rendertype_translucent_moving_block` is removed + - This now uses the the shaders provided by the `ChunkSectionLayer` +- `com.mojang.blaze3d` + - `GLFWErrorCapture` - Captures errors during a GL process. + - `GLFWErrorScope` - A closable that defines the scope of the GL errors to capture. +- `com.mojang.blaze3d.opengl` + - `GlProgram#BUILT_IN_UNIFORMS`, `INVALID_PROGRAM` are now final + - `GlBackend` - A GPU backend for OpenGL. + - `GlCommandEncoder` now implements `CommandEncoderBackend` instead of `CommandEncoder`, the class now package-private + - `getDevice` is removed + - `GlConst#toGl` now takes in a `CompareOp` instead of the `DepthTestFunction` + - `GlDevice` now implements `GpuDeviceBackend` instead of `GpuDevice`, the class now package-private + - The constructor now takes in a `GpuDebugOptions` containing the log level, whether to use synchronous logs, and whether to use debug labels instead of those parameters being passed in directly + - `GlRenderPass` now implements `RenderPassBackend` instead of `RenderPass`, the class now package-private + - The constructor now takes in the `GlDevice` + - `GlStateManager#_colorMask` now takes an `int` for the color mask instead of four `boolean`s +- `com.mojang.blaze3d.platform` + - `ClientShutdownWatchdog` now takes in the `Minecraft` instance + - `DebugMemoryUntracker#untrack` is removed + - `GLX#make(T, Consumer)` is removed + - `NativeImage` + - `computeTransparency` - Returns whether there is at least one transparent or translucent pixel in the image. + - This crashes if the image's area is greater than 512MiB, or 2GiB with color data. + - `isClosed` - Whether the image is closed or deallocated. + - `Transparency` - An object of whether some image has a translucent and/or transparent pixel. + - `Window` now takes the `GpuBackend` instead of the `ScreenManager` + - `createGlfwWindow` - Directly creates the GLFW window with the provided settings. + - `updateDisplay` -> `updateFullscreenIfChanged`, not one-to-one + - `isResized`, `resetIsResized` - Handles whether the window has been resized. + - `backend` - Returns the `GpuBackend`. + - `$WindowInitFailed` constructor is now `public` from `private` + - `WindowEventHandler#resizeDisplay` -> `resizeGui` +- `com.mojang.blaze3d.pipeline` + - `ColorTargetState` - A record containing the blend function and mask for the color. + - `DepthStencilState` - A record containing the data for the depth stencil. + - `RenderPipeline` now takes in the `ColorTargetState` instead of the optional `BlendFunction`, color and alpha `boolean`s, and `LogicOp`; and the `DepthStencilState` instead of the `DepthTestFunction`, depth `boolean`, and bias `float`s + - `getDepthTestFunction`, `isWriteDepth`, `getDepthBiasScaleFactor`, `getDepthBiasConstant` -> `getDepthStencilState`, not one-to-one + - `getColorLogic`, `getBlendFunction`, `isWriteColor`, `isWriteAlpha` -> `getColorTargetState`, not one-to-one + - `$Builder` + - `withDepthTestFunction`, `withDepthWrite`, `withDepthBias` -> `withDepthStencilState`, not one-to-one + - `withBlend`, `withColorWrite`, `withColorLogic` -> `withColorTargetState`, not one-to-one + - `$Snippet` now takes in the `ColorTargetState` instead of the optional `BlendFunction`, color and alpha `boolean`s, and `LogicOp`; and the `DepthStencilState` instead of the `DepthTestFunction` and depth `boolean` +- `com.mojang.blaze3d.platform` + - `BackendOptions` - A configuration for initializing the backend with. + - `DepthTestFunction` -> `CompareOp`, not one-to-one + - `NO_DEPTH_TEST` -> `CompareOp#ALWAYS_PASS` + - `EQUAL_DEPTH_TEST` -> `CompareOp#EQUAL` + - `LEQUAL_DEPTH_TEST` -> `CompareOp#LESS_THAN_OR_EQUAL` + - `LESS_DEPTH_TEST` -> `CompareOp#LESS_THAN` + - `GREATER_DEPTH_TEST` -> `CompareOp#GREATER_THAN` + - `GLX` + - `_initGlfw` now takes in the `BackendOptions` + - `glfwBool` - `1` if `true`, `0` if `false`. + - `LogicOp` enum is removed +- `com.mojang.blaze3d.shaders.GpuDebugOptions` - The debug options for the GPU pipeline. +- `com.mojang.blaze3d.systems` + - `BackendCreationException` - An exception thrown when the GPU backend couldn't be created. + - `CommandEncoder` -> `CommandEncoderBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `GpuBackend` - An interface responsible for creating the used GPU device and window to display to. + - `GpuDevice` -> `GpuDeviceBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `setVsync` - Sets whether VSync is enabled. + - `presentFrame` - Swaps the front and back buffers of the window to display the present frame. + - `isZZeroToOne` - Whether the 0 to 1 Z range is used instead of -1 to 1. + - `RenderPass` -> `RenderPassBackend` + - The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks + - `RenderSystem` + - `pollEvents` is now public + - `flipFrame` no longer takes in the `Window` + - `initRenderer` now only takes in the `GpuDevice` + - `limitDisplayFPS` -> `FramerateLimiter#limitDisplayFPS` + - `initBackendSystem` now takes in the `BackendOptions` +- `com.mojang.blaze3d.vertex` + - `DefaultVertexFormat#BLOCK` no longer takes in the normal vector + - `PoseStack#mulPose`, `$Pose#mulPose` now has an overload that takes in the `Transformation` + - `QuadInstance` - A class containing the color, light coordinates, and overlay of a quad. + - `TlsfAllocator` - A two-level segregate fit allocator for dynamic memory allocation. + - `UberGpuBuffer` - A buffer for uploading dynamically sized data to the GPU, used for chunk section layers. + - `VertexConsumer` + - `putBulkData` -> `putBlockBakedQuad`, `putBakedQuad`; not one-to-one + - Brightness `float` array, color `float`s, lightmap `int` array, and overlay `int` are replaced with `QuadInstance` + - `putBlockBakedQuad` replaces the `PoseStack$Pose` with the XYZ `float` block position + - `addVertex(PoseStack$Pose, Vector3f)` -> `addVertex(PoseStack$Pose, Vector3fc)` + - `setNormal(PoseStack$Pose, Vector3f)` -> `setNormal(PoseStack$Pose, Vector3fc)` +- `com.mojang.math` + - `MatrixUtil` + - `checkPropertyRaw` is now `public` from `private` + - `isOrthonormal` is removed + - `Transformation` + - `IDENTITY` is now `public` from `private` + - Replaces `identity` method + - `getTranslation` -> `translation` + - `getLeftRotation` -> `leftRotation` + - `getScale` -> `scale` + - `getRightRotation` -> `rightRotation` + - `compose` - Applies the transformation to the given matrix, if present. +- `net.minecraft.SharedConstants` + - `DEBUG_DUMP_INTERPOLATED_TEXTURE_FRAMES` is removed + - `DEBUG_PREFER_WAYLAND` - When true, prevents the platform initialization hint from being set to X11 if both Wayland and X11 are supported. +- `net.minecraft.client` + - `Camera` + - `BASE_HUD_FOV` - The base hud field-of-view. + - `setup` -> `update`, not one-to-one + - `extractRenderState` - Extract the state of the camera. + - `getFov` - Gets the field-of-view. + - `getViewRotationMatrix` - Gets the matrix for a projection view. + - `setEntity` - Sets the entity the camera is attached to. + - `getNearPlane` now takes in the `float` field-of-view + - `panoramicForwards` - The forward vector when in panorama mode. + - `getPartialTickTime` is removed + - `setLevel` - Sets the level the camera is in. + - `getCameraEntityPartialTicks` - Gets the partial tick based on the state of the entity. + - `DeltaTracker#advanceTime` replaced by `advanceGameTime` when the `boolean` was `true`, and `advanceRealTime` + - `advanceGameTime`, `advanceRealTime` were previously `private`, now `public` + - `FramerateLimiter` - A utility for limiting the framerate of the client. + - `Minecraft` + - `noRender` is removed + - `useAmbientOcclusion` is removed + - `getBlockRenderer` is removed + - `getItemRenderer` is removed + - `Options` + - `getCloudsType` -> `getCloudStatus` + - `exclusiveFullscreen` - When `true`, fullscreen mode takes full control of the monitor. +- `net.minecraft.client.color.block` + - `BlockColor` replaced by `BlockTintSource`, not one-to-one + - `getColor` -> `colorInWorld`, `colorAsTerrainParticle`; not one-to-one + - `BlockColors` + - `getColor` replaced by `getTintSources`, `getTintSource`; not one-to-one + - `register` now takes in a list of `BlockTintSource`s instead of a `BlockColor` + - `BlockTintSource` - A source for how to tint a `BlockState` in isolation or with context. + - `BlockTintSources` - Utilites for common block tint sources. +- `net.minecraft.client.data.models` + - `BlockModelGenerators` + - `createSuffixedVariant` now takes in a function of `Material` to `TextureMapping` for the textures instead of just an `Identifier` + - `createAirLikeBlock` now takes in a `Material` instead of an `Identifier` for the particle texture + - `generateSimpleSpecialItemModel` now takes in an optional `Transformation` + - `createChest` now has an overload that takes in the `MutiblockChestResources` textures + - `ItemModelGenerators#generateLayeredItem` now takes in `Material`s instead of `Identifier`s for the textures +- `net.minecraft.client.data.models.model` + - `ItemModelUtils` + - `specialModel` now has overloads that take in the `Transformation` + - `conditional` now has overloads that take in the `Transformation` + - `select` now has an overload that takes in the `Transformation` + - `selectBlockItemProperty` now has an overload that takes in the `Transformation` + - `TexturedModel#createAllSame` now takes in a `Material` instead of an `Identifier` for the texture + - `TextureMapping` + - `put`, `putForced` now take in a `Material` instead of an `Identifier` for the texture + - `get` now returns a `Material` instead of an `Identifier` for the texture + - `copyAndUpdate` now takes in a `Material` instead of an `Identifier` for the texture + - `updateSlots` - Replaces all slots using the provided mapper function. + - `forceAllTranslucent` - Sets the force translucency flag for all material textures. + - `defaultTexture`, `cube`, `cross`, `plant`, `rail`, `wool`, `crop`, `singleSlot`, `particle`, `torch`, `cauldron`, `layer0` now take in a `Material` instead of an `Identifier` for the texture + - `column`, `door`, `layered` now take in `Material`s instead of `Identifier`s for the textures + - `getBlockTeture`, `getItemTexture` now return a `Material` instead of an `Identifier` for the texture +- `net.minecraft.client.entity.ClientAvatarEntity#belowNameDisplay` -> `Entity#belowNameDisplay` +- `net.minecraft.client.gui` + - `Font` + - `drawInBatch`, `drawInBatch8xOutline` now take in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `$GlyphVisitor#forMultiBufferSource` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `Gui` + - `render*` methods have been renamed to `extract*` + - `render` -> `extractRenderState` + - `$RenderFunction` interface is removed + - `GuiGraphics` -> `GuiGraphicsExtractor` + - `hLine` -> `horizontalLine` + - `vLine` -> `verticalLine` + - `renderOutline` -> `outline` + - `drawCenteredString` -> `centeredText` + - `drawString` -> `text` + - `drawStringWithBackdrop` -> `textWithBackdrop` + - `renderItem` -> `item` + - `renderFakeItem` -> `fakeItem` + - `renderItemDecorations` -> `itemDecorations` + - `submitMapRenderState` -> `map` + - `submitEntityRenderState` -> `entity` + - `submitSkinRenderState` -> `skin` + - `submitBookModelRenderState` -> `book` + - `submitBannerPatternRenderState` -> `bannerPattern` + - `submitSignRenderState` -> `sign` + - `submitProfilerChartRenderState` -> `profilerChart` + - `renderTooltip` -> `tooltip` + - `renderComponentHoverEffect` -> `componentHoverEffect`, now `private` instead of `public` +- `net.minecraft.client.gui.components` + - Most methods that begin with `render*` or `draw*` have been renamed to either `extract*` or `extract*RenderState` depending on usage. + - `AbstractWidget#renderWidget` -> `extractWidgetRenderState` + - `DebugScreenOverlay#render3dCrosshair` now takes in the `CameraRenderState` instead of the `Camera`, and the gui scale `int` + - `LogoRenderer#renderLogo` -> `extractRenderState` + - `PlayerFaceRenderer` -> `PlayerFaceExtractor` + - `draw` -> `extractRenderState` + - `Renderable#render` -> `extractRenderState` + - `StringWidget#clipText` -> `ComponentRenderUtils#clipText` + - `TextCursorUtils#draw*` -> `extract*` +- `net.minecraft.client.gui.components.debugchart` + - `AbstractDebugChart` + - `drawChart` -> `extractRenderState` + - `drawDimensions` -> `extractSampleBars` + - `drawMainDimension` -> `extractMainSampleBar` + - `drawAdditionalDimensions` -> `extractAdditionalSampleBars` + - `renderAdditionalLinesAndLabels` -> `extractAdditionalLinesAndLabels` + - `drawStringWithShade` -> `extractStringWithShade` + - `ProfilerPieChart#render` -> `extractRenderState` +- `net.minecraft.client.gui.components.spectator.SpectatorGui#render*` -> `extract*` +- `net.minecraft.client.gui.components.toasts` + - `NowPlayingToast#renderToast` -> `extractToast` + - `Toast#render` -> `extractRenderState` + - `ToastManager`, `$ToastInstance#render` -> `extractRenderState` + - `TutorialToast$Icons#render` -> `extractRenderState` +- `net.minecraft.client.gui.contextualbar.ContextualBarRenderer` + - `renderBackground` -> `extractBackground` + - `render` -> `extractRenderState` + - `renderExperienceLevel` -> `extractExperienceLevel` +- `net.minecraft.client.gui.font` + - `PlainTextRenderable#renderSprite` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `TextRenderable#render` now takes in a `Matrix4fc` instead of a `Matrix4f` for the pose +- `net.minecraft.client.gui.render` + - `DynamicAtlasAllocator` - An allocator for handling a dynamically sized texture atlas. + - `GuiItemAtlas` - An atlas for all items displayed in a user interface. + - `GuiRenderer#incrementFrameNumber` -> `endFrame`, not one-to-one +- `net.minecraft.client.gui.render.state.*` -> `.client.rendererer.state.gui.*` + - `GuiItemRenderState` no longer takes in the `String` name + - `name` is removed +- `net.minecraft.client.gui.render.state.pip.*` -> `.client.rendererer.state.gui.pip.*` +- `net.minecraft.client.gui.screens` + - `LevelLoadingScreen#renderChunks` -> `extractChunksForRendering` + - `Screen` + - `renderWithTooltipAndSubtitles` -> `extractRenderStateWithTooltipAndSubtitles` + - `renderBackground` -> `extractBackground` + - `renderBlurredBackground` -> `extractBlurredBackground` + - `renderPanorama` -> `extractPanorama` + - `renderMenuBackground` -> `extractMenuBackground` + - `renderMenuBackgroundTexture` -> `extractMenuBackgroundTexture` + - `renderTransparentBackground` -> `extractTransparentBackground` +- `net.minecraft.client.gui.screens.advancements` + - `AdvancementTab#draw*` -> `extract*` + - `AdvancementTabType` + - `draw` -> `extractRenderState` + - `drawIcon` -> `extractIcon` + - `AdvancementWidget` + - `draw` -> `extractRenderState` + - `draw*` -> `extract*` +- `net.minecraft.client.gui.screens.inventory` + - Most methods that begin with `render*` or `draw*` have been renamed to either `extract*` or `extract*RenderState` depending on usage. + - `AbstractContainerScreen` + - `renderContents` -> `extractContents` + - `renderCarriedItem` -> `extractCarriedItem` + - `renderSnapbackItem` -> `extractSnapbackItem` + - `renderSlots` -> `extractSlots` + - `renderTooltip` -> `extractTooltip` + - `renderLabels` -> `extractLabels` + - `renderBg` replaced by `Screen#extractBackground` + - `renderSlot` -> `extractSlot` + - `AbstractMountInventoryScreen#drawSlot` -> `extractSlot` + - `AbstractSignEditScreen#renderSignBackground` -> `extractSignBackground` + - `CyclingSlotBackground#render` -> `extractRenderState` + - `EffectsInInventory#render` -> `extractRenderState` + - `InventoryScreen#renderEntityInInventoryFollowsMouse` -> `extractEntityInInventoryFollowsMouse` + - `ItemCombinerScreen#renderErrorIcon` -> `extractErrorIcon` +- `net.minecraft.client.gui.screens.inventory.tooltip` + - `ClientTooltipComponent` + - `renderText` -> `extractText` + - `renderImage` -> `extractImage` + - `TooltipRenderUtil#renderTooltipBackground` -> `extractTooltipBackground` +- `net.minecraft.client.gui.screens.options` + - `DifficultyButtons` is now a record that takes in the `LayoutElement`, `CycleButton` for the difficulty, the `LockIconButton`, and the current `Level` + - `create` now takes in the `Level` and returns the `DifficultyButtons` instead of a `LayoutElement` + - `refresh` - Sets the data of the held button components. + - `HasDifficultyReaction` - An interface that responds to when the difficulty has changed. + - `OptionsScreen` now implements `HasDifficultyReaction` + - `WorldOptionsScreen` now implements `HasDifficultyReaction` + - The constructor now takes in the `Level` +- `net.minecraft.client.gui.screens.recipebook` + - `GhostSlots` + - `render` -> `extractRenderState` + - `renderTooltip` -> `extractTooltip` + - `RecipeBookComponent#render*` -> `extract*` + - `RecipeBookPage` + - `render` -> `extractRenderState` + - `renderTooltip` -> `extractTooltip` +- `net.minecraft.cilent.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#renderItem` -> `extractItem` +- `net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen$GameRuleEntry#renderLabel` -> `extractLabel` +- `net.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon` -> `extractIcon` +- `net.minecraft.client.model.Model#renderType` now has an overload that returns the passed in function +- `net.minecraft.client.model.object.book.BookModel$State` no longer takes in the animation pos, and moves the open `float` to the first parameter + - `forAnimation` - Gets the current state of the animation for the book based on the progress. +- `net.minecraft.client.model.object.statue.CopperGolemStatueModel` now uses `Unit` for the generic instead of `Direction` +- `net.minecraft.client.multiplayer.ClientLevel` now implements `BlockAndTintGetter` + - `update` - Updates the lighting of the level. +- `net.minecraft.client.multiplayer.chat.GuiMessageTag$Icon#draw` -> `extractRenderState` +- `net.minecraft.client.particle` + - `Particle#getLightColor` -> `getLightCoords` + - `SimpleVerticalParticle` - A particle that moves vertically. + - `SingleQuadParticle$Layer` + - `TERRAIN` -> `OPAQUE_TERRAIN`, `TRANSLUCENT_TERRAIN` + - `ITEMS` -> `OPAQUE_ITEMS`, `TRANSLUCENT_ITEMS` + - `bySprite` - Gets the layer from the atlas sprite. +- `net.minecraft.client.renderer` + - `CachedOrthoProjectionMatrixBuffer`, `CachedPerspectiveProjectionMatrixBuffer`, `PerspectiveProjectionMatrixBuffer` -> `ProjectionMatrixBuffer` with sometimes `Projection`, not one-to-one + - `CloudRenderer` now takes in the cloud range `int` + - `CubeMap` no longer takes in the `Minecraft` instance + - `GameRenderer` now takes in the `ModelManager` instead of the `BlockRenderDispatcher` + - `PROJECTION_Z_NEAR` -> `Camera#PROJECTION_Z_NEAR` + - `setPanoramicScreenshotParameters`, `getPanoramicScreenshotParameters` -> `Camera#enablePanoramicMode`, `disablePanoramicMode`; not one-to-one + - `isPanoramicMode` -> `Camera#isPanoramicMode` + - `getProjectionMatrix` -> `Camera#getViewRotationProjectionMatrix`, not one-to-one + - `updateCamera` -> `Camera#update`, not one-to-one + - `getRenderDistance` is removed + - `cubeMap` -> `GuiRenderer#cubeMap`, now `private` from `protected` + - `getDarkenWorldAmount` -> `getBossOverlayWorldDarkening` + - `lightTexture` -> `lightmap`, `levelLightmap`; not one-to-one + - `getLevelRenderState` replaced by `getGameRenderState`, returning the `GameRenderState` instead of the `LevelRenderState` + - `pick` -> `Minecraft#pick`, now `private` from `public` + - `render` split between `update`, `extract`, and `render`; with the `boolean` now taking in whether to advance the game time rather than render the level + - `GlobalSettingsUniform` now takes in the `Vec3` camera position instead of the main `Camera` itself + - `ItemBlockRenderTypes` is removed + - `getChunkRenderType`, `getMovingBlockRenderType` now stored within `BakedQuad$SpriteInfo` + - `getRenderLayer(FluidState)` -> `FluidModel#layer`, not one-to-one + - `setCutoutLeaves` is removed + - This should be obtained directly from the options + - `MultiblockChestResources` - A record containing some data based on the `ChestType`. + - `LevelRenderer` now takes in the `GameRenderState` instaed of the `LevelRenderState` + - `update` - Updates the level. + - `renderLevel` now takes in the `CameraRenderState` instead of the `Camera`, a `Matrix4fc` instead of a `Matrix4f` from the model view, and the `ChunkSectionsToRender`; it no longer takes in the `Matrix3f` for the projection matrices + - `extractLevel` - Extracts the level state. + - `prepareChunkRenders` is now `public` instead of `private` + - `captureFrustum`, `killFrustum`, `getCapturedFrustum` are removed + - `getLightColor` -> `getLightCoords`, now taking in the `BlockAndLightGetter` instead of the `BlockAndTintGetter` + - `$BrightnessGetter#packedBrightness` now takes in the `BlockAndLightGetter` instead of the `BlockAndTintGetter` + - `LightTexture` -> `Lightmap` + - `tick` -> `LightmapRenderStateExtractor#tick` + - `updateLightTexture` -> `render` + - `pack` -> `LightCoordsUtil#pack` + - `block` -> `LightCoordsUtil#block` + - `sky` -> `LightCoordsUtil#sky` + - `lightCoordsWithEmission` -> `LightCoordsUtil#lightCoordsWithEmission` + - `MaterialMapper` -> `SpriteMapper` + - `OrderedSubmitNodeCollector` + - `submitBlock` is removed + - `submitBlockModel` now takes in a list of `BlockStateModelPart`s instead of the `BlockStateModel`, and an array of `int`s (array of tint colors) instead of three `float`s for a single color + - `submitItem` no longer takes in the `RenderType` + - `submitModel` now has overloads that takes in the `Identifier` for the texture, or a `SpriteId` with the `SpriteGetter` along with an `int` tint color + - `submitBreakingBlockModel` - Submits the block breaking overlay. + - `PanoramaRenderer` replaced by `Panorama` + - `registerTextures` -> `GuiRenderer#registerPanoramaTextures` + - `render` -> `extractRenderState` + - `PanoramicScreenshotParameters` record is removed + - `PostChain` now takes in a `Projection` and `ProjectionMatrixBuffer` instead of an `CachedOrthoProjectionMatrixBuffer` + - `load` now takes in a `Projection` and `ProjectionMatrixBuffer` instead of an `CachedOrthoProjectionMatrixBuffer` + - `RenderPipelines` + - `ENTITY_CUTOUT_NO_CULL` -> `ENTITY_CUTOUT` + - The original cutout with cull is replaced by `ENTITY_CUTOUT_CULL` + - `ENTITY_CUTOUT_NO_CULL_Z_OFFSET` -> `ENTITY_CUTOUT_Z_OFFSET` + - `ENTITY_SMOOTH_CUTOUT` -> `END_CRYSTAL_BEAM` + - `ENTITY_NO_OUTLINE` replaced by `ENTITY_TRANSLUCENT`, render type constructed with affects outline being false + - `ENTITY_DECAL`, `DRAGON_EXPLOSION_ALPHA` -> `ENTITY_CUTOUT_DISSOLVE`, not one-to-one + - `ITEM_ENTITY_TRANSLUCENT_CULL` -> `ENTITY_TRANSLUCENT_CULL`, `ITEM_CUTOUT`, `ITEM_TRANSLUCENT`; not one-to-one + - `TRANSLUCENT_MOVING_BLOCK` replaced by `TRANSLUCENT_BLOCK` + - `BANNER_PATTERN` - A pipeline for rendering the patterns on a banner. + - `ScreenEffectRenderer#renderScreenEffect` now takes in `boolean`s for whether the player is in first person and whether to hide the GUI + - `Sheets` + - `*CHEST_*LOCATION*` have been combined into one of the `CHEST_*` fields based on what the resource was for + - `translucentBlockSheet` - A cullable entity item translucent render type using the block atlas. + - `cutoutBlockItemSheet` - An item cutout render type using the block atlas. + - `bannerSheet` -> `RenderTypes#entityTranslucent`, not one-to-one + - `cutoutItemSheet` - An item cutout render type using the item atlas. + - `get*Material` -> `get*Sprite` + - `chooseMaterial` -> `chooseSprite` + - `SpecialBlockModelRenderer` replaced by `BuiltInBlockModels`, not one-to-one + - `renderByBlock` -> `BlockModelRenderState#submit*`, not one-to-one + - `SubmitNodeCollection` + - `getBlockSubmits` is removed + - `getBreakingBlockModelSubmits` - Gets the submitted breaking block overlay. + - `SubmitNodeCollector$ParticleGroupRenderer` + - `isEmpty` - Whether there are no particles to render in this group. + - `prepare` now takes whether the particles are being prepared for the translucent layer + - `render` no longer takes in the translucent `boolean` + - `SubmitNodeStorage` + - `$BlockModelSubmit` now takes in a list of `BlockStateModelPart`s instead of the `BlockStateModel`, and an array of `int`s (array of tint colors) instead of three `float`s for a single color + - `$BlockSubmit` is removed + - `$BreakingBlockModelSubmit` - A record containing the information to render the block breaking overlay. + - `$ItemSubmit` no longer takes in the `RenderType` + - `$MovingBlockSubmit`, `$NameTagSubmit`, `$ShadowSubmit`, `$TextSubmit` now take in a `Matrix4fc` instead of a `Matrix4f` for the pose + - `VirtualScreen` replaced by `GpuBackend` +- `net.minecraft.client.renderer.block` + - `BlockAndTintGetter` - A getter for positional block tinting (e.g., biomes). + - `BlockModelRenderState` - The render state for a block model. + - `BlockModelResolver` - A helper for setting up the render state for a `BlockState`. + - `BlockModelSet` - Holds the `BlockModel` associated with each `BlockState`. + - `BlockModelShaper` -> `BlockStateModelSet`, not one-to-one + - `getParticleIcon` -> `getParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `getBlockModel` -> `get` + - `getModelManager`, `replaceCache` are removed + - `BlockQuadOutput` - A functional interface for writing the baked quad information to some output, like a buffer. + - `BlockRenderDispatcher` class is removed + - `getBlockModelShaper` -> `getModelSet`, not one-to-one + - `renderBreakingTexture` replaced with `SubmitNodeCollector#submitBreakingBlockModel` + - `renderBatched` replaced with direct call to `ModelBlockRenderer#tesselateBlock` + - `renderLiquid` replaced with direct call to `FluidRenderer#tesselate` + - `renderSingleBlock` is now inlined within `BlockFeatureRenderer#renderBlockModelSubmits`, a `private` method + - Use `ModelBlockRenderer#tesselateBlock` as an alternative + - `FluidModel` - The base fluid model that holds the data for the renderer. + - `FluidStateModelSet` - Holds the `FluidModel` associated with each `Fluid`. + - `LoadedBlockModels` - A task for baking the `BlockModel` for each `BlockState`. + - `LiquidBlockRenderer` -> `FluidRenderer`, not one-to-one + - The constructor now takes in the `FluidStateModelSet` instead of the `SpriteGetter` + - `tesselate` now takes in a `FluidRenderer$Output` instead of a `VertexConsumer` + - `$Output` - Gets the `VertexConsumer` to use for the `ChunkSectionLayer`. + - `ModelBlockRenderer` now takes in `boolean`s for ambient occlusion and culling + - `tesselateBlock` now takes in a `BlockQuadOutput` instead of a `VertexConsumer`, the XYZ `float`s instead of a `PoseStack`, the `BlockStateModel` instead of the list of `BlockModelPart`s, no longer takes in the cull `boolean` and `int` overlay, and takes in the seed `long` + - `tesselateWithAO` -> `tesselateAmbientOcclusion`, now `private` instead of `public` + - `tesselateWithoutAO` -> `tesselateFlat`, now `private` instead of `public` + - `renderModel` is now inlined within `BlockFeatureRenderer#renderBlockModelSubmits`, a `private` method + - `forceOpaque` - Whether the block textures should be opaque instead of translucent. + - `enableCaching` -> `BlockModelLighter$Cache#enable` + - `clearCache` -> `BlockModelLighter$Cache#disable` + - `$AdjacencyInfo` -> `BlockModelLighter$AdjacencyInfo`, now `private` instead of `protected` + - `$AmbientOcclusionRenderStorage` is replaced by `BlockModelLighter`, not one-to-one + - `$AmbientVertexRemap` -> `BlockModelLighter$AmbientVertexRemap` + - `$Cache` -> `BlockModelLighter$Cache` + - `$CommonRenderStorage` is replaced by `BlockModelLighter`, not one-to-one + - `$SizeInfo` -> `BlockModelLighter$SizeInfo` + - `MovingBlockRenderState#level` -> `cardinalLighting`, `lightEngine`; not one-to-one + - `SelectBlockModel` - A block model that determined or selected by its resolved property. +- `net.minecraft.client.renderer.block.model` + - `BakedQuad` -> `.client.resources.model.geometry.BakedQuad` + - The constructor now takes in a `$MaterialInfo` instead of the `TextureAtlasSprite`, `int` tint index, `int` light emission, and `boolean` shade + - `FLAG_TRANSLUCENT` - A flag that marks the baked quad has having translucency. + - `FLAG_ANIMATED` - A flag that marks the baked quad has having an animated texture. + - `isTinted` -> `$MaterialInfo#isTinted` + - `$MaterialFlags` - An annotation that marks whether a given integer defines the flags for a material. + - `$MaterialInfo` - A record holding the information on how to render the quad. + - `BlockDisplayContext` - An object that represents the display context of a block. + - `BlockElement` -> `.client.resources.model.cuboid.CuboidModelElement` + - `BlockElementFace` -> `.client.resources.model.cuboid.CuboidFace` + - `BlockElementRotation` -> `.client.resources.model.cuboid.CuboidRotation` + - `BlockModel` - The base block model that updates the render state for use outside the world context. + - The original implementation has been moved to `.client.resources.model.cuboid.CuboidModel` + - `BlockModelDefinition` -> `.block.dispatch.BlockStateModelDispatcher` + - `BlockModelPart` -> `.block.dispatch.BlockStateModelPart` + - `particleIcon` -> `particleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `materialFlags` - Handles the flags for the material(s) used by the model. + - `BlockStateModel` -> `.block.dispatch.BlockStateModel` + - `particleIcon` -> `particleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `materialFlags`, `hasMaterialFlag` - Handles the flags for the material(s) used by the model. + - `BlockStateModelWrapper` - The basic block model that contains the model, tints, and transformation. + - `CompositeBlockModel` - Overlays multiple block models together. + - `ConditionalBlockModel` - A block model that shows a different model based on a boolean obtained from some property. + - `EmptyBlockModel` - A block model that shows nothing. + - `FaceBakery` -> `.client.resources.model.cuboid.FaceBakery` + - `bakeQuad` overload now takes in a `ModelBaker` instead of the `ModelBaker$PartCache`, and a `Material$Baked` instead of a `TextureAtlasSprite` + - It also has an overload taking in the fields of the `BlockElementFace` instead of the object itself + - Another `bakedQuad` ovrload now takes in the `BakedQuad$MaterialInfo` instead of the `int` tint index and light emission, and the shade `boolean` + - `ItemModelGenerator` -> `.client.resources.model.cuboid.ItemModelGenerator` + - `ItemTransform` -> `.client.resources.model.cuboid.ItemTransform` + - `ItemTransforms` -> `.client.resources.model.cuboid.ItemTransforms` + - `SimpleModelWrapper` -> `.client.resources.model.SimpleModelWrapper` + - The constructor now takes in a `Material$Baked` instead of a `TextureAtlasSprite` for the particle + - `SimpleUnbakedGeometry` -> `.client.resources.model.cuboid.UnbakedCuboidGeometry` + - `SingleVariant` -> `.block.dispatch.SingleVariant` + - `SpecialBlockModelWrapper` - A block model for models that submit their elements through `SpecialModelRenderer`s. + - `TextureSlots` -> `.client.resources.model.sprite.TextureSlots` + - `Variant` -> `.block.dispatch.Variant` + - `VariantMutator` -> `.block.dispatch.VariantMutator` + - `VariantSelector` -> `.block.dispatch.VariantSelector` +- `net.minecraft.client.renderer.block.model.multipart.*` -> `.block.dispatch.multipart.*` +- `net.minecraft.client.renderer.block.model.properties.conditional` + - `ConditionalBlockModelProperty` - A property that computes some `boolean` from the `BlockState`. + - `IsXmas` - Returns whether the current time is between December 24th - 26th. +- `net.minecraft.client.renderer.block.model.properties.select` + - `DisplayContext` - A case based on the current `BlockDisplayContext`. + - `SelectBlockModelProperty` - A property that computes some switch state from the `BlockState`. +- `net.minecraft.client.renderer.blockentity` + - `AbstractEndPortalRenderer` + - `renderCube` -> `submitCube`, now `protected` and `static` from `private` + - `submitSpecial` - Submits the end portal cube, used by the special renderer. + - `getExtents` - Gets the vertices of each face. + - `getOffsetUp`, `getOffsetDown` are removed + - `renderType` is removed + - `AbstractSignRenderer` now takes in a generic for the `SignRenderState` + - `getSignModel` now takes in the `SignRenderState` generic instead of the `BlockState` and `WoodType` + - `getSignModelRenderScale`, `getSignTextRenderScale`, `getTextOffset`, `translateSign` replaced by `SignRenderState#transformations`, `SignRenderState$SignTransformations` + - `getSignMaterial` -> `getSignSprite` + - `BannerRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `submitPatterns` no longer takes in the base `SpriteId`, whether the pattern has foil, and the outline color + - `submitSpecial` now takes in the `BannerBlock$AttachmentType` + - `BedRenderer` + - `submitSpecial` is removed + - This is replaced by calling `submitPiece` twice, or making a composite for each bed part via the `BedSpecialRenderer` + - `submitPiece` is now `public` from `private`, taking in the `BedPart` instead of the `Model$Simple`, `Direction`, or the `boolean` of whether to translate in the Z direction + - `getExtents` now takes in the `BedPart` + - `modelTransform` - Gets the transformation for the given `Direction`. + - `BlockEntityRenderDispatcher` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher`, and no longer takes in the `ItemRenderer` + - `prepare` now takes in a `Vec3` camera position instead of the `Camera` itself + - `BlockEntityRendererProvider$Context` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher`, and no longer takes in the `ItemRenderer` + - `materials` -> `sprites` + - `ChestRenderer` + - `LAYERS` - Holds the model layers of the chest. + - `modelTransformation` - Gets the transformation for the given `Direction`. + - `ConduitRenderer#DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `CopperGolemStatueBlockRenderer#modelTransformation` - Gets the transformation for the given `Direction`. + - `DecoratedPotRenderer#modelTransformation` - Gets the transformation for the given `Direction`. + - `HangingSignRenderer` now uses a `HangingSignRenderState` + - `MODEL_RENDER_SCALE` is now `private` from `public` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `translateBase` -> `baseTransformation`, now `private` from `public` + - `$AttachmentType` -> `HangingSignBlock$Attachment` + - `byBlockState` -> `$Models#get` + - `$ModelKey` record is removed + - `ShulkerBoxRenderer` + - `modelTransform` - Gets the transformation for the given `Direction`. + - `getExtents` no longer takes in the `Direction` + - `SignRenderer` -> `StandingSignRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `createSignModel` now takes in a `PlainSignBlock$Attachment` instead of a `boolean` for whether the block is standing + - `SkullBlockRenderer` + - `TRANSFORMATIONS` - The transformations to apply when on the wall or ground. + - `submitSkull` no longer takes in the `Direction` or `float` rotation + - `WallAndGroundTransformations` - A class that holds a map of `Direction`s to transforms to apply for the wall, and an `int` function to compute the ground transformations, with the `int` segments generally acting as the number of rotation states. +- `net.minecraft.client.renderer.blockentity.state` + - `BannerRenderState` + - `angle` -> `transformation`, not one-to-one + - `standing` -> `attachmentType`, not one-to-one + - `BedRenderState#isHead` -> `part`, not one-to-one + - `BlockEntityRenderState#blockState` is now `private` from `public` + - `ChestRenderState#angle` -> `facing`, not one-to-one + - `CondiutRenderState` -> `ConduitRenderState` + - `CopperGolemStatueRenderState#oxidationState` - The current oxidation state. + - `HangingSignRenderState` - The render state for the hanging sign. + - `ShelfRenderState#facing` - The direction the shelf is facing. + - `SignRenderState#woodType` - The type of wood the sign is made of. + - `SkullblockRenderState#direction`, `rotationDegrees` -> `transformation`, not one-to-one + - `StandingSignRenderState` - The render state for the standing sign. +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer` now takes in a `boolean` for whether the layer is translucent rather than just sorting on upload + - `byTransparency` - Gets the layer by its transparency setting. + - `sortOnUpload` -> `translucent`, not one-to-one + - `vertexFormat` - The vertex format of the pipeline used by the layer. + - `ChunkSectionsToRender#drawsPerLayer` -> `drawGroupsPerLayer`, with its value being a `int` to list of draws map + - `CompiledSectionMesh` + - `uploadMeshLayer` replaced by `isVertexBufferUploaded`, `setVertexBufferUploaded` + - `uploadLayerIndexBuffer` replaced by `isIndexBufferUploaded`, `setIndexBufferUploaded` + - `RenderRegionCache#createRegion` now takes in the `ClientLevel` instead of the `Level` + - `SectionBuffers` -> `SectionRenderDispatcher$RenderSectionBufferSlice`, not one-to-one + - `SectionCompiler` now takes in the `boolean`s for ambient occlusion and cutout leaves, the `BlockStateModelSet`, the `FluidStateModelSet`, and the `BlockColors` instead of the `BlockRenderDispatcher` + - `SectionMesh` + - `getBuffers` -> `getSectionDraw`, not one-to-one + - `$SectionDraw` - The draw information for the section. + - `SectionRenderDispatcher` now takes in the `SectionCompiler` instead of the `BlockRenderDispatcher` and `BlockEntityRenderDispatcher` + - `getRenderSectionSlice` - Gets the buffer slice of the section mesh to render for the chunk layer. + - `uploadAllPendingUploads` -> `uploadGlobalGeomBuffersToGPU`, not one-to-one + - `lock`, `unlock` - Handles locking the dispatcher when copying data from location to another, usually for GPU allocation. + - `getToUpload` is removed + - `setLevel` now takes in the `SectionCompiler` + - `$RenderSection` + - `upload`, `uploadSectionIndexBuffer` -> `addSectionBuffersToUberBuffer`, now private + - `$CompileTask` + - `doTask` now returns a `$SectionTaskResult` instead of a `CompletableFuture` + - `$SectionTaskResult` -> `$RenderSection$CompileTask$SectionTaskResult` +- `net.minecraft.client.renderer.culling.Frustum` now takes in a `Matrix4fc` instead of a `Matrix4f` for the model view + - `set` - Copies the information from another frustum. +- `net.minecraft.client.renderer.entity` + - `AbstractBoatRenderer` now takes in the `Identifier` texture + - `renderType` is removed + - `AbstractMinecartRenderer` + - `BLOCK_DISPLAY_CONTEXT` - The context of how to display the block inside the minecart. + - `submitMinecartContents` now takes in a `BlockModelRenderState` instead of the `BlockState` + - `CopperGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the antenna block. + - `DisplayRenderer` + - `BLOCK_DISPLAY_CONTEXT` - The context of how to display the displayed block. + - `blockModelResolver` - The block model resolver. + - `EndermanRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the held block. + - `EntityRenderDispatcher` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher` + - `EntityRenderer#submitNameTag` -> `submitNameDisplay`, now optionally taking in the y position `int` as an offset from the name tag attachment + - `EntityRendererProvider$Context` now takes in the `BlockModelResolver` instead of the `BlockRenderDispatcher` + - `getMaterials` -> `getSprites` + - `getBlockRenderDispatcher` replaced by `getBlockModelResolver` + - `IronGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the held block. + - `ItemFrameRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the displayed block. + - `ItemRenderer` class is removed + - Use the `ItemStackRenderState` to submit elements to the feature dispatcher instead + - `ENCHANTED_GLINT_ARMOR` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ARMOR` + - `ENCHANTED_GLINT_ITEM` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ITEM` + - `NO_TINT` -> `ItemFeatureRenderer#NO_TINT` + - `getFoilBuffer` -> `ItemFeatureRenderer#getFoilBuffer` + - `getFoilRenderType` -> `ItemFeatureRenderer#getFoilRenderType`, now `public` from `private` + - `MushroomCowRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the attached blocks. + - `SnowGolemRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the head block. + - `TntRenderer#BLOCK_DISPLAY_CONTEXT` - The context of how to display the TNT block. + - `TntMinecartRenderer#submitWhiteSolidBlock` now takes in a `BlockModelRenderState` instead of the `BlockState` +- `net.minecraft.client.renderer.entity.layers` + - `BlockDecorationLayer` now takes in a function that returns a `BlockModelRenderState` instead of an optional `BlockState` + - `MushroomCowMushroomLayer` no longer takes in the `BlockRenderDispatcher` + - `SnowGolemHeadLayer` no longer takes in the `BlockRenderDispatcher` +- `net.minecraft.client.renderer.entity.state` + - `AvatarRenderState#scoreText` -> `EntityRenderState#scoreText` + - `BlockDisplayEntityRenderState#blockRenderState` -> `blockModel`, now a `BlockModelRenderState` instead of a `BlockRenderState` + - `CopperGolemRenderState#blockOnAntenna` now a `BlockModelRenderState` instead of an optional `BlockState` + - `EndermanRenderState#carriedBlock` now a `BlockModelRenderState` instead of a nullable `BlockState` + - `IronGolemRenderState#flowerBlock` - The flower held by the iron golem. + - `ItemFrameRenderState#frameModel` - The model of the item frame block. + - `MinecartRenderState#displayBlockState` -> `displayBlockModel`, now a `BlockModelRenderState` instead of a `BlockState` + - `MushroomCowRenderState#mushroomModel` - The model of mushrooms attached to the cow. + - `SnowGolemRenderState#hasPumpkin` -> `headBlock`, now a `BlockModelRenderState` instead of a `boolean` + - `TntRenderState#blockState` now a `BlockModelRenderState` instead of a nullable `BlockState` +- `net.minecraft.client.renderer.features` + - Feature `render` methods have been split into `renderSolid` for solid render types, and `renderTranslucent` for see-through render types + - Some `render*` methods now take in the `OptionsRenderState` + - `BlockFeatureRenderer` + - `renderSolid` now takes in the `BlockStateModelSet` instead of the `BlockRenderDispatcher` + - `renderTranslucent` now takes in the `BlockStateModelSet` and the crumbling `MultiBufferSource$BufferSource` instead of the `BlockRenderDispatcher` + - `FeatureRenderDispatcher` now takes in the `GameRenderState` and `ModelManager` + - `renderAllFeatures` has been split into `renderSolidFeatures` and `renderTranslucentFeatures` + - The original method now calls both of these methods, first solid then translucent + - `clearSubmitNodes` - Clears the submit node storage. + - `renderTranslucentParticles` - Renders collected translucent particles. + - `FlameFeatureRenderer#render` -> `renderSolid` + - `LeashFeatureRenderer#render` -> `renderSolid` + - `NameTagFeatureRenderer#render` -> `renderTranslucent` + - `ShadowFeatureRenderer#render` -> `renderTranslucent` + - `TextFeatureRenderer#render` -> `renderTranslucent` +- `net.minecraft.client.renderer.fog` + - `FogData#color` - The color of the fog. + - `FogRenderer` + - `setupFog` now returns a `FogData` instead of the `Vector4f` fog color + - `updateBuffer` - Updates the buffer with the fog data. +- `net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives#render` now takes in a `Matrix4fc` instead of a `Matrix4f` for the model view +- `net.minecraft.client.renderer.item` + - `BlockModelWrapper` -> `CuboidItemModelWrapper` + - The constructor no longer takes in the `RenderType` function, and now takes in the `Matrix4fc` transformation + - `$Unbaked` now takes in an optional `Transformation` + - `CompositeModel$Unbaked` now takes in an optional `Transformation` + - `ConiditionalItemModel$Unbaked` now takes in an optional `Transformation` + - `ItemModel` + - `$BakingContext` + - `materials` -> `sprites` + - `missingItem` - Gets the missing item model with the given `Matrix4fc` transformation. + - `$Unbaked#bake` now takes in the `Matrix4fc` transformation from any parent client items + - `ItemStackRenderState` + - `pickParticleIcon` -> `pickParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `$LayerRenderState` + - `EMPTY_TINTS` - An `int` array representing no tints to apply. + - `setRenderType` is removed + - `setParticleIcon` -> `setParticleMaterial`, now taking a `Material$Baked` instead of a `TextureAtlasSprite` + - `setTransform` -> `setItemTransform` + - `setLocalTransform` - Sets the client item transform that's applied after item display transforms. + - `prepareTintLayers` -> `tintLayers`, not one-to-one + - `MissingItemModel#withTransform` - Gets a missing item model with the given transform. + - `ModelRenderProperties#particleIcon` -> `particleMaterial`, now taking a `Material$Baked` instead of a `TextureAtlasSprite` + - `RangeSelectItemModel$Unbaked` now takes in an optional `Transformation` + - `SelectItemModel` + - `$ModelSelector#get` no longer supports nullable `ItemModel`s. + - `$Unbaked` now takes in an optional `Transformation` + - `$UnbakedSwitch#bake` now takes in the `Matrix4fc` transformation + - `SpecialModelWrapper` now takes in the `Matrix4fc` transformation + - `$Unbaked` now takes in an optional `Transformation` +- `net.minecraft.client.renderer.rendertype` + - `RenderType#outputTarget` - Gets the output target. + - `RenderTypes` + - `MOVING_BLOCK_SAMPLER` replaced by `createMovingBlockSetup`, now `private` + - `entityCutoutNoCull` -> `entityCutout` + - The original cutout with cull is replaced by `entityCutoutCull` + - `entityCutoutNoCullZOffset` -> `entityCutoutZOffset` + - `entitySmoothCutout` -> `endCrystalBeam` + - `entityNoOutline` -> `entityTranslucent` with `affectsOutline` as `false` + - `entityDecal`, `dragonExplosionAlpha` -> `entityCutoutDissolve`, not one-to-one + - `itemEntityTranslucentCull` -> `entityTranslucentCullItemTarget`, `itemCutout`, `itemTranslucent`; not one-to-one + - `bannerPattern` - The render type for rendering the patterns of banners. +- `net.minecraft.client.renderer.special` + - `BannerSpecialRenderer`, `$Unbaked` now take in the `BannerBlock$AttachmentType` + - `$Unbaked` now uses `BannerPatternLayers` for the generic + - `BedSpecialRenderer`, `$Unbaked` now take in the `BedPart` + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `BellSpecialRenderer` - A special renderer for the bell. + - `BookSpecialRenderer` - A special renderer for the book on the enchantment table. + - `ChestSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `ChestType` + - `*_CHEST_TEXTURE` is removed from the field name, now a `MultiBlockChestResources` + - `ENDER_CHEST_TEXTURE` -> `ENDER_CHEST` + - `ConduitSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `CopperGolemStatueSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `DecoratedPotSpecialRenderer$Unbaked` now uses `PotDecorations` for the generic + - `EndCubeSpecialRenderer` - A special renderer for the end portal cube. + - `HangingSignSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `HangingSignBlock$Attachment` + - `NoDataSpecialModelRenderer` + - `submit` no longer takes in the `ItemDisplayContext` + - `$Unbaked` - The unbaked renderer for a special model renderer not needing extracted data. + - `PlayerHeadSpecialRenderer$Unbaked` now uses `PlayerSkinRenderCache$RenderInfo` for the generic + - `ShieldSpecialRenderer` + - `DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `$Unbaked` now uses `DataComponentMap` for the generic + - `ShulkerBoxSpecialRenderer`, `$Unbaked` no longer takes in the `Direction` orientation + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `SkullSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - `SpecialModelRenderer` + - `submit` no longer takes in the `ItemDisplayContext` + - `$BakingContext` + - `materials` -> `sprites` + - `$Simple` replaced by `BlockModel$BakingContext`, `ItemModel$BakingContext` + - `materials` -> `sprites` + - `$Unbaked` now has the generic of the argument to extract from the representing object + - `SpecialModelRenderers#createBlockRenderers` -> `BuiltInBlockModels#createBlockModels`, not one-to-one + - `StandingSignSpecialRenderer$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` + - The constructor now takes in the `PlainSignBlock$Attachment` + - `TridentSpecialRenderer` + - `DEFAULT_TRANSFORMATION` - The default transformation to apply. + - `$Unbaked` now implements `NoDataSpecialModelRenderer$Unbaked` +- `net.minecraft.client.renderer.state.*` -> `.state.level.*` +- `net.minecraft.client.renderer.state` + - `GameRenderState` - The render state of the game. + - `OptionsRenderState` - The render state of the client user options. + - `WindowRenderState` - The render state of the game window. +- `net.minecraft.client.renderer.state.gui.GuiRenderState#submit*` methods have been renamed to `add*` +- `net.minecraft.client.renderer.state.level` + - `BlockBreakingRenderState` is now a record, and no longer extends `MovingBlockRenderState` + - The constructor takes in the `BlockPos`, `BlockState`, and the current `int` progress + - `CameraEntityRenderState` - The render state for the camera entity. + - `CameraRenderState` + - `xRot`, `yRot` - The rotation of the camera. + - `entityPos` is removed + - `isPanoramicMode` - Whether the camera is in panorama mode. + - `cullFrustum` - The cull frustum. + - `fogType`, `fogData` - Fog metadata. + - `hudFov` - The hud field-of-view. + - `depthFar` - The depth Z far plane. + - `projectionMatrix`, `viewRotationMatrix` - The matrices for moving from world space to screen space. + - `entityRenderState` - The entity the camera is attached to. + - `LevelRenderState` + - `lastEntityRenderStateCount` - The number of entities being rendered to the screen. + - `cloudColor`, `cloudHeight` - Cloud metadata. + - `LightmapRenderState` - The render state for the lightmap. +- `net.minecraft.client.renderer.texture` + - `MipmapGenerator#generateMipLevels` now takes in the computed `Transparency` of the image + - `SpriteContents` + - `transparency` - Gets the transparency of the sprite. + - `getUniqueFrames` now returns an `IntList` instaed of an `IntStream` + - `computeTransparency` - Computes the transparency of the selected UV bounds. + - `$AnimatedTexture#getUniqueFrames` now returns an `IntList` instaed of an `IntStream` + - `TextureAtlasSprite#transparency` - Gets the transparency of the sprite. +- `net.minecraft.client.resources.model` + - `AtlasManager` -> `.model.sprite.AtlasManager` + - `BlockModelRotation` -> `.client.renderer.block.dispatch.BlockModelRotation` + - `Material` -> `.model.sprite.SpriteId`, not one-to-one + - `MaterialSet` -> `.model.sprite.SpriteGetter` + - `MissingBlockModel` -> `.model.cuboid.MissingCuboidModel` + - `ModelBaker` + - `sprites` -> `materials` + - `parts` -> `interner` + - `$PartCache` -> `$Interner` + - `vector(float, float, float)` is removed + - `materialInfo` - Gets the interned material info object. + - `ModelBakery` + - `BANNER_BASE` -> `Sheets#BANNER_BASE` + - `SHIELD_BASE` -> `Sheets#SHIELD_BASE` + - `NO_PATTERN_SHIELD` -> `Sheets#SHIELD_BASE_NO_PATTERN` + - `LAVA_*` -> `FluidStateModelSet#LAVA_MODEL`, now `private` from `public` + - `WATER_*` -> `FluidStateModelSet#WATER_MODEL`, now `private` from `public` + - `$BakingResult#getBlockStateModel` - Gets the `BlockStateModel` from the `BlockState`. + - `$MissingModels` now takes in a `MissingItemModel` instead of an `ItemModel` for the `Item`, and a `FluidModel` + - `ModelManager` + - `BLOCK_OR_ITEM` is removed + - `getMissingBlockStateModel` -> `BlockStateModelSet#missingModel` + - `getBlockModelShaper` -> `getBlockStateModelSet`, not one-to-one + - `getBlockModelSet` - Gets the map of `BlockState` to block model. + - `specialBlockModelRenderer` is removed + - `getFluidStateModelSet` - Gets the map of `Fluid` to fluid model. + - `ModelState` -> `.client.renderer.block.dispatch.ModelState` + - `QuadCollection` -> `.model.geometry.QuadCollection` + - `addAll` - Adds all elements from another quad collection. + - `materialFlags`, `hasMaterialFlag` - Handles the flags for the material(s) used by the model. + - `ResolvedModel#resolveParticleSprite` -> `resolveParticleMaterial`, now returning a `Material$Baked` instead of a `TextureAtlasSprite` + - `SpriteGetter` -> `.model.sprite.MaterialBaker` + - `UnbakedGeometry` -> `.model.geometry.UnbakedGeometry` + - `WeightedVariants` -> `.client.renderer.block.dispatch.WeightedVariants` +- `net.minecraft.client.resources.model.sprite.Material` - A reference to a texture sprite, along with whether to force translucency on the texture. +- `net.minecraft.world.entity.animal.Animal#isBrightEnoughToSpawn` now takes in a `BlockAndLightGetter` instead of the `BlockAndTintGetter` +- `net.minecraft.world.level` + - `BlockAndTintGetter` -> `BlockAndLightGetter` + - `BlockAndTintGetter` is now client only, implementing `BlockAndLightGetter` + - `getShade` -> `cardinalLighting`; not one-to-one + - `getBlockTint` -> `BlockAndTintGetter#getBlockTint` + - `CardinalLighting` - Holds the lighting applied in each direction. + - `EmptyBlockAndTintGetter` -> `BlockAndTintGetter#EMPTY` + - `LevelReader` now implements `BlockAndLightGetter` instead of `BlockAndTintGetter` +- `net.minecraft.world.level.block` + - `BannerBlock$AttachmentType` - Where the banner attaches to another block. + - `CeilingHangingSignBlock` now implements `HangingSignBlock` + - `getAttachmentPoint` - Gets where the sign attaches to another block. + - `HangingSignBlock` - An interface that defines a hanging sign attached to another block. + - `PlainSignBlock` - An inteface that defines a plain sign attached to another block. + - `StandingSignBlock` now implements `PlainSignBlock` + - `WallingHangingSignBlock` now implements `HangingSignBlock` + - `WallSignBlock` now implements `PlainSignBlock` +- `net.minecraft.world.level.block.state.BlockBehaviour#getLightBlock`, `$BlockStateBase#getLightBlock` -> `getLightDampening` +- `net.minecraft.world.level.block.state.properties` + - `BedPart#CODEC` - The codec for the bed part. + - `ChestType#CODEC` - The codec for the chest type. +- `net.minecraft.world.level.dimension.DimensionType$CardinalLightType` -> `CardinalLighting$Type` + +### 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. + +#### Plantable Tags + +The blocks to determine whether a plantable can survive or be placed on has been moved to block and fluid tags. Each of these tags starts with `support_*` along with the block (e.g., `bamboo`, `cactus`) or group (e.g., `crops`, `dry_vegetation`). This is handled by the relevant block subclasses overriding either `Block#canSurvive`, or for vegetation `VegetationBlock#mayPlaceOn`. + +- `net.minecraft.world.level.block` + - `AttachedStemBlock` now takes in a `TagKey` for the blocks it can be placed on + - `FarmBlock` -> `FarmlandBlock` + - `FungusBlock` -> `NetherFungusBlock`, not one-to-one + - `RootsBlock` -> `NetherRootsBlock`, not one-to-one + - `WaterlilyBlock` -> `LilyPadBlock`, not one-to-one + - `StemBlock` now takes in a `TagKey` for the blocks it can be placed on, and a `TagKey` for the blocks its fruit can be placed on + +#### Container Screen Changes + +The usage of `AbstractContainerScreen`s has changed slightly, requiring some minor changes. First `imageWidth` and `imageHeight` are now final, settable as parameters within the constructor. If these two are not specified, they default to the original 176 x 166 background image. + +```java +// Assume some AbstractContainerMenu subclass exists +public class ExampleContainerScreen extends AbstractContainerScreen { + + // Constructor + public ExampleContainerScreen(ExampleContainerMenu menu, Inventory playerInventory, Component title) { + // Specify image width and height as the last two parameters in the constructor + super(menu, playerInventory, title, 256, 256); + } +} +``` + +Additionally, the `AbstractContainerScreen#render` override now calls `renderTooltip` at the end of the call stack. This means that, in most cases, you should not override `render` in subtypes of the `AbstractContainerScreen`. Everything can be done in one of the other methods provided by the class. + +- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen` now optionally takes in the background image width and height + - `imageWidth`, `imageHeight` are now final + - `DEFAULT_IMAGE_WIDTH`, `DEFAULT_IMAGE_HEIGHT` - The default width and height of the container background image. + - `slotClicked` now takes is a `ContainerInput` instead of a `ClickType` + - `render` override now calls `renderTooltip` by default +- `net.minecraft.world.inventory` + - `AbstractContainerMenu#clicked` now takes in a `ContainerInput` instead of a `ClickType` + - `ClickType` -> `ContainerInput` + +#### New Tag Providers + +A new `TagsProvider` has been added that provides a utility for working with `Holder$Reference`s, known as `HolderTagProvider`. This is only used by the `PotionTagsProvider`. + +Additionally, the `TagBuilder` now provides a method of setting the `replace` field on a tag, which removes all previous read entries during deserialization. + +- `net.minecraft.data.tags` + - `FeatureTagsProvider` - A tag provider for `ConfiguredFeature`s. + - `HolderTagProvider` - A tag provider with a utility for appending tags by their reference holder. + - `KeyTagProvider#tag` now has an overload of whether to replace the entries in the tag. + - `PotionTagsProvider` - A provider for potion tags. + - `TradeRebalanceTradeTagsProvider` - A provider for villager trade tags for the trade rebalance. + - `VillagerTradesTagsProvider` - A provider for villager trade tags. +- `net.minecraft.tags` + - `FeatureTags` - Tags for `ConfiguredFeature`s. + - `TagBuilder#shouldReplace`, `setReplace` - Handles the `replace` field that removes all previously read entries during deserialization. + +#### Test Environment State Tracking + +`TestEnvironmentDefinition`s can now keep track of the original state of the world when being created, such that it can be properly restored on run. This is done through a generic known as the 'SavedDataType'. On `setup`, each environment will return the generic data representing the original state of what was modified. Then, on `teardown`, the original state will be restored to the level for the next test case. + +```java +// The generic should represent the original data stored on the level +public record RespawnEnvironment(LevelData.RespawnData respawn) implements TestEnvironmentDefinition { + + @Override + public LevelData.RespawnData setup(ServerLevel level) { + // Modify the level while logging the original state. + var original = level.getRespawnData(); + level.setRespawnData(this.respawn); + + // Return the original state. + return original; + } + + @Override + public void teardown(ServerLevel level, LevelData.RespawnData original) { + // Reset the state of the level to the original values. + level.setRespawnData(original); + } + + @Override + public MapCodec codec() { + // Return the registered MapCodec here. + // ... + } +} +``` + +- `net.minecraft.gametest.framework.TestEnvironmentDefinition` now has a generic representing the original state of the given modification performed by the test environment + - `setup` now returns the generic representing the original state + - `teardown` is no longer default, taking in the original state to restore + - `activate`, `$Activation` - Handles an active test environment. + +#### Typed Instance + +`TypedInstance` is an interface that is attached to certain objects that represent an instance of some other 'type' object. For example, and `Entity` is a typed instance of `EntityType`, or a `BlockState` is a typed instance of `Block`. This interface is meant as a standard method to provide access to the type `Holder` and check whether the backing type, and therefore the instance, is equivalent to some identifier, tag, or raw object via `is`. + +```java +// For some Entity entity, check the EntityType +entity.is(EntityType.PLAYER); + +// For some ItemStack itemStack, check the Item +itemStack.is(ItemTags.BUTTONS); + +// For some BlockEntity blockEntity, check the BlockEntityType +blockEntity.is(BlockEntityType.CHEST); + +// For some BlockState blockState, check the Block +blockState.is(Blocks.DIRT); + +// For some FluidState fluidState, check the Fluid +fluidState.is(FluidTags.WATER); +``` + +- `net.minecraft.core.TypedInstance` - An interface that represents that this object is an instance for some other 'type' object. +- `net.minecraft.world.entity` + - `Entity` now implements `TypedInstance>` + - `EntityType#is` -> `TypedInstance#is` + - Now on the `Entity` instance +- `net.minecraft.world.item.ItemStack` now implements `TypedInstance` + - `getItemHolder` -> `typeHolder` + - `getTags` -> `tags` +- `net.minecraft.world.level.block.entity` + - `BlockEntity` now implements `TypedInstance` + - `BlockEntityType#getKey` is removed +- `net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase` now implements `TypedInstance` + - `getBlockHolder` -> `typeHolder` + - `getTags` -> `tags` +- `net.minecraft.world.level.material.FluidState` now implements `TypedInstance` + - `holder` -> `typeHolder` + - `getTags` -> `tags` + +#### Entity Textures and Adult/Baby Models + +Entity textures within `assets/minecraft/textures/entity/*` have now been sorted into subdirectories (e.g., `entity/panda` for panda textures, or `entity/pig` for pig textures). Most textures have been named with the entity type starting followed by an underscore along with its variant (e.g., `arrow_tipped` for tipped arrow, `pig_cold` for the cold pig variant, or `panda_brown` for the brown panda variant). + +Additionally, some animal models have been split into separate classes for the baby and adult variants. These models either directly extend an abstract model implementation (e.g., `AbstractFelineModel`) or the original model class (e.g., `PigModel`). + +- `net.minecraft.client.animation.definitions` + - `BabyArmadilloAnimation` - Animations for the baby armadillo. + - `BabyAxolotlAnimation` - Animations for the baby axolotl. + - `BabyRabbitAnimation` - Animations for the baby rabbit. + - `CamelBabyAnimation` - Animations for the baby camel. + - `FoxBabyAnimation` - Animations for the baby fox. + - `RabbitAnimation` - Animations for the rabbit. +- `net.minecraft.client.model` + - `HumanoidModel` + - `ADULT_ARMOR_PARTS_PER_SLOT`, `BABY_ARMOR_PARTS_PER_SLOT` - A map of equipment slot to model part keys. + - `createBabyArmorMeshSet` - Creates the armor model set for a baby humanoid. + - `createArmorMeshSet` can now take in a map of equipment slot to model part keys for what to retain + - `setAllVisible` is removed + - `QuadrupedModel` now has a constructor that takes in a function for the `RenderType` +- `net.minecraft.client.model.animal.armadillo` + - `AdultArmadilloModel` - Entity model for the adult armadillo. + - `ArmadilloModel` is now abstract + - The constructor now takes in the definitions for the walk, roll out/up, and peek animations + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyArmadilloModel` + - `HEAD_CUBE`, `RIGHT_EAR_CUBE`, `LEFT_EAR_CUBE` are now `protected` instead of `private` + - `createBodyLayer` -> `AdultArmadilloModel#createBodyLayer`, `BabyArmadilloModel#createBodyLayer` + - `BabyArmadilloModel` - Entity model for the baby armadillo. +- `net.minecraft.client.model.animal.axolotl.AxolotlModel` -> `AdultAxolotlModel`, `BabyAxolotlModel` +- `net.minecraft.client.model.animal.bee` + - `AdultBeeModel` - Entity model for the adult bee. + - `BabyBeeModel` - Entity model for the baby bee. + - `BeeModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyBeeModel` + - `BONE`, `STINGER`, `FRONT_LEGS`, `MIDDLE_LEGS`, `BACK_LEGS` are now `protected` instead of `private` + - `bone` is now `protected` instead of `private` + - `createBodyLayer` -> `AdultBeeModel#createBodyLayer`, `BabyBeeModel#createBodyLayer` + - `bobUpAndDown` - Bobs the bee up and down at the desired speed, depending on its current age. +- `net.minecraft.client.model.animal.camel` + - `AdultCamelModel` - Entity model for the adult camel. + - `BabyCamelModel` - Entity model for the baby camel. + - `CamelModel` is now abstract + - The constructor now takes in the definitions for the walk, sit with/without pose, standup, idle, and dash animations + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyCamelModel` + - `createBodyLayer` -> `AdultCamelModel#createBodyLayer`, `BabyCamelModel#createBodyLayer` + - `CameSaddleModel` now extends `AdultCamelModel` instead of `CamelModel` +- `net.minecraft.client.model.animal.chicken` + - `AdultChickenModel` - Entity model for the adult chicken. + - `BabyChickenModel` - Entity model for the baby chicken. + - `ChickenModel` is now abstract + - `RED_THING` -> `AdultChickenModel#RED_THING` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyChickenModel` + - `createBodyLayer` -> `AdultChickenModel#createBodyLayer` + - `createBaseChickenModel` -> `AdultChickenModel#createBaseChickenModel` + - `ColdChickenModel` now extends `AdultChickenModel` +- `net.minecraft.client.model.animal.cow.BabyCowModel` - Entity model for the baby cow. +- `net.minecraft.client.model.animal.dolphin.BabyDolphinModel` - Entity model for the baby dolphin. +- `net.minecraft.client.model.animal.equine` + - `AbstractEquineModel` now has an overload that directly specifies the `ModelPart`s to use + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyDonkeyModel` + - `rightHindLeg`, `leftHindLeg`, `rightFrontLeg`, `leftFrontLeg` are now `protected` from `private` + - `createBabyMesh` -> `BabyHorseModel#createBabyMesh`, not one-to-one + - `offsetLegPositionWhenStanding` - Offsets the position of the legs when the entity is standing. + - `getLegStandAngle`, `getLegStandingYOffset`, `getLegStandingZOffset`, `getLegStandingXRotOffset`, `getTailXRotOffset` - Offsets and angles for parts of the equine model. + - `animateHeadPartsPlacement` - Animates the head based on its eating and standing states. + - `BabyDonkeyModel` - Entity model for the baby donkey. + - `BabyHorseModel` - Entity model for the baby horse. + - `DonkeyModel` now has an overload that directly specifies the `ModelPart`s to use + - `createBabyLayer` -> `BabyDonkeyModel#createBabyLayer` + - `EquineSaddleModel#createFullScaleSaddleLayer` is removed + Merged into `createSaddleLayer`, with the baby variant removed +- `net.minecraft.client.model.animal.feline` + - `CatModel` -> `AdultCatModel`, `BabyCatModel`; not one-to-one + - `FelineModel` -> `AbstractFelineModel`, not one-to-one + - Implementations in `AdultFelineModel` and `BabyFelineModel` + - `OcelotModel` -> `AdultOcelotModel`, `BabyOcelotModel`; not one-to-one +- `net.minecraft.client.model.animal.fox` + - `AdultFoxModel` - Entity model for the adult fox. + - `BabyFoxModel` - Entity model for the baby fox. + - `FoxModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyFoxModel` + - `body`, `rightHindLeg`, `leftHindLeg`, `rightFontLeg`, `leftFrontLeg`, `tail` are now `protected` instead of `private` + - `createBodyLayer` -> `AdultFoxModel#createBodyLayer`, `BabyFoxModel#createBodyLayer` + - `set*Pose` - Methods for setting the current pose of the fox. +- `net.minecraft.client.model.animal.goat` + - `BabyGoatModel` - Entity model for the baby goat. + - `GoatModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyGoatModel` +- `net.minecraft.client.model.animal.llama` + - `BabyLlamaModel` - Entity model for the baby llama. + - `LlamaModel#createBodyLayer` no longer takes in the `boolean` for if the entity is a baby +- `net.minecraft.client.model.animal.panda` + - `BabyPandaModel` - Entity model for the baby panda. + - `PandaModel` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyPandaModel` + - `animateSitting` - Animates the panda sitting. +- `net.minecraft.client.model.animal.pig.BabyPigModel` - Entity model for the baby pig. +- `net.minecraft.client.model.animal.polarbear` + - `BabyPolarBearModel` - Entity model for the baby polar bear. + - `PolarBearModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyPolarBearModel` +- `net.minecraft.client.model.animal.rabbit` + - `AdultRabbitModel` - Entity model for the adult rabbit. + - `BabyRabbitModel` - Entity model for the baby rabbit. + - `RabbitModel` is now abstract + - The constructor now takes in two animation definitions for the hop and idle head tilt + - `FRONT_LEGS`, `BACK_LEGS` - The child name for the entity legs. + - `LEFT_HAUNCH`, `RIGHT_HAUNCH` are now `protected` + - `createBodyLayer` -> `AdultRabbitModel#createBodyLayer`, `BabyRabbitModel#createBodyLayer`; not one-to-one +- `net.minecraft.client.model.animal.sheep` + - `BabySheepModel` - Entity model for the baby sheep. + - `SheepModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabySheepModel` +- `net.minecraft.client.model.animal.sniffer` + - `SnifferModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `SniffletModel` + - `SniffletModel` - Entity model for the baby sniffer. +- `net.minecraft.client.model.animal.squid` + - `BabySquidModel` - Entity model for the baby squid. + - `SquidModel#createTentacleName` is now protected from private +- `net.minecraft.client.model.animal.turtle` + - `AdultTurtleModel` - Entity model for the adult turtle. + - `BabyTurtleModel` - Entity model for the baby turtle. + - `TurtleModel` is now abstract + - The constructor can how take in the render type function + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyTurtleModel` + - `createBodyLayer` -> `AdultTurtleModel#createBodyLayer`, `BabyTurtleModel#createBodyLayer` +- `net.minecraft.client.model.animal.wolf` + - `AdultWolfModel` - Entity model for the adult wolf. + - `BabyWolfModel` - Entity model for the baby wolf. + - `WolfModel` is now abstract + - `ModelPart` fields are now all protected + - `createMeshDefinition` -> `AdultWolfModel#createBodyLayer`, `BabyWolfModel#createBodyLayer`; not one-to-one + - `shakeOffWater` - Sets the body rotation when shaking off water. + - `setSittingPose` - Sets the sitting pose of the wolf. +- `net.minecraft.client.model.geom` + - `ModelLayers` + - `COLD_CHICKEN_BABY` is removed + - `COLD_PIG_BABY` is removed + - `PIG_BABY_SADDLE` is removed + - `SHEEP_BABY_WOOL_UNDERCOAT` is removed + - `WOLF_BABY_ARMOR` is removed + - `DONKEY_BABY_SADDLE` is removed + - `HORSE_BABY_ARMOR` is removed + - `HORSE_BABY_SADDLE` is removed + - `MULE_BABY_SADDLE` is removed + - `SKELETON_HORSE_BABY_SADDLE` is removed + - `UNDEAD_HORSE_BABY_ARMOR` is removed + - `ZOMBIE_HORSE_BABY_SADDLE` is removed + - `STRIDER_BABY_SADDLE` is removed + - `PartNames#WAIST` - The waist part. +- `net.minecraft.client.model.monster.hoglin` + - `BabyHoglinModel` - Entity model for the baby hoglin. + - `HoglinModel` + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyHoglinModel` + - `head` is now `protected` from `private` + - `createBabyLayer` -> `BabyHoglinModel#createBodyLayer` +- `net.minecraft.client.model.monster.piglin` + - `AbstractPiglinModel` is now abstract + - `leftSleeve`, `rightSleeve`, `leftPants`, `rightPants`, `jacket` are removed + - `ADULT_EAR_ANGLE_IN_DEGREES`, `BABY_EAR_ANGLE_IN_DEGREES` - The angle of the piglin ears. + - `createMesh` replaced by `AdultPiglinModel#createBodyLayer`, `AdultZombifiedPiglinModel#createBodyLayer`, `BabyPiglinModel#createBodyLayer`, `BabyZombifiedPiglinModel#createBodyLayer` + - `createBabyArmorMeshSet` - Create the armor meshes for the baby piglin model. + - `getDefaultEarAngleInDegrees` - Gets the default ear angle. + - `AdultPiglinModel` - Entity model for the adult piglin. + - `AdultZombifiedPiglinModel` - Entity model for the adult zombified piglin. + - `BabyPiglinModel` - Entity model for the baby piglin. + - `BabyZombifiedPiglinModel` - Entity model for the baby zombified piglin. + - `PiglinModel` is now abstract + - `ZombifiedPiglinModel` is now abstract +- `net.minecraft.client.model.monster.strider` + - `AdultStriderModel` - Entity model for the adult strider. + - `BabyStriderModel` - Entity model for the baby strider. + - `StriderModel` is now abstract + - `BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyStriderModel` + - `rightLeg`, `leftLeg`, `body` are now `protected` from `private` + - `SPEED` - The speed scalar of the movement animation. + - `customAnimations` - Additional animation setup. + - `animateBristle` - Animates the bristles of the strider. +- `net.minecraft.client.model.monster.zombie` + - `BabyDrownedModel` - Entity model for the baby drowned. + - `BabyZombieModel` - Entity model for the baby zombie. + - `BabyZombieVillagerModel` - Entity model for the baby zombie villager. +- `net.minecraft.client.model.npc` + - `BabyVillagerModel` - Entity model for the baby villager. + - `VillagerModel#BABY_TRANSFORMER` has been directly merged into the layer definition for the `BabyVillagerModel` +- `net.minecraft.client.renderer.entity` + - `AxolotlRenderer` now takes in an `EntityModel` for its generic + - `CamelHuskRenderer` now extends `MobRenderer` instead of `CamelRenderer` + - `CamelRenderer#createCamelSaddleLayer` is now `static` + - `CatRenderer` now takes in an `AbstractFelineModel` for its generic + - `DonkeyRenderer` now takes in an `EquipmentClientInfo$LayerType` and `ModelLayerLocation` for the saddle layer and model, and splits the `DonkeyRenderer$Type` into the adult type and baby type + - `$Type` + - `DONKEY_BABY` - A baby variant of the donkey. + - `MULE_BABY` - A baby variant of the mule. + - `OcelotRenderer` now takes in an `AbstractFelineModel` for its generic + - `UndeadHorseRenderer` now takes in an `EquipmentClientInfo$LayerType` and `ModelLayerLocation` for the saddle layer and model, and splits the `UndeadHorseRenderer$Type` into the adult type and baby type + - `$Type` + - `SKELETON_BABY` - A baby variant of the skeleton horse. + - `ZOMBIE_BABY` - A baby variant of the zombie horse. +- `net.minecraft.client.renderer.entity.layers.CatCollarLayer` now takes in an `AbstractFelineModel` for its generic +- `net.minecraft.client.renderer.entity.state` + - `AxolotlRenderState` + - `swimAnimation` - The state of swimming. + - `walkAnimationState` - The state of walking on the ground, not underwater. + - `walkUnderWaterAnimationState` - The state of walking underwater. + - `idleUnderWaterAnimationState` - The state of idling underwater but not on the ground. + - `idleUnderWaterOnGroundAnimationState` - The state of idling underwater while touching the seafloor. + - `idleOnGroundAnimationState` - The state of idling on the ground, not underwater. + - `playDeadAnimationState` - The state of playing dead. + - `RabbitRenderState` + - `hopAnimationState` - The state of the hop the entity is performing. + - `idleHeadTiltAnimationState` - The state of the head tilt when performing the idle animation. +- `net.minecraft.client.resources.model.EquipmentClientInfo$LayerType#HUMANOID_BABY` - The baby humanoid equipment layer. +- `net.minecraft.sounds.SoundEvents#PIG_EAT_BABY` - Ths sound played when a baby big is eating. +- `net.minecraft.world.entity.AgeableMob` + - `canUseGoldenDandelion` - Whether a golden dandelion can be used to agelock an entity. + - `setAgeLocked` - Sets the entity as agelocked. + - `makeAgeLockedParticle` - Creates the particles when agelocking an entity. + - `AGE_LOCK_DOWNWARDS_MOVING_PARTICLE_Y_OFFSET` - The Y offset for the particle's starting position. +- `net.minecraft.world.entity.animal.axolotl.Axolotl` + - `swimAnimation` - The state of swimming. + - `walkAnimationState` - The state of walking on the ground, not underwater. + - `walkUnderWaterAnimationState` - The state of walking underwater. + - `idleUnderWaterAnimationState` - The state of idling underwater but not on the ground. + - `idleUnderWaterOnGroundAnimationState` - The state of idling underwater while touching the seafloor. + - `idleOnGroundAnimationState` - The state of idling on the ground, not underwater. + - `playDeadAnimationState` - The state of playing dead. + - `$AnimationState` -> `$AxolotlAnimationState` +- `net.minecraft.world.entity.animal.chicken.ChickenVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.cow.CowVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.cat.CatVariant` now takes in a resource for the baby texture + - `CatVariant#assetInfo` - Gets the entity texture based on whether the entity is a baby. +- `net.minecraft.world.entity.animal.equine.AbstractHorse#BABY_SCALE` - The scale of the baby size compared to an adult. +- `net.minecraft.world.entity.animal.frog.Tadpole` + - `ageLockParticleTimer` - A timer for how long the particles for the agelocked entity should spawn. + - `setAgeLocked`, `isAgeLocked` - Handles agelocking for the tadpole. +- `net.minecraft.world.entity.animal.goat.Goat` + - `BABY_DEFAULT_X_HEAD_ROT` - The default head X rotation for the baby variant. + - `MAX_ADDED_RAMMING_X_HEAD_ROT` - The maximum head X rotation. + - `addHorns`, `removeHorns` are removed +- `net.minecraft.world.entity.animal.pig.PigVariant` now takes in a resource for the baby texture +- `net.minecraft.world.entity.animal.rabbit.Rabbit` + - `hopAnimationState` - The state of the hop the entity is performing. + - `idleHeadTiltAnimationState` - The state of the head tilt when performing the idle animation. +- `net.minecraft.world.entity.animal.wolf` + - `WolfSoundVariant` -> `WolfSoundVariant$WolfSoundSet` + - The class itself now holds two sound sets for the adult wolf and baby wolf. + - `WolfSoundVariants$SoundSet#getSoundEventSuffix` -> `getSoundEventIdentifier` +- `net.minecraft.world.entity.animal.wolf.WolfVariant` now takes in an asset info for the baby variant +- `net.minecraft.world.item.equipment.EquipmentAssets#TRADER_LLAMA_BABY` - Equipment asset for baby trader llamas. + +#### The Removal of interactAt + +`Entity#interactAt` has been removed, with all further invocation merged with `Entity#interact`. Originally, `Entity#interactAt` was called if the hit result was within the entity's interaction range. If `interactAt` did not consume the action (i.e., `InteractionResult#consumesAction` returns false), then `Entity#interact` is called. Now, `Entity#interact` is called if within the entity's interaction range, taking in the `Vec3` location of interaction. + +```java +// In some Entity subclass + +@Override +public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) { + // Handle the interaction + super.interact(player, hand, location); +} +``` + +`interactAt` checks if result does not consume the interaction, and if not calls `interact` +Now, `interact` is called with the entity hit + +- `net.minecraft.client.multiplayer.MultiPlayerGameMode` + - `interact` now takes in the `EntityHitResult` + - `interactAt` is removed +- `net.minecraft.world.entity.Entity` + - `interact` now takes in a `Vec3` for the location of the interaction + - `interactAt` is removed +- `net.minecraft.world.entity.player.Player#interactOn` now takes in a `Vec3` for the location of the interaction + +#### ChunkPos, now a record + +`ChunkPos` is now a record. The `BlockPos` constructor has been replaced by `ChunkPos#containing` while the packed `long` constructor has been replaced by `ChunkPose#unpack`. + +- `net.minecraft.world.level.ChunkPos` is now a record + - `ChunkPos(BlockPos)` -> `containing` + - `ChunkPos(long)` -> `unpack` + - `toLong`, `asLong` -> `pack` + +#### No More Tripwire Pipelines + +The tripwire render pipeline has been completely removed. Now, tripwires make use of `cutout` with an `alpha_cutoff_bias` of 0.1 for the texture. + +- `net.minecraft.client.renderer.RenderPipelines#TRIPWIRE_BLOCK`, `TRIPWIRE_TERRAIN` are removed +- `net.minecraft.client.renderer.chunk` + - `ChunkSectionLayer#TRIPWIRE` is removed + - `ChunkSectionLayerGroup#TRIPWIRE` is removed +- `net.minecraft.client.renderer.rendertype.RenderTypes#tripwireMovingBlock` is removed + +#### Activities and Brains + +Activities, which define how a living entity behaves during a certain phase, now are stored and passed around through `ActivityData`. This contains the activity type, the behaviors to perform along with their priorities, the conditions on when this activity activates, and the memories to erase when the activity has stopped. `Brain#provider` now takes in an `$ActivitySupplier` to construct a list of `ActivityData` the entity performs. + +Brains have also changed slightly. First, the `Brain` itself is not directly serializable. Instead, the brain is `$Packed` into the record, holding a map of its current memories. To get the memory types used, they are typically extracted from those that the `Sensor#requires`. Additionally, `LivingEntity#brainProvider` no longer exists, instead opting to store the provider in a static constant on the entity itself. This means that brains are now completely constructed through the `makeBrain` method, taking in the previous `$Packed` data: + +```java +// For some ExampleEntity extends LivingEntity +// Assume extends Mob subclass +private static final Brain.Provider BRAIN_PROVIDER = Brain.provider( + // The list of sensors the entity uses. + ImmutableList.of(), + // A function that takes in the entity and returns a list of activities. + entity -> List.of( + new ActivityData( + // The activity type + Activity.CORE, + // A list of priority and behavior pairs + ImmutableList.of(Pair.of(0, new MoveToTargetSink())), + // A set of memory conditions for the activity to run + // For example, this memory value must be present + ImmutableSet.of(Pair.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT)), + // The set of memories to erase when the activity has stopped + ImmutableSet.of(MemoryModuleType.ATTACK_TARGET) + ) + ) +); + +@Override +protected Brain.Provider makeBrain(Brain.Packed packedBrain) { + // Make the brain, populating any previous memories + return BRAIN_PROVIDER.makeBrain(this, packedBrain); +} +``` + +- `net.minecraft.world.entity.LivingEntity` + - `brainProvider` is removed + - `makeBrain` now takes in a `Brain$Packed` instead of a `Dynamic` +- `net.minecraft.world.entity.ai` + - `ActivityData` - A record containing the activity being performed, the behaviors to perform during that activity, any memory conditions, and what memories to erase once stopped. + - `Brain` is now protected, taking in a list of `ActivityData`, a `MemoryMap` instead of an immutable list of memories, a `RandomSource`, and not the supplied `Codec` + - The public constructor no longer takes in anything + - `provider` now has an overload that only takes in the sensor types, defaulting the memory types to an empty list + - Some `provider` methods also take in the `Brain$ActivitySupplier` to perform + - `codec`, `serializeStart` are replaced by `pack`, `Brain$Packed` + - `addActivityAndRemoveMemoryWhenStopped`, `addActivityWithConditions` merged into `addActivity` + - Alternatively use `ActivityData#create` + - `copyWithoutBehaviors` is removed + - `getMemories` replaced by `forEach` + - `$ActivitySupplier` - Creates a list of activities for the entity. + - `$MemoryValue` is removed + - `$Packed` - A record containing the data to serialize the brain to disk. + - `$Provider#makeBrain` now takes in the entity and the `Brain$Packed` to deserialize the memories + - `$Visitor` - Visits the memories within a brain, whether defined but empty, present, or present with some timer. +- `net.minecraft.world.entity.ai.behavior.VillagerGoalPackages#get*Package` no longer take in the `VillagerProfession` +- `net.minecraft.world.entity.ai.memory` + - `ExpirableValue` -> `MemorySlot`, not one-to-one + - The original `ExpirableValue` is now a record that defines when a memory should expire, rather than be updated itself + - `MemoryMap` - A map linking the memory type to its stored value. + - `MemoryModuleType` - Whether a memory can be serialized. +- `net.minecraf.tworld.entity.ai.sensing.Sensor#randomlyDelayStart` - How long to delay a sensor. +- `net.minecraft.world.entity.animal.allay.AllayAi` + - `SENSOR_TYPES`, `MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.animal.armadillo.ArmadilloAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.axolotl` + - `AxolotlSENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `AxolotlAi` + - `makeBrain` -> `getActivities`, not one-to-one + - `initPlayDeadActivity`, now `protected`, no longer taking in anything + - `initFightActivity`, now `protected`, no longer taking in anything + - `initCoreActivity`, now `protected`, no longer taking in anything + - `initIdleActivity`, now `protected`, no longer taking in anything +- `net.minecraft.world.entity.animal.camel.CamelAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.frog` + - `Frog#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `FrogAi#makeBrain` -> `getActivities`, not one-to-one + - `Tadpole#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one +- `net.minecraft.world.entity.animal.frog.TadpoleAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.animal.goat` + - `Goat#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `GoatAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.animal.golem.CopperGolemAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.happyghast.HappyGhastAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.animal.nautilus` + - `NautilusAi` + - `SENSOR_TYPES`,`MEMORY_TYPES` -> `Nautilus#BRAIN_PROVIDER`, now private, not one-to-one + - `makeBrain`, `brainProvider` -> `getActivities`, now `public`, not one-to-one + - `ZombieNautilusAi` + - `SENSOR_TYPES`,`MEMORY_TYPES` -> `ZombieNautilus#BRAIN_PROVIDER`, now private, not one-to-one + - `makeBrain`, `brainProvider` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.animal.sniffer.SnifferAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.monster.Zoglin` + - `SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `getActivities` - The activities the zoglin performs. +- `net.minecraft.world.entity.monster.breeze.BreezeAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.monster.creaking.CreakingAi#makeBrain`, `brainProvider` -> `getActivities`, now `protected`, not one-to-one +- `net.minecraft.world.entity.monster.hoglin` + - `Hoglin#SENSOR_TYPES` -> `BRAIN_PROVIDER`, now private; not one-to-one + - `HoglinAi#makeBrain` -> `getActivities`, not one-to-one +- `net.minecraft.world.entity.monster.piglin` + - `Piglin#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `PiglinAi#makeBrain` -> `getActivities`, now `public`, not one-to-one + - `PiglinBrute#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`, now private, not one-to-one + - `PiglinBruteAi#makeBrain` -> `getActivities`, now `public`, not one-to-one +- `net.minecraft.world.entity.monster.warden.WardenAi#makeBrain` -> `getActivities`, not one-to-one + +#### File Fixer Upper + +The file fixer upper is a new system to help with upgrading game files between versions, in conjunction with the data fixer upper. Similar to how the data within files can be modified or 'upgraded' between Minecraft versions via data fixers, file fixers can modify anything within a world directory, from moving files and directories to deleting them outright. As such, file fixers are always applied before data fixers. + +Unlike when upgrading when data fixers, file fixers change the structure of the world folder. Because of this, downgrading is rarely possible, as the file names and locations will have likely changed location. + +File fixers are applied through a `FileFix`, which defines some operation(s) to perform on a file using `makeFixer`. This is done typically through the `addFileContentFix`, providing access to the desired files through the `FileAccess`, and then modifying the data like any other `Dynamic` instance. Operations are commonly defined as `FileFixOperation`s, which can move the file structure around. + +The file fixes are then applied through the `FileFixerUpper`, which uses a copy-on-write file system to operate on the files. The fixer is constructed using the `$Builder`, using `addSchema` and `addFixer` to apply the fixers for the desired version. During the upgrade process, the files are created in a temporary folder, then moved to the world folder. The original world folder is moved to another folder before being deleted. + +- `net.minecraft.client.gui.screens.FileFixerAbortedScreen` - A screen that's shown when the file fixing has been aborted. +- `net.minecraft.client.gui.screens.worldselection.FileFixerProgressScreen` - A screen that's displayed when attempting to show the progress of upgrading and fixing the world files. +- `net.minecraft.server.packs.linkfs` + - `DummyFileAttributes` -> `.minecraft.util.DummyFileAttributes` + - `LinkFSPath` + - `DIRECTORY_ATTRIBUTES` -> `DummyFileAttributes#DIRECTORY` + - `FILE_ATTRIBUTES` -> `DummyFileAttributes#FILE` +- `net.minecraft.util` + - `ExtraCodecs` + - `pathCodec` - A codec for a path, converting from a string and storing with Unix separators. + - `relaiveNormalizedSubPathCodec` - A codec for a path, normalized and validated to make sure it is relative. + - `guardedPathCodec` - A codec for a path, resolved and relativatized from some base path. + - `FileUtil` + - `isPathNormalized`, `createPathToResource` are removed + - `isEmptyPath` - Returns whether the path is empty. + - `Util#safeMoveFile` - Safely moves a file from some source to a destination with the given options. +- `net.minecraft.util.filefix` + - `AbortedFileFixException` - An exception thrown when the file fix has been aborted and was unable to revert moves. + - `AtmoicMoveNotSupportedFileFixException` - An exception thrown when the user file system does not support atomic moves. + - `CanceledFileFixException` - An exception thrown when the file fix upgrade proccess is canceled. + - `FailedCleanupFileFixException` - An exception thrown when the file fix was not able to move or delete folders for cleanup. + - `FileFix` - A fixer that performs some operation on a file. + - `FileFixerUpper` - The file fixers to perform operations with. + - `FileFixException` - An exception thrown when attempting to upgrade a world through the file fixer. + - `FileFixUtil` - A utility for performing some file operations. + - `FileSystemCapabilities` - The capabilities of the file system from a directory. +- `net.minecraft.util.filefix.access` + - `ChunkNbt` - Handles upgrading a chunk nbt. + - `CompressedNbt` - Handles upgrading a compressed nbt file. + - `FileAccess` - Provides an reference to some file resource(s), given its relation. + - `FileAccessProvider` - A provider of file accesses, given some relation to the origin. + - `FileRelation` - A definition of how a file relates to some origin bpath. + - `FileResourceType` - Defines the type of resource to access. + - `FileResourceTypes` - All defined file resource types. + - `LevelDat` - Handles upgrading a level dat. + - `PlayerData` - Handles upgrading the player data. + - `SavedDataNbt` - Handles upgrading the saved data. +- `net.minecraft.util.filefix.fixes.*` - The vanilla fixes to apply to the file(s). +- `net.minecraft.util.filefix.operations` + - `ApplyInFolders` - Applies the given operations within the related folders. + - `DeleteFileOrEmptyDirectory` - Deletes the target file or empty directory. + - `FileFixOperation` - An operation performed within some base directory. + - `FileFixOperations` - All vanilla file fix operations. + - `GroupMove` - Moves some directory, applying any move operation on its contents. + - `ModifyContent` - Modifies the content of a file. + - `Move` - Moves a file from some source to some destination. + - `RegexMove` - Moves all files that match the given source pattern to the destination, replacing the matched sections. +- `net.minecraft.util.filefix.virtualfilesystem` + - `CopyOnWriteFileStore` - A file store using the copy-on-write principle. + - `CopyOnWriteFileSystem` - A file system using the copy-on-write principle. + - `CopyOnWriteFSPath` - A path using the copy-on-write principle. + - `CopyOnWriteFSProvider` - A file system provider using the copy-on-write principle. + - `DirectoryNode` - A directory node for some copy-on-write file system path. + - `FileMove` - A record containing the path a file has been moved from to. + - `FileNode` - A file node for some copy-on-write file system path. + - `Node` - A node for some copy-on-write file system path. +- `net.minecraft.util.filefix.virtualfilesystem.exception` + - `CowFSCreationException` - A `CowFSFileSystemException` when the file system cannot be created. + - `CowFSDirectoryNotEmptyException` - A `DirectoryNotEmptyException` specifically for a copy-on-write system. + - `CowFSFileAlreadyExistsException` - A `FileAlreadyExistsException` specifically for a copy-on-write system. + - `CowFSFileSystemException` - A `FileSystemException` specifically for a copy-on-write system. + - `CowFSIllegalArgumentException` - An `IllegalArgumentException` when attempting to operate upon a copy-on-write system. + - `CowFSNoSuchFileException` - A `NoSuchFileException` specifically for a copy-on-write system. + - `CowFSNotDirectoryException` - A `NotDirectoryException` specifically for a copy-on-write system. + - `CowFSSymlinkException` - A `CowFSCreationException` when attempting to use the copy-on-write system with a symlink. +- `net.minecraft.util.worldupdate` + - `UpgradeProgress` + - `getTotalFiles` -> `getTotalFileFixState`, not one-to-one + - `addTotalFiles` -> `addTotalFileFixOperations`, not one-to-one + - `getTypeFileFixStats`, `getRunningFileFixerStats` - Gets the fixer stats for the specific file group. + - `incrementFinishedOperations`, `incrementFinishedOperationsBy` - Increments the number of operations that have finished. + - `setType`, `getType` - Gets the type of the upgrade progress. + - `setApplicableFixerAmount` - Sets the total number of finished operations for the running file fixers. + - `incrementRunningFileFixer` - Increments the number of finished operations. + - `logProgress` - Logs the progress of the upgrade every second. + - `$FileFixStats` - A counter for the operations performed / finished. + - `$Type` - The type of upgrade being performed on the world data. + - `WorldUpgrader` no longer takes in the `WorldData` + - `STATUS_*` messages have been combined in `UpgradeStatusTranslator` + - This also contains the specific datafix type + - `running`, `finished`, `progress`, `totalChunks`, `totalFiles`, `converted`, `skipped`, `progressMap`, `status` have all been moved into `UpgradeProgress`, stored in `upgradeProgress` + - `getProgress` -> `getTotalProgress`, not one-to-one + - `$AbstractUpgrader`, `$SimpleRegionStorageUpgrader` -> `RegionStorageUpgrader`, no longer taking in the supplied `LegacyTagFixer`, not one-to-one + - `$ChunkUpgrader`, `$EntityUpgrader`, `$PoiUpgrader` are now just constructed within `WorldUpgrader#work` + - `$Builder#setLegacyFixer` is removed + - `$ChunkUpgrader#tryProcessOnePosition` has been partially abstracted into `getDataFixContentTag`, `verifyChunkPosAndEraseCache`, `verifyChunkPos` + - `$FileToUpgrade` -> `FileToUpgrade` +- `net.minecraft.world.level.ChunkPos#getRegionX`, `getRegionZ` - Gets the region the chunk is in. +- `net.minecraft.world.level.chunk.ChunkGenerator#getTypeNameForDataFixer` now returns an optional `Identifier` instead of a `ResourceKey` +- `net.minecraft.world.level.chunk.storage` + - `LegacyTagFixer` interface is removed + - `RecreatingSimpleRegionStorage` no longer takes in the supplied `LegacyTagFixer` + - `SimpleRegionStorage` no longer takes in the supplied `LegacyTagFixer` + - `markChunkDone` is removed +- `net.minecraft.world.level.levelgen.structure` + - `LegacyStructureDataHandler` class is removed + - `StructureFeatureIndexSavedData` class is removed +- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager` + - `STRUCTURE_RESOURCE_DIRECTORY_NAME` -> `STRUCTURE_DIRECTORY_NAME`, not one-to-one + - `WORLD_STRUCTURE_LISTER`, `RESOURCE_TEXT_STRUCTURE_LISTER` - Id converters for the structure nbts. + - `save` now has an overload that takes in the path, `StructureTemplate`, and `boolean` for whether to write the data as text + - `createAndValidatePathToGeneratedStructure` -> `TemplatePathFactory#createAndValidatePathToStructure`, not one-to-one + - `worldTemplates`, `testTemplates` - The template path factories. +- `net.minecraft.world.level.levelgen.structure.templatesystem.loader` + - `DirectoryTemplateSource` - A template source for some directory. + - `ResourceManagerTemplateSource` - A template source for the resource manager. + - `TemplatePathFactory` - A factory that gets the path to some structure. + - `TemplateSource` - A loader for structure templates. +- `net.minecraft.world.level.storage` + - `LevelStorageSource` + - `getLevelDataAndDimensions` now takes in the `$LevelStorageAccess` + - `readExistingSavedData` - Reads any existing saved data. + - `writeGameRules` - Writes the game rules to the saved data. + - `$LevelStorageAccess#releaseTemporarilyAndRun` - Releases the access and runs before recreating the lock. + - `collectIssues` - Collects any issues when attempting to upgrade the data. + - `getSummary` -> `fixAndGetSummary`, `fixAndGetSummaryFromTag`; not one-to-one + - `getDataTag` -> `getUnfixedDataTag`, not one-to-one + - `getDataTagFallback` -> `getUnfixedDataTagWithFallback`, not one-to-one + - `saveDataTag` no longer takes in the `RegistryAccess` + - `saveLevelData` - Saves the level dat. + - `LevelSummary` now takes in whether it requires file fixing + - `UPGRADE_AND_PLAY_WORLD` - A component telling the user to upgrade their world and play. + - `requiresFileFixing` - Whether the level requires file fixing. + - `$BackupStatus#FILE_FIXING_REQUIRED` - Whether file fixing is require to play this level on this version. + +#### Chat Permissions + +The chat system now has an associated set of permissions indicating what messages the player can send or receive. `Permissions#CHAT_SEND_MESSAGES` and `CHAT_SEND_COMMANDS` determine if the player can send messages or commands, respectively. Likewise, `CHAT_RECEIVE_PLAYER_MESSAGES` and `CHAT_RECEIVE_SYSTEM_MESSAGES` if the player can receive messages from other players or the system, respectively. Note that all of these permissions are only handled clientside and are not validated serverside. + +- `net.minecraft.SharedConstants#DEBUG_CHAT_DISABLED` - A flag that disables the chat box. +- `net.minecraft.client` + - `GuiMessage` -> `.multiplayer.chat.GuiMessage` + - `GuiMessageTag` -> `.multiplayer.chat.GuiMessageTag` + - `Minecraft` + - `getChatStatus` -> `computeChatAbilities`, not one-to-one + - `$ChatStatus` -> `ChatRestriction`, not one-to-one +- `net.minecraft.client.gui.Gui#setChatDisabledByPlayerShown`, `isShowingChatDisabledByPlayer` - Handles whether the chat is disabled by the shown player. +- `net.minecraft.client.gui.components` + - `ChatComponent` + - `GO_TO_RESTRICTIONS_SCREEN` - An identifier for redirecting to the restrictions screen. + - `setVisibleMessageFilter` - Sets the message filter function. + - `render`, `captureClickableText` now take in the `$DisplayMode` instead of a `boolean` for if the player is chatting + - `addMessage` is now private + - Split for use into `addClientSystemMessage`, `addServerSystemMessage`, `addPlayerMessage` + - `$DisplayMode` - How the chat should be displayed. + - `CommandSuggestions` + - `USAGE_FORMAT`, `USAGE_OFFSET_FROM_BOTTOM`, `LINE_HEIGHT` - Constants for showing the command suggestions. + - `setRestrictions` - Sets the restrictions of the messages that can be typed. + - `hasAllowedInput` - Whether the chat box can allow input. +- `net.minecraft.client.gui.screens.ChatScreen#USAGE_BACKGROUND_COLOR` - The background color of the command suggestions box. +- `net.minecraft.client.gui.screens.multiplayer.RestrictionsScreen` - A screen for settings the restrictions of the player's chat box. +- `net.minecraft.client.gui.screens.reporting.ReportPlayerScreen` now takes in a `boolean` for if the chat is disabled or blocked +- `net.minecraft.client.multiplayer.chat` + - `ChatAbilities` - The set of restrictions the player has on chatting with the chat box. + - `ChatListener` + - `handleSystemMessage` `boolean` is now used for if the system is remote instead of overlay + - The overlay is now handled through `handleOverlay` + - `GuiMessageSource` - The source the message came from. +- `net.minecraft.client.player.LocalPlayer` now takes in the `ChatAbilities` + - `chatAbilities`, `refreshChatAbilities` - Handles the chat abilities. +- `net.minecraft.server.permissions.Permissions` + - `CHAT_SEND_MESSAGES` - If the player can send chat messages. + - `CHAT_SEND_COMMANDS` - If the player can send commands. + - `CHAT_RECEIVE_PLAYER_MESSAGES` - If the player can receive other player messages. + - `CHAT_RECEIVE_SYSTEM_MESSAGES` - If the player can receive system messages. + - `CHAT_PERMISSIONS` - A set of available chat permissions. +- `net.minecraft.world.entity.player.Player#displayClientMessage` split into `sendSystemMessage` when overlay message was `false`, and `sendOverlayMessage` when the overlay message was `true` + +#### More Entity Sound Variant Registries + +Cats, chickens, cows, and pigs now have sound variants: a databack registry object that specifies the sounds an entity plays. This does not need to be directly tied to an actual entity variant, as it only defines the sounds an entity plays, typically during `Mob#finalizeSpawn`. + +For cows: + +```json5 +// A file located at: +// - `data/examplemod/cow_sound_variant/example_cow_sound.json` +{ + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.cow.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.cow.death", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.cow.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.cow.step" +} +``` + +For chickens and pigs: + +```json5 +// A file located at: +// - `data/examplemod/chicken_sound_variant/example_chicken_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.chicken.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.chicken.death", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.chicken.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.chicken.step" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_chicken.ambient", + "death_sound": "minecraft:entity.baby_chicken.death", + "hurt_sound": "minecraft:entity.baby_chicken.hurt", + "step_sound": "minecraft:entity.baby_chicken.step" + } +} +``` + +For pigs: + +```json5 +// A file located at: +// - `data/examplemod/pig_sound_variant/example_pig_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle. + "ambient_sound": "minecraft:entity.pig.ambient", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.pig.death", + // The registry name of the sound event to play when eating. + "eat_sound": "minecraft:entity.pig.eat", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.pig.hurt", + // The registry name of the sound event to play when stepping. + "step_sound": "minecraft:entity.pig.step" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_pig.ambient", + "death_sound": "minecraft:entity.baby_pig.death", + "eat_sound": "minecraft:entity.baby_pig.eat", + "hurt_sound": "minecraft:entity.baby_pig.hurt", + "step_sound": "minecraft:entity.baby_pig.step" + } +} +``` + +For cats: + +```json5 +// A file located at: +// - `data/examplemod/cat_sound_variant/example_cat_sound.json` +{ + // The sounds played when an entity's age is greater than or equal to 0 (an adult). + "adult_sounds": { + // The registry name of the sound event to play randomly on idle when tamed. + "ambient_sound": "minecraft:entity.cat.ambient", + // The registry name of the sound event to play when non-tamed and tempted by food. + "beg_for_food_sound": "minecraft:entity.cat.beg_for_food", + // The registry name of the sound event to play when killed. + "death_sound": "minecraft:entity.cat.death", + // The registry name of the sound event to play when fed. + "eat_sound": "minecraft:entity.cat.eat", + // The registry name of the sound event to play when hissing, typically at a pursuing phantom. + "hiss_sound": "minecraft:entity.cat.hiss", + // The registry name of the sound event to play when hurt. + "hurt_sound": "minecraft:entity.cat.hurt", + // The registry name of the sound event to play when purring, typically when in love or lying down. + "purr_sound": "minecraft:entity.cat.purr", + // The registry name of the sound event to play randomly on idle when tamed 25% of the time. + "purreow_sound": "minecraft:entity.cat.purreow", + // The registry name of the sound event to play randomly on idle when not tamed. + "stray_ambient_sound": "minecraft:entity.cat.stray_ambient" + }, + // The sounds played when an entity's age is less than 0 (a baby). + "baby_sounds": { + "ambient_sound": "minecraft:entity.baby_cat.ambient", + "beg_for_food_sound": "minecraft:entity.baby_cat.beg_for_food", + "death_sound": "minecraft:entity.baby_cat.death", + "eat_sound": "minecraft:entity.baby_cat.eat", + "hiss_sound": "minecraft:entity.baby_cat.hiss", + "hurt_sound": "minecraft:entity.baby_cat.hurt", + "purr_sound": "minecraft:entity.baby_cat.purr", + "purreow_sound": "minecraft:entity.baby_cat.purreow", + "stray_ambient_sound": "minecraft:entity.baby_cat.stray_ambient" + } +} +``` + +- `net.minecraft.core.registries.Registries` + - `CAT_SOUND_VARIANT` - The registry key for the sounds a cat should make. + - `CHICKEN_SOUND_VARIANT` - The registry key for the sounds a chicken should make. + - `COW_SOUND_VARIANT` - The registry key for the sounds a cow should make. + - `PIG_SOUND_VARIANT` - The registry key for the sounds a pig should make. +- `net.minecraft.network.synched.EntityDataSerializers` + - `CAT_SOUND_VARIANT` - The entity serializer for the sounds a cat should make. + - `CHICKEN_SOUND_VARIANT` - The entity serializer for the sounds a chicken should make. + - `COW_SOUND_VARIANT` - The entity serializer for the sounds a cow should make. + - `PIG_SOUND_VARIANT` - The entity serializer for the sounds a pig should make. +- `net.minecraft.sounds.SoundEvents` + - `CAT_*` sounds are now either `Holder$Reference`s or stored in the map of `CAT_SOUNDS` + - `CHICKEN_*` sounds are now either `Holder$Reference`s or stored in the map of `CHICKEN_SOUNDS` + - `COW_*` sounds are stored in the map of `COW_SOUNDS` + - `PIG_*` sounds are now either `Holder$Reference`s or stored in the map of `PIG_SOUNDS` +- `net.minecraft.world.entity.animal.chicken` + - `ChickenSoundVariant` - The sounds that are played for a chicken variant. + - `ChickenSoundVariants` - All vanilla chicken variants. +- `net.minecraft.world.entity.animal.cow` + - `AbstractCow#getSoundSet` - Gets the sounds a cow makes. + - `CowSoundVariant` - The sounds that are played for a cow variant. + - `CowSoundVariants` - All vanilla cow variants. +- `net.minecraft.world.entity.animal.feline` + - `CatSoundVariant` - The sounds that are played for a cat variant. + - `CatSoundVariants` - All vanilla cat variants. +- `net.minecraft.world.entity.animal.chicken` + - `ChickenSoundVariant` - The sounds that are played for a chicken variant. + - `ChickenSoundVariants` - All vanilla chicken variants. +- `net.minecraft.world.entity.animal.pig` + - `PigSoundVariant` - The sounds that are played for a pig variant. + - `PigSoundVariants` - All vanilla pig variants. + +#### Audio Changes + +Audio devices are now handled through the `DeviceTracker` which, depending on the backing machine, allows for either the machine to send system events when audio devices change, or using a standard polling interval to requery the list of available devices. + +- `com.mojang.blaze3d.audio` + - `AbstractDeviceTracker` - An abstract tracker for managing the changes of audio devices. + - `CallbackDeviceTracker` - A device tracker that uses the SOFT system events callback to determine changes. + - `DeviceList` - A list of all audio devices, including the default device, if available. + - `DeviceTracker` - An interface for managing the changes of audio devices. + - `Library` + - `NO_DEVICE` is now `public` from `private` + - `init` now takes in the `DeviceList` + - `getDefaultDeviceName` moved to `DeviceList#defaultDevice` + - `getCurrentDeviceName` -> `currentDeviceName` + - `hasDefaultDeviceChanged` moved to `AbstractDeviceTracker`, not one-to-one + - `getAvailableSoundDevices` moved to `DeviceList`, not one-to-one + - `createDeviceTracker` - Creates the tracker for managing audio device changes. + - `getDebugString` -> `getChannelDebugString` + - `PollingDeviceTracker` - A device tracker that uses polling intervals to determine changes. + - `SoundBuffer` + - `format` - The format of the sound stream. + - `size` - The number of bytes in the sound stream. + - `isValid` - If the sound stream is in a valid state. +- `net.minecraft.client.Options` + - `DEFAULT_SOUND_DEVICE` is now `private` from `public` + - `isSoundDeviceDefault` - Checks if the device is the default audio device. +- `net.minecraft.client.gui.components.debug` + - `DebugEntrySoundCache` - A debug entry displaying the current cache for loaded sound streams. + - `DebugScreenEntries#SOUND_CACHE` - The identifier for the sound stream cache debug information. +- `net.minecraft.client.sounds` + - `SoundBufferLibrary` + - `enumerate` - Loops through all cached sounds, outputting its id, size, and format. + - `$DebugOutput` - An interface that accepts some sound metadata. + - `$Counter` - An output implementation that keepts track of the number of sound streams and the total size. + - `SoundEngine` + - `getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; not one-to-one + - `$DeviceCheckState` is removed + - `SoundManager#getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; not one-to-one + +#### Input Message Editor Support + +Minecraft now has support for Input Message Editors (IME), which allow complex characters from languages like Chinese or Hindi to be inputted instead of the temporary preedit text. The preedit text is displayed as an overlay within the game, while any other IME features provided by the host OS. With this addition, support can be added within screens through `GuiEventListener#preeditUpdated`, or by using an existing vanilla widget which implements the method. + +- `com.mojang.blaze3d.platform` + - `InputConstants#setupKeyboardCallbacks` now takes in the `GLFWCharCallbackI` instead of `GLFWCharModsCallbackI` for the character typed callback, `GLFWPreeditCallbackI` to handle inputting complex characters via an input method editor, and `GLFWIMEStatusCallbackI` for notifying about the status of the editor + - `MessageBox` - A utility for creating OS native messages boxes. + - `TextInputManager` - A manager for handling when text is inputted in the game window. + - `setTextInputArea` - Sets the area where the predicted text cursor should appear. + - `startTextInput`, `stopTextInput` - Handles toggling the input message editor. +- `net.minecraft.client` + - `KeyboardHandler` + - `resubmitLastPreeditEvent` - Repeats the last preedit event that was sent. + - `submitPreeditEvent` - Tells the listener that the preedit text has been updated. + - `Minecraft` + - `textInputManager` - Returns the input manager. + - `onTextInputFocusChange` - Changes the editor input status based on if the text input is focused. +- `net.minecraft.client.gui.GuiGraphics` + - `setPreeditOverlay` - Sets the overlay drawing the preedit text. + - `renderDeferredElements` now takes in the `int`s for the mouse position and the game time delta ticks `float` +- `net.minecraft.client.gui.components` + - `IMEPreeditOverlay` - The overlay for displaying the preedit text for an input message editor. + - `TextCursorUtils` - A utility for drawing the text cursor. +- `net.minecraft.client.gui.components.events.GuiEventListener#preeditUpdated` - Listens for when the preedit text changes. +- `net.minecraft.client.input` + - `CharacterEvent` no longer takes in the modifier `int` set + - `PreeditEvent` - An event containing the preedit text along with the cursor location. + +#### Cauldron Interaction Dispatchers + +Cauldron interactions have been reorganized somewhat, with all registration being moved to `CauldronInteractions` from `CauldronInteraction`. In addition, the backing `$InteractionMap` for a cauldron type has been replaced with a `$Dispatcher` that can register interactions for both tags and items. Tags are checked before items. + +```java +CauldronInteractions.EMPTY.put( + // The Item or TagKey to use + ItemTags.WOOL, + // The cauldron interaction to apply + (state, level, pos, player, hand, itemInHand) -> InteractionResult.TRY_WITH_EMPTY_HAND +); +``` + +- `net.minecraft.core.cauldron` + - `CauldronInteraction` + - All fields regarding to registering interactions to a map have been moved to `CauldronInteractions` + - `INTERACTIONS` -> `CauldronInteractions#ID_MAPPER`, now `private` + - `DEFAULT` - The default interaction with a cauldron + - `$InteractionMap` -> `$Dispatcher`, not one-to-one + - `CauldronInteractions` - All vanilla cauldron interactions. + +#### Rule-Based Block State Providers + +`RuleBasedStateProvider` now extends `BlockStateProvider`, allowing it to be used wherever a state provider is required. It's implementation hasn't changed, now only requiring `rule_based_state_provider` to be specified as the `type`. As such, all configurations that used `RuleBasedBlockStateProvider` have been broadened to allow any `BlockStateProvider`. + +- `net.minecraft.world.level.levelgen.feature.configurations` + - `DiskConfiguration` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `TreeConfiguration` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `belowTrunkProvider` is now a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` + - `$TreeConfigurationBuilder` now takes in a `BlockStateProvider` instead of a `RuleBasedBlockStateProvider` +- `net.minecraft.world.level.levelgen.feature.stateproviders` + - `BlockStateProvider#getOptionalState` - Gets the state of the block, or otherwise `null`. + - `BlockStateProviderType#RULE_BASED_STATE_PROVIDER` - The type for the rule based state provider. + - `RuleBasedBlockStateProvider` -> `RuleBasedStateProvider`, now a class, implementing `BlockStateProvider` + - The constructor can now take in a nullable fallback `BlockStateProvider` + - `ifTrueThenProvide` - If the predicate is true, provide the given block. + - `simple` -> `always` + - `$Builder` - A builder for constructing the rules for the block to place. + +#### Fluid Logic Reorganization + +Generic entity fluid movement has been moved into a separate `EntityFluidInteraction` class, where all tracked fluids are updated and then potentially pushed by the current at a layer time. + +- `net.minecraft.world.entity` + - `Entity` + - `updateInWaterStateAndDoFluidPushing` -> `updateFluidInteraction`, not one-to-one + - `updateFluidHeightAndDoFluidPushing` -> `EntityFluidInteraction#update` + - `getFluidInteractionBox` - Gets the bounding box of the entity during fluid interactions. + - `modifyPassengerFluidInteractionBox` - Returns the modified bounding box of the entity when riding in some vehicle. + - `EntityFluidInteraction` - A handler for managing the fluid interactions and basic movement with an entity. +- `net.minecraft.world.level.chunk.LevelChunkSection#hasFluid` - Whether the chunk section has a fluid block. + +#### Removal of Random Patch Feature + +The random patch feature has been completely removed in favor of using placements like most other features. To convert, the `ConfiguredFeature` defined as part of the configuration should be its own file. Then, the placements should specify the `CountPlacement`, followed by the `RandomOffsetPlacement` using a `TrapezoidInt`, and finished with a `BlockPredicateFilter`: + +```json5 +// In `data/examplemod/worldgen/configured_feature/example_configured_feature.json` +{ + // Previously config.feature.feature + "type": "minecraft:simple_block", + "config": { + "to_place": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:sweet_berry_bush", + "Properties": { + "age": "3" + } + } + } + } +} + +// In `data/examplemod/worldgen/placed_feature/example_placed_feature.json` +{ + "feature": "examplemod:example_configured_feature", + "placement": [ + { + // Previously config.tries + "type": "minecraft:count", + "count": 96 + }, + { + "type": "minecraft:random_offset", + "xz_spread": { + // Previously config.xz_spread + // The min and max are additive inverses + "type": "minecraft:trapezoid", + "max": 7, + "min": -7, + "plateau": 0 + }, + "y_spread": { + // Previously config.y_spread + "type": "minecraft:trapezoid", + "max": 3, + "min": -3, + "plateau": 0 + } + }, + { + // Previously config.feature.placement + // This contains the placements of the original placed feature + "type": "minecraft:block_predicate_filter", + "predicate": { + "type": "minecraft:all_of", + "predicates": [ + { + "type": "minecraft:matching_block_tag", + "tag": "minecraft:air" + }, + { + "type": "minecraft:matching_blocks", + "blocks": "minecraft:grass_block", + "offset": [ 0, -1, 0 ] + } + ] + } + } + ] +} +``` + +- `net.minecraft.data.worldgen.features` + - `FeatureUtils#simpleRandomPatchConfiguration`, `simplePatchConfiguration` are removed + - Typically replaced by `Feature#SIMPLE_BLOCK` with placements for random offset and filters + - `NetherFeatures#PATCH_*` fields no longer has the `PATCH_*` prefix + - `VegetationFeatures` + - `PATCH_*` fields no longer has the `PATCH_*` prefix + - `WILDFLOWERS_BIRCH_FOREST`, `WILDFLOWERS_MEADOW` -> `WILDFLOWER`, not one-to-one + - `PALE_FOREST_FLOWERS` -> `PALE_FOREST_FLOWER` +- `net.minecraft.world.level.biome.BiomeGenerationSettings#getFlowerFeatures` -> `getBoneMealFeatures` +- `net.minecraft.world.level.levelgen.feature` + - `ConfiguredFeature#getFeatures` -> `getSubFeatures`, now returning a stream of holders-wrapped `ConfiguredFeature`s without this feature + - `Feature` + - `FLOWER`, `NO_BONEMEAL_FLOWER` are removed + - `RANDOM_PATCH` is removed + - `RandomPatchFeature` class is removed +- `net.minecraft.world.level.levelgen.feature.configurations` + - `FeatureConfiguration#getFeatures` -> `getSubFeatures`, now returning a stream of holders-wrapped `ConfiguredFeature`s + - `RandomPatchConfiguration` record is removed +- `net.minecraft.world.level.levelgen.placement.PlacedFeature#getFeatures` now returns a stream of holders-wrapped `ConfiguredFeature`s with this feature concatenated + +#### Specific Logic Changes + +- Picture-In-Picture submission calls are now taking in `0xF000F0` instead of `0x000000` for the light coordinates. +- `net.minecraft.client.multiplayer.RegistryDataCollector#collectGameRegistries` `boolean` parameter now handles only updating components from synchronized registries along with tags. +- `net.minecraft.client.renderer.RenderPipelines#VIGNETTE` now blends the alpha with a source of zero and a destination of one. +- `net.minecraft.server.packs.PathPackResources#getResource`, `listPath`, `listResources` resolves the path using the identifier's namespace first. +- `net.minecraft.world.entity.EntitySelector#CAN_BE_PICKED` can now find entities in spectator mode, assuming `Entity#isPickable` is true. +- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#requires` is no longer implemented by default. +- `net.minecraft.world.level.levelgen.WorldOptions#generate_features` field in JSON has been renamed to `generate_structures` to match its java field name. +- `net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate#ONLY_IN_AIR_PREDICATE` now matches the air tag instead of just the air block. +- `net.minecraft.world.level.timers` + - `FunctionCallback`, `FunctionTagCallback` now use `id` instead of `Name` when serializing + - `TimerCallbacks` now uses `type` instead of `Type` when serializing + +#### Data Component Additions + +- `dye` - Sets the item as a dye material, used in specific circumstances. +- `additional_trade_cost` - A modifier that offsets the trade cost by the specified amount. +- `pig/sound_variant` - The sounds a pig should make. +- `cow/sound_variant` - The sounds a cow should make. +- `chicken/sound_variant` - The sounds a chicken should make. +- `cat/sound_variant` - The sounds a cat should make. + +#### Environment Attribute Additions + +- `visual/block_light_tint` - Tints the color of the light emitted by a block. +- `visual/night_vision_color` - The color when night vision is active. +- `visual/ambient_light_color` - The color of the ambient light in an environment. + +#### Tag Changes + +- `minecraft:block` + - `bamboo_plantable_on` -> `supports_bamboo` + - `mushroom_grow_block` -> `overrides_mushroom_light_requirement` + - `small_dripleaf_placeable` -> `supports_small_dripleaf` + - `big_dripleaf_placeable` -> `supports_big_dripleaf` + - `dry_vegetation_may_place_on` -> `supports_dry_vegetation` + - `snow_layer_cannot_survive_on` -> `cannot_support_snow_layer` + - `snow_layer_can_survive_on` -> `support_override_snow_layer` + - `enables_bubble_column_drag_down` + - `enables_bubble_column_push_up` + - `supports_vegetation` + - `supports_crops` + - `supports_stem_crops` + - `supports_stem_fruit` + - `supports_pumpkin_stem` + - `supports_melon_stem` + - `supports_pumpkin_stem_fruit` + - `supports_melon_stem_fruit` + - `supports_sugar_cane` + - `supports_sugar_cane_adjacently` + - `supports_cactus` + - `supports_chorus_plant` + - `supports_chorus_flower` + - `supports_nether_sprouts` + - `supports_azalea` + - `supports_warped_fungus` + - `supports_crimson_fungus` + - `supports_mangrove_propagule` + - `supports_hanging_mangrove_propagule` + - `supports_nether_wart` + - `supports_crimson_roots` + - `supports_warped_roots` + - `supports_wither_rose` + - `supports_cocoa` + - `supports_lily_pad` + - `supports_frogspawn` + - `support_override_cactus_flower` + - `cannot_support_seagrass` + - `cannot_support_kelp` + - `grows_crops` + - `mud` + - `moss_blocks` + - `grass_blocks` + - `substrate_overworld` + - `beneath_tree_podzol_replaceable` + - `beneath_bamboo_podzol_replaceable` + - `cannot_replace_below_tree_trunk` + - `ice_spike_replaceable` + - `forest_rock_can_place_on` + - `huge_brown_mushroom_can_place_on` + - `huge_red_mushroom_can_place_on` + - `prevents_nearby_leaf_decay` +- `minecraft:enchantment` + - `trades/desert_special` is removed + - `trades/jungle_special` is removed + - `trades/plains_special` is removed + - `trades/savanna_special` is removed + - `trades/snow_special` is removed + - `trades/swamp_special` is removed + - `trades/taiga_special` is removed +- `minecraft:entity_type` + - `cannot_be_age_locked` +- `minecraft:fluid` + - `supports_sugar_cane_adjacently` + - `supports_lily_pad` + - `supports_frogspawn` + - `bubble_column_can_occupy` +- `minecraft:item` + - `metal_nuggets` + - `dyeable` is removed, split between: + - `dyes` + - `loom_dyes` + - `loom_patterns` + - `cauldron_can_remove_due` + - `cat_collar_dyes` + - `wolf_collar_dyes` + - `mud` + - `moss_blocks` + - `grass_blocks` +- `minecraft:potion` + - `tradable` +- `minecraft:worldgen/configured_feature` + - `can_spawn_from_bone_meal` + +#### List of Additions + +- `net.minecraft.advancements.criterion` + - `FoodPredicate` - A criterion predicate that can check the food level and saturation. + - `MinMaxBounds` + - `validateContainedInRange` - Returns a function which validates the target range and returns as a data result. + - `$Bounds#asRange` - Converts the bounds into a `Range`. +- `net.minecraft.client` + - `Minecraft#sendLowDiskSpaceWarning` - Sends a system toast for low disk space. + - `Options#keyDebugLightmapTexture` - A key mapping to show the lightmap texture. +- `net.minecraft.client.gui.components` + - `AbstractScrollArea` + - `scrollbarWidth` - The width of the scrollbar. + - `defaultSettings` - Constructs the default scrollbar settings given the scroll rate. + - `$ScrollbarSettings` - A record containing the metadata for the scrollbar. + - `DebugScreenOverlay` + - `showLightmapTexture` - Whether to render the lightmap texture on the overlay. + - `toggleLightmapTexture` - Toggles whether the lightmap texture should be rendered. + - `ScrollableLayout` + - `setMinHeight` - Sets the minimum height of the container layout. + - `$ReserveStrategy` - What to use when reserving the width of the scrollbar within the layout. + - `Tooltip` + - `component` - The component of a tooltip to display. + - `style` - The identifier used to compute the tooltip background and frame. +- `net.minecraft.client.gui.components.debug` + - `DebugEntryDetailedMemory` - A debug entry displaying the detailed memory usage. + - `DebugEntryLookingAt#getHitResult` - Gets the hit result of the camera entity. + - `DebugEntryLookingAtEntityTags` - A debug entry for displaying an entity's tags. + - `DebugScreenEntries` + - `DETAILED_MEMORY` - The identifier for the detailed memory usage debug entry. + - `LOOKING_AT_ENTITY_TAGS` - The identifier for the entity tags debug entry. +- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation#with` - Sets the previous focus of the navigation. +- `net.minecraft.client.gui.screens.GenericWaitingScreene#createWaitingWithoutButton` - Creates a waiting screen without showing the button to cancel. +- `net.minecraft.client.gui.screens.options` + - `DifficultyButtons` - A class containing the layout element to create the difficulty buttons. + - `HasGamemasterPermissionReaction` - An interface marking an option screen as able to respond to changing gamemaster permissions. + - `OptionsScreen#getLastScreen` - Returns the previous screen that navigated to this one. + - `WorldOptionsScreen` - A screen containing the options for the current world the player is in. +- `net.minecraft.client.gui.screens.worldselection.EditWorldScreen#conditionallyMakeBackupAndShowToast` - Only makes the backup and shows a toast if the passed in `boolean` is true; otherwise, returns a `false` future. +- `net.minecraft.client.multiplayer.MultiPlayerGameMode#spectate` - Sends a packet to the server that the player will spectate the given entity. +- `net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler#onTeleport` - Runs when a player is moved on the server, typically from some kind of teleportation (e.g. commands, riding an entity). +- `net.minecraft.client.renderer` + - `LightmapRenderStateExtractor` - Extracts the render state for the lightmap. + - `UiLightmap` - The lightmap when in a user interface. + - `RenderPipelines` + - `LINES_DEPTH_BIAS` - A render pipeline that sets the polygon depth offset factor to -1 and the units to -1. + - `ENTITY_CUTOUT_DISSOLVE` - A render pipeline that dissolves an entity model into the background using a mask sampler. +- `net.minecraft.client.renderer.rendertype.RenderType#hasBlending` - Whether the pipeline has a defined blend function. +- `net.minecraft.commands.ArgumentVisitor` - A helper for visiting the arguments for a command. +- `net.minecraft.commands.arguments.selector.EntitySelector#COMPILABLE_CODEC` - A `CompilableString` codec wrapped around an `EntitySelectorParser`. +- `net.minecraft.core.component.predicates` + - `DataComponentPredicates#VILLAGER_VARIANT` - A predicate that checks a villager type. + - `VillagerTypePredicate` - A predicate that checks a villager's type. +- `net.minecraft.core.dispenser.SpawnEggItemBehavior` - The dispenser behavior for spawn eggs. +- `net.minecraft.core.registries.ConcurrentHolderGetter` - A getter that reads references from a local cache, synchronizing to the original when necessary. +- `net.minecraft.data` + - `BlockFamilies` + - `END_STONE` - A family for end stone variants. + - `getFamily` - Gets the family for the base block, when present. + - `BlockFamily` + - `$Builder#tiles`, `$Variant#TILES` - The block that acts as the tiles variant for some base block. + - `$Builder#bricks`, `$Variant#BRICKS` - The block that acts as the bricks variant for some base block. + - `$Builder#cobbled`, `$Variant#COBBLED` - The block that acts as the cobbled variant from some base block. + - `DataGenerator$Uncached` - A data generator which does not cache any information about the files generated. +- `net.minecraft.data.recipes.RecipeProvider` + - `bricksBuilder`, `tilesBuilder` - Builders for the bricks and tiles block variants. + - `generateCraftingRecipe`, `generateStonecutterRecipe` - Generates the appropriate recipes for the given block family. + - `getBaseBlock` -> `getBaseBlockForCrafting` + - `bredAnimal` - Unlocks the recipe if the player has bred two animals together. +- `net.minecraft.gametest.framework` + - `GameTestEvent#createWithMinimumDelay` - Creates a test event with some minimum delay. + - `GameTestHelper` + - `getBoundsWithPadding` - Gets the bounding box of the test area with the specified padding. + - `runBeforeTestEnd` - Runs the runnable at one tick before the test ends. + - `despawnItem` - Despawns all item entities within the distance of the position. + - `discard` - Discards the entity. + - `setTime` - Sets the time of the dimension's default clock. + - `placeBlock` - Places the given block at the relative position and direction. + - `GameTestInstance#padding` - The number of blocks spaced around each game test. + - `GameTestSequence#thenWaitAtLeast` - Waits for at least the specified number of ticks before running the runnable. +- `net.minecraft.nbt.TextComponentTagVisitor` + - `$PlainStyling` - A styling that stores the nbt in a component literal map. + - `$RichStyling` - A styling that stores the nbt with syntax highlighting and formatting. + - `$Styling` - An interface defining how the read tag should be styled. + - `$Token` - The tokens used to more richly represent the tag datas. +- `net.minecraft.network.chat.ResolutionContext` - The context that the component is being resolved to a string within. +- `net.minecraft.network.chat.contents.NbtContents#NBT_PATH_CODEC` - A `CompilableString` codec wrapped around a `NbtPathArgument$NbtPath`. +- `net.minecraft.network.chat.contents.data.BlockDataSource#BLOCK_POS_CDEC` - A `CompilableString` codec wrapped around `Coordinates`. +- `net.minecraft.network.protocol.game` + - `ClientboundGameRuleValuesPacket` - A packet that sends the game rule values in string form to the client. + - `ClientboundGamePacketListener#handleGameRuleValues` - Handles the game rule values sent from the server. + - `ClientboundLowDiskSpaceWarningPacket` - A packet sent to the client warning about low disk space on the machine. + - `ClientGamePacketListener#handleLowDiskSpaceWarning` - Handles the warning packet about low disk space. + - `ServerboundAttackPacket` - A packet sent to the server about what entity the player attacked. + - `ServerboundClientCommandPacket$Action#REQUEST_GAMERULE_VALUES` - Requests the game rule values from the server. + - `ServerboundSetGameRulePacket` - A packet that sends the game rules entries to set from the client. + - `ServerboundSpectateEntityPacket` - A packet sent to the server about what entity the player wants to spectate. + - `ServerGamePacketListener` + - `handleAttack` - Handles the player's attack on an entity. + - `handleSpectateEntity` - Handles the player wanting to spectate an entity. + - `handleSetGameRule` - Handles setting the game rules from the client. +- `net.minecraft.resources` + - `FileToIdConverter#extensionMatches` - Checks if the identifier ends with the specified extension. + - `Identifier` + - `ALLOWED_NAMESPACE_CHARACTERS` - The characters allowed in an identifier's namespace. + - `resolveAgainst` - Resolves the path from the given root by checking `//`. +- `net.minecraft.server` + - `Bootstrap#shutdownStdout` - Closes the stdout stream. + - `MinecraftServer` + - `DEFAULT_GAME_RULES` - The supplied default game rules for a server. + - `warnOnLowDiskSpace` - Sends a warning if the disk space is below 64 MiB. + - `sendLowDiskSpaceWarning` - Sends a warning for low disk space. +- `net.minecraft.server.commands.SwingCommand` - A command that calls `LivingEntity#swing` for all targets. +- `net.minecraft.server.level.ServerPlayer` + - `sendBuildLimitMessage` - Sends an overlay message if the player cannot build anymore in the cooresponding Y direction. + - `sendSpawnProtectionMessage` - Sends an overlay message if the player cannot modify the terrain due to spawn protection. +- `net.minecraft.server.packs.AbstractPackResources#loadMetadata` - Loads the root `pack.mcmeta`. +- `net.minecraft.server.packs.resources.ResourceMetadata$MapBased` - A resource metadata that stores the sections in a map. +- `net.minecraft.tags.TagLoader$ElementLookup#fromGetters` - Constructs an element lookup from the given `HolderGetter`s depending on whether the element is required or not. +- `net.minecraft.util` + - `ARGB#gray` - Gets a grayscale color based on the given brightness. + - `CompilableString` - A utility for taking some string pattern and compiling it to an object through some parser. + - `LightCoordsUtil` - A utility for determining the light coordinates from light values. + - `ProblemReporter$MapEntryPathElement` - A path element for some entry key in a map. + - `Util#allOfEnumExcept` - Gets the set of all enums except the provided value. +- `net.minecraft.util.thread.BlockableEventLoop#hasDelayedCrash` - Whether there is a crash report queued. +- `net.minecraft.util.valueproviders.TrapezoidInt` - Samples a random value with a trapezoidal distribution. +- `net.minecraft.world.InteractionHand#STREAM_CODEC` - The network codec for the interaction hand. +- `net.minecraft.world.attribute` + - `AttributeType#toFloat` - Gets the attribute value as a `float`, or throws an exception if not defined. + - `AttributeTypes#INTEGER` - An integer attribute type. + - `LerpFunction#ofInteger` - A lerp function for an integer value. +- `net.minecraft.world.attribute.modifier` + - `AttributeModifier#INTEGER_LIBRARY` - A library of operators to apply for integers. + - `IntegerModifier` - A modifier that applies some argument to the integer value. +- `net.minecraft.world.entity` + - `AgeableMob` + - `AGE_LOCK_COOLDOWN_TICKS` - The number of ticks to wait before the entity can be age locked/unlocked. + - `ageLockParticleTimer` - The time for displaying particles while age locking/unlocking. + - `Entity` + - `applyEffectsFromBlocksForLastMovements` - Applies any block effects to this entity for the last movement, used by items. + - `$Flags` - An annotation that marks a particular value as a bitset of flags for an entity. + - `LivingEntity#getLiquidCollisionShape` - Return's the bounds of the entity when attempting to collide with a liquid. + - `Mob` + - `asValidTarget` - Checks whether an entity is a valid target (can attack) for this entity. + - `getTargetUnchecked` - Gets the raw target without checking if its valid. + - `canAgeUp` - If the entity can grow up into a more mature variant. + - `setAgeLocked`, `isAgeLocked` - Whether the entity cannot grow up. + - `NeutralMob#getTargetUnchecked` - Gets the raw target without checking if its valid. + - `TamableAnimal#feed` - The player gives the stack as food, healing them either based on the stored component or some default value. +- `net.minecraft.world.entity.ai.behavior` + - `BehaviorControl#getRequiredMemories` - The list of memories required by the behavior. + - `GoAndGiveItemsToTarget$ItemThrower` - An interface that handles what should occur if an item is thrown because of this entity's behavior. +- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder$TriggerWithResult#memories` - The list of memories required by the behavior. +- `net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities#nearbyEntities` - The list of entities within the follow range of this one. +- `net.minecraft.world.entity.decoration.LeashFenceKnotEntity` + - `getKnot` - Finds the knot at the given position, else returns an empty optional. + - `createKnot` - Creates a new knot and adds it to the level. +- `net.minecraft.world.entity.monster.piglin` + - `PiglinAi` + - `MAX_TIME_BETWEEN_HUNTS` - The maximum number of seconds before a piglin begins to hunt again. + - `findNearbyAdultPiglins` - Returns a list of all adult piglins in this piglin's memory. +- `net.minecraft.world.entity.raid.Raid` + - `getBannerComponentPatch` - Gets the components of the banner pattern. + - `getOminousBannerTemplate` - Gets the stack template for the omnious banner. +- `net.minecraft.world.inventory.SlotRanges` + - `MOB_INVENTORY_SLOT_OFFSET` - The start index of a mob's inventory. + - `MOB_INVENTORY_SIZE` - The size of a mob's inventory. +- `net.minecraft.world.item.component.BundleContents#BEEHIVE_WEIGHT` - The weight of a beehive. +- `net.minecraft.world.item.enchantment.EnchantmentTarget#NON_DAMAGE_CODEC` - A codec that only allows the attacker and victim enchantment targets. +- `net.minecraft.world.level.block.BigDripleafBlock#canGrowInto` - Whether the dripleaf can grow into the specified position. +- `net.minecraft.world.level.block.grower.TreeGrower#getMinimumHeight` - If present, gets the base height of the trunk placer. +- `net.minecraft.world.level.block.state` + - `BlockBehaviour$PostProcess` - An interface that gets the position to mark for post-processing. + - `StateDefinition` + - `propertiesCodec` - The map codec for the state properties. + - `isSingletonState` - If the definition only contains one state. + - `StateHolder#isSingletonState` - If the holder only contains one state. +- `net.minecraft.world.level.block.state.properties` + - `NoteBlockInstrument` + - `TRUMPET` - The sound a copper block makes when placed under a note block. + - `TRUMPET_EXPOSED` - The sound an exposed copper block makes when placed under a note block. + - `TRUMPET_OXIDIZED` - The sound an oxidized copper block makes when placed under a note block. + - `TRUMPET_WEATHERED` - The sound a weathered copper block makes when placed under a note block. + - `Property$Value#valueName` - Gets the name of the value. +- `net.minecraft.world.level.dimension.DimensionDefaults` + - `BLOCK_LIGHT_TINT` - The default tint for the block light. + - `NIGHT_VISION_COLOR` - The default color when in night vision. + - `TURTLE_EGG_HATCH_CHANCE` - The chance of a turtle egg hatching on a random tick. +- `net.minecraft.world.level.gamerules.GameRule#getIdentifierWithFallback` - Gets the identifier of the game rule, or else the unregistered identifier. +- `net.minecraft.world.level.levelgen` + - `NoiseBasedChunkGenerator#getInterpolatedNoiseValue` - Gets the interpolated density at the given position, or the not-a-number value if the Y is outside the range of the noise settings. + - `NoiseChunk#getInterpolatedDensity` - Computes the full noise density. +- `net.minecraft.world.level.levelgen.feature.AbstractHugeMushroomFeature#MIN_MUSHROOM_HEIGHT` - The minimum mushroom height. +- `net.minecraft.world.level.levelgen.feature.configurations.BlockBlobConfiguration` - The configuration for the block blob feature. +- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer#getBaseHeight` - Returns the minimum height of the trunk. +- `net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement#ofTriangle` - Creates a trapezoidal distribution to select from for the XZ and Y range. +- `net.minecraft.world.level.material` + - `FluidState#isFull` - If the fluid amount is eight. + - `LavaFluid#LIGHT_EMISSION` - The amount of light the lava fluid emits. +- `net.minecraft.world.level.pathfinder.PathType#BIG_MOBS_CLOSE_TO_DANGER` - A path malus for mobs with an entity width greater than a block. +- `net.minecraft.world.level.storage.LevelStorageSource#writeWorldGenSettings` - Wriets the world generation settings to its saved data location. +- `net.minecraft.world.level.storage.loot.functions` + - `EnchantRandomlyFunction$Builder#withOptions` - Specifies the enchantments that can be used to randomly enchant this item. + - `SetRandomDyesFunction` - An item function that applies a random dye (if the item is in the `dyeable` tag) to the `DYED_COLOR` component from the provided list. + - `SetRandomPotionFunction` - An item function that applies a random potion to the `POTION_CONTENTS` component from the provided list. +- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#ADDITIONAL_COST_COMPONENT_ALLOWED` - Enables a trade to incur an additional cost if desired by the wanted stack or modifiers. +- `net.minecraft.world.level.storage.loot.predicates.EnvironmentAttributeCheck` - A loot condition that checks whether that given attribute matches the provided value. +- `net.minecraft.world.level.storage.loot.providers.number` + - `EnvironmentAttributeValue` - A provider that gets the attribute value as a float. + - `Sum` - A provider that sums the value of all provided number providers. +- `net.minecraft.world.phys.AABB$Builder#isDefined` - Checks if there is at least one point making up the bounding box. + +#### List of Changes + +- `net.minecraft.advancements.criterion` + - `EntityTypePredicate#matches` now takes in a holder-wrapped `EntityType` instead of the raw type itself + - `KilledTrigger$TriggerInstance#entityPredicate` -> `entity` + - `PlayerPredicate` now takes in a `FoodPredicate` + - Can be set using `PlayerPredicate$Builder#setFood` +- `net.minecraft.client.gui` + - `GuiGraphics` + - `blit` now has an overload that takes in the `GpuTextureView` and the `GpuSampler` + - `setTooltipForNextFrame` now has an overload that takes in a list of `FormattedCharSequence`s for the tooltip and whether to replace any existing tooltip + - `ItemSlotMouseAction#onSlotClicked` now takes in a `ContainerInput` instead of a `ClickType` +- `net.minecraft.client.gui.components` + - `AbstractContainerWidget` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `AbstractScrollArea` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `scrollbarVisible` -> `scrollable` + - `scrollBarY` is now public + - `scrollRate` is now longer abstract + - `AbstractTextAreaWidget` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `PopupScreen$Builder#setMessage` -> `addMessage`, not one-to-one + - `ScrollableLayout$Container` now takes in an `AbstractScrollArea$ScrollbarSettings` + - `Tooltip#create` now has an overload that takes in an optional `TooltipComponent` and style `Identifier` +- `net.minecraft.client.gui.components.debug` + - `DebugEntryLookingAtBlock`, `DebugEntryLookingAtFluid` -> `DebugEntryLookingAt` + - More specifically, `$BlockStateInfo`, `$BlockTagInfo`, `$FluidStateInfo`, `$FluidTagInfo` + - `DebugEntryLookingAtEntity#GROUP` is now public + - `DebugScreenEntries` + - `LOOKING_AT_BLOCK` -> `LOOKING_AT_BLOCK_STATE`, `LOOKING_AT_BLOCK_TAGS` + - `LOOKING_AT_FLUID` -> `LOOKING_AT_FLUID_STATE`, `LOOKING_AT_FLUID_TAGS` + - `DebugScreenEntryList` now takes in a `DataFixer` +- `net.minecraft.client.gui.components.tabs.TabNavigationBar#setWidth` -> `updateWidth`, not one-to-one +- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation` now takes in a nullable `ScreenRectangle` for the previous focus +- `net.minecraft.client.gui.screens` + - `ConfirmScreen#layout` is now final + - `DemoIntroScreen` replaced by `ClientPacketListener#openDemoIntroScreen`, now private + - `GenericWaitingScreen` now takes in three `boolean`s for showing the loading dots, the cancel button, and whether the screen should close on escape +- `net.minecraft.client.gui.screens.inventory.AbstractMountInventoryScreen#mount` is now final +- `net.minecraft.client.gui.screens.options` + - `OptionsScreen` now implements `HasGamemasterPermissionReaction` + - The constructor now takes in a `boolean` for if the player is currently in a world + - `createDifficultyButton` now handles within `WorldOptionsScreen#createDifficultyButtons`, not one-to-one + - `WorldOptionsScreen` now implements `HasGamemasterPermissionReaction` + - `createDifficultyButtons` -> `DifficultyButtons#create`, now public +- `net.minecraft.client.multiplayer` + - `ClientLevel#syncBlockState` can now take in a nullable player position + - `MultiPlayerGameMode#handleInventoryMouseClick` now takes in a `ContainerInput` instead of a `ClickType` + - `WeatherEffectRenderer#render` no longer takes in the `MultiBufferSource` +- `net.minecraft.client.renderer.block.ModelBlockRenderer$Cache#getLightColor` -> `getLightCoords` +- `net.minecraft.client.renderer.blockentity.state` + - `BrushableBlockRenderState#itemState` is now final + - `EndPortalRenderState` is now a final set of `Direction`s rather than an `EnumSet` + - `ShelfRenderState#items` is now final +- `net.minecraft.client.renderer.entity.state` + - `FallingBlockRenderState#movingBlockRenderState` is now final + - `HumanoidRenderState#attackArm` -> `ArmedEntityRenderState#attackArm` + - `WitherRenderState#xHeadRots`, `yHeadRots` are now final +- `net.minecraft.client.resources.sounds.AbstractSoundInstance#random` is now final +- `net.minecraft.commands.SharedSuggestionProvider#getCustomTabSugggestions` -> `getCustomTabSuggestions` +- `net.minecraft.commands.arguments.ComponentArgument#getResolvedComponent` now takes in a non-nullable `Entity` +- `net.minecraft.commands.arguments.selector.SelectorPattern` replaced by `CompilableString` +- `net.minecraft.core.HolderGetter$Provider#get`, `getOrThrow` now has overloads that take in the `TagKey` +- `net.minecraft.data` + - `BlockFamily` + - `shouldGenerateRecipe` -> `shouldGenerateCraftingRecipe`, `shouldGenerateStonecutterRecipe` + - `$Builder#dontGenerateRecipe` -> `dontGenerateCraftingRecipe`, `generateStonecutterRecipe` + - `DataGenerator` is now abstract + - The constructor now only takes in the `Path` output, not the `WorldVersion` or whether to always generate + - The original implementation can be founded in `DataGenerator$Cached` + - `run` is now abstract + - `Main#addServerProviders` -> `addServerDefinitionProviders`, no longer taking in the dev `boolean`, not one-to-one + - The remaining logic has been put into `addServerConverters`, taking in the dev `boolean` but not the report `boolean` +- `net.minecraft.data.loot.BlockLootSubProvider` + - `explosionResistant` is now private + - `enabledFeatures` is now private + - `map` is now private +- `net.minecraft.data.recipes` + - `RecipeProvider$FamilyRecipeProvider` -> `$FamilyCraftingRecipeProvider`, `$FamilyStonecutterRecipeProvider` + - `SingleItemRecipeBuilder#stonecutting` moved to a parameter on the `BlockFamily` +- `net.minecraft.data.structures.SnbtToNbt` now has an overload that takes in a single input folder path +- `net.minecraft.gametest.framework` + - `GameTestHelper` + - `assertBlockPresent` now has an overload that only takes in the block to check for + - `moveTo` now has overloads for taking in the `BlockPos` and `Vec3` for the position + - `assertEntityInstancePresent` now has an overload that inflates (via a `double`) the bounding box to check entities within + - `GameTestServer#create` now takes in an `int` for the number of times to run all matching tests + - `StructureUtils#testStructuresDir` split into `testStructuresTargetDir`, `testStructuresSourceDir` + - `TestData` now takes in an `int` for the number of blocks padding around the test +- `net.minecraft.nbt` + - `NbtUtils` + - `addDataVersion` now uses a generic for the `Dynamic` instead of the explicit nbt tag + - `getDataVersion` now has an overload that defaults to -1 if the version is not specified + - `TextComponentTagVisitor` can now take in a `$Styling` and a `boolean` of whether to sort the keys + - `handleEscapePretty` is now a `private` instance method from `protected` static +- `net.minecraft.network.FriendlyByteBuf` + - `readVec3`, `writeVec3` replaced with `Vec3#STREAM_CODEC` + - `readLpVec3`, `writeLpVec3` replaced with `Vec3#LP_STREAM_CODEC` +- `net.minecraft.network.chat` + - `Component` + - `nbt` now takes in a `CompilableString` instead of a `String` + - `object` now has an overload that takes in a `Component` fallback + - `ComponentContents#resolve` now takes in a `ResolutionContext` instead of the `CommandSourceStack` and `Entity` + - `ComponentUtils#updateForEnttiy` -> `resolve`, taking in the `ResolutionContext` instead of the `CommandSourceStack` and `Entity` + - `LastSeenMessages#EMPTY` is now final +- `net.minecraft.network.chat.contents` + - `NbtContents` is now a record, the constructor taking in a `CompilableString` instead of a `String` + - `ObjectContents` now takes in an optional `Component` for the fallback if its contents cannot be validated +- `net.minecraft.network.chat.contents.data` + - `BlockDataSource` now takes in a `CompilableString` for the `Coordinates` instead of the pattern and compiled position + - `EntityDataSource` now takes in a `CompilableString` for the `EntitySelector` instead of the pattern and compiled selector +- `net.minecraft.network.chat.contents.objects.ObjectInfo#description` -> `defaultFallback` +- `net.minecraft.network.protocol.game` + - `ClientboundSetEntityMotionPacket` is now a record + - `ServerboundContainerClickPacket` now takes in a `ContainerInput` instead of a `ClickType` + - `ServerboundInteractPacket` is now a record, now taking in the `Vec3` interaction location +- `net.minecraft.references` + - `Blocks` -> `BlockIds` + - `Items` -> `ItemIds` +- `net.minecraft.resources` + - `FileToIdConverter` is now a record + - `RegistryDataLoader#load` now returns a `CompletableFuture` of the frozen registry access +- `net.minecraft.server.MinecraftServer` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash + - `throwIfFatalException` -> `BlockableEventLoop#throwDelayedException`, now private, not one-to-one + - `setFatalException` -> `BlockableEventLoop#delayCrash`, `relayDelayCrash`; not one-to-one +- `net.minecraft.server.commands.ChaseCommand#DIMENSION_NAMES` is now final +- `net.minecraft.server.dedicated.DedicatedServerProperties#acceptsTransfers` is now final +- `net.minecraft.server.packs` + - `BuiltInMetadata` has been merged in `ResourceMetadata` + - `get` -> `ResourceMetadata#getSection` + - `of` -> `ResourceMetadata#of` + - `PathPackResources#getNamespaces` now has a static overload that takes in the root directory `Path` + - `VanillaPackResourcesBuilder#setMetadata` now takes in a `ResourceMetadata` instead of a `BuiltInMetadata` +- `net.minecraft.server.players.OldUsersConverter#serverReadyAfterUserconversion` replaced by `areOldUserListsRemoves`, now `public` +- `net.minecraft.tags.TagLoader` + - `loadTagsFromNetwork` now takes in a `Registry` instead of a `WritableRegistry`, returning a map of tag keys to a list of holder entries + - `loadTagsForRegistry` now has an overload which takes in registry key along with an element lookup, returning a map of tag keys to a list of holder entries +- `net.minecraft.util` + - `Brightness` + - `pack` -> `LightCoordsUtil#pack` + - `block` -> `LightCoordsUtil#block` + - `sky` -> `LightCoordsUtil#sky` + - `RandomSource#createNewThreadLocalInstance` -> `createThreadLocalInstance` + - Now has an overload to specify the seed + - `Util#copyAndAdd` now has an overload that takes in a varargs of elements +- `net.minecraft.util.thread` + - `BlockableEventLoop` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash + - `ReentrantBlockableEventLoop` now takes in a `boolean` of whether to propogate crashes, usually to throw a delayed crash +- `net.minecraft.world.InteractionResult$ItemContext#NONE`, `DEFAULT` are now final +- `net.minecraft.world.attribute` + - `AttributeType` now takes in a `ToFloatFunction` for use in a number provider + - `ofInterpolated` now takes in a `ToFloatFunction` + - `EnvironmentAttributeReader#getValue` now has an overload that takes in the `LootContext` +- `net.minecraft.world.entity` + - `Avatar` is now abstract + - `Entity` + - `fluidHeight` is now final + - `getTags` -> `entityTags` + - `getRandomY` now has an overload that specifies the spread `double` + - `Leashable$Wrench#ZERO` is now final + - `LivingEntity` + - `interpolation` is now final + - `swingingArm` is now nullable + - `canAttackType` -> `canAttack`, not one-to-one, taking in the `LivingEntity` instead of the `EntityType` + - `lungeForwardMaybe` -> `postPiercingAttack` + - `entityAttackRange` -> `getAttackRangeWith`, now taking in the `ItemStack` used to attack +- `net.minecraft.world.entity.ai.behavior` + - `GoAndGiveItemsToTarget` now takes in the `$ItemThrower` + - `throwItem` -> `BehaviorUtils#throwItem`, not one-to-one + - `SpearAttack` no longer takes in the approach distance `float` + - `TryLaySpawnOnWaterNearLand` -> `TryLaySpawnOnFluidNearLand`, not one-to-one +- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder#sequence` now takes in a `Oneshot` for the second entry instead of a `Trigger` +- `net.minecraft.world.entity.ai.goal` + - `BoatGoals` -> `FollowPlayerRiddenEntityGoal$FollowEntityGoal` + - `BOAT` is replaced by `ENTITY` + - `FollowBoatGoal` -> `FollowPlayerRiddenEntityGoal`, not one-to-one +- `net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal#targetConditions` is now final +- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#getMemory` -> `getMemoryToSet` +- `net.minecraft.world.entity.decoration.Mannequin#getProfile` -> `Avatar#getProfile`, now `public` and `abstract` + - Still implemented in `Mannequin` +- `net.minecraft.world.entity.item.ItemEntity#DEFAULT_HEALTH` is now `public` from `private` +- `net.minecraft.world.entity.monster.breeze.Breeze#idle`, `slide`, `slideBack`, `longJump`, `shoot`, `inhale` are now final +- `net.minecraft.world.entity.monster.piglin.PiglinAi#isZombified` now takes in the `Entity` instead of the `EntityType` +- `net.minecraft.world.entity.monster.warden.Warden#roarAnimationState`, `sniffAnimationState`, `emergeAnimationState`, `diggingAnimationState`, `attackAnimationState`, `sonicBoomAnimationState` are now final +- `net.minecraft.world.entity.monster.zombie.Zombie#handleAttributes` now takes in the `EntitySpawnReason` +- `net.minecraft.world.entity.player` + - `Input#EMPTY` is now final + - `Player` + - `currentImpulseImpactPos` -> `LivingEntity#currentImpulseImpactPos` + - `currentExplosionCause` -> `LivingEntity#currentExplosionCause` + - `setIgnoreFallDamageFromCurrentImpulse` -> `LivingEntity#setIgnoreFallDamageFromCurrentImpulse` + - `applyPostImpulseGraceTime` -> `LivingEntity#applyPostImpulseGraceTime` + - `isIgnoringFallDamageFromCurrentImpulse` -> `LivingEntity#isIgnoringFallDamageFromCurrentImpulse` + - `tryResetCurrentImpulseContext` -> `LivingEntity#tryResetCurrentImpulseContext` + - `resetCurrentImpulseContext` -> `LivingEntity#resetCurrentImpulseContext` + - `isInPostImpulseGraceTime` -> `LivingEntity#isInPostImpulseGraceTime` + - `isWithinAttackRange` now takes in the `ItemStack` attacked with +- `net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior$MinecartStep#EMPTY` is now final +- `net.minecraft.world.inventory.AbstractContainerMenu#getQuickCraftPlaceCount` now takes in the number of quick craft slots instead of the set of slots itself +- `net.minecraft.world.item` + - `BundleItem#getSelectedItem` -> `getSelectedItemIndex` + - `CreativeModeTab$Output` is now `protected` from `public` + - `EnderpearlItem#PROJECTILE_SHOOT_POWER` is now final + - `Item$Properties#requiredFeatures` now has an overload that takes in a `FeatureFlagSet` + - `Items#register*` methods are now `private` from `public` + - `ItemUtils#onContainerDestroyed` now takes in a `Stream` of `ItemStack`s instead of an `Iterable` + - `SignApplicator#tryApplyToSign`, `canApplyToSign` now take in the `ItemStack` being used + - `SnowballItem#PROJECTILE_SHOOT_POWER` is now final + - `ThrowablePotionItem#PROJECTILE_SHOOT_POWER` is now final + - `WindChargeItem#PROJECTILE_SHOOT_POWER` is now final +- `net.minecraft.world.item.alchemy.Potions` now deal with `Holder$Reference`s instead of the super `Holder` +- `net.minecraft.world.item.component` + - `AttackRange` + - `minRange` -> `minReach` + - `maxRange` -> `maxReach` + - `minCreativeRange` -> `minCreativeReach` + - `maxCreativeRange` -> `maxCreativeReach` + - `BundleContents` + - `weight` now returns a `DataResult`-wrapped `Fraction` instead of the raw object + - `getSelectedItem` -> `getSelectedItemIndex` + - `WrittenBookContent` + - `tryCraftCopy` -> `craftCopy` + - `resolveForItem`, `resolve` now take in the `ResolutionContext` and `HolderLookup$Provider` instead of the `CommandSourceStack` and `Player` +- `net.minecraft.world.item.enchantment` + - `ConditionalEffect#codec` no longer takes in the `ContextKeySet` + - `Enchantment#doLunge` -> `doPostPiercingAttack` + - `EnchantmentHelper#doLungeEffects` -> `doPostPiercingAttackEffects` + - `TargetedConditionalEffect#codec`, `equipmentDropsCodec` no longer take in the `ContextKeySet` +- `net.minecraft.world.item.enchantment.effects.EnchantmentAttributeEffect#CODEC` -> `MAP_CODEC` +- `net.minecraft.world.item.equipment.Equippable#canBeEquippedBy` now takes in a holder-wrapped `EntityType` instead of the raw type itself +- `net.minecraft.world.item.trading.VillagerTrades#LIBRARIAN_5_EMERALD_NAME_TAG` was replaced with `LIBRARIAN_5_EMERALD_YELLOW_CANDLE`, `LIBRARIAN_5_EMERALD_RED_CANDLE`, not one-to-one + - The original trade was moved to `WANDERING_TRADER_EMERALD_NAME_TAG` +- `net.minecraft.world.level` + - `LevelAccessor` no longer implements `LevelReader` + - `LevelHeightAccessor#isInsideBuildHeight` now has an overload that takes in the `BlockPos` +- `net.minecraft.world.level.block` + - `BigDripleafBlock#canPlaceAt` now takes in the `LevelReader` instead of the `LevelHeightAccessor`, and no longer takes in the old state + - `BubbleColumnBlock#updateColumn` now takes in the bubble column `Block` + - `FireBlock#setFlammable` is now `private` from `public` + - `MultifaceSpreader$DefaultSpreaderConfig#block` is now final + - `SnowyDirtBlock` -> `SnowyBlock` + - `SpreadingSnowyDirtBlock` -> `SpreadingSnowyBlock` + - The constructor now takes in the `ResourceKey` for the 'base' block, or the block when the snow or any other decoration (e.g. grass) is removed +- `net.minecraft.world.level.block.entity.TestInstanceBlockEntity` + - `getTestBoundingBox` - The bounding box of the test inflated by its padding. + - `getTestBounds` - The axis aligned bounding box of the test inflated by its padding. +- `net.minecraft.world.level.block.entity.vault` + - `VaultConfig#DEFAULT`, `CODEC` are now final + - `VaultServerData#CODEC` is now final + - `VaultSharedData#CODEC` is now final +- `net.minecraft.world.level.block.state` + - `BlockBehaviour` + - `$BlockStateBase` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `hasPostProcess` -> `getPostProcessPos`, not one-to-one + `$Properties#hasPostProcess` -> `getPostProcessPos`, not one-to-one + - `BlockState` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `StateHolder` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` + - `populateNeighbours` -> `initializeNeighbors`, now package-private instead of `public`; not one-to-one + - `getValues` now returns a stream of `Property$Value`s + - `codec` now takes in the function that gets the state definition from some object +- `net.minecraft.world.level.chunk.ChunkAccess#blendingData` is now final +- `net.minecraft.world.level.chunk.storage.SimpleRegionStorage#upgradeChunkTag` now takes in an `int` for the target version +- `net.minecraft.world.level.gameevent.vibrations.VibrationSystem$Data#CODEC` is now final +- `net.minecraft.world.level.gamerules.GameRules` now has an overload that takes in a list of `GameRule`s +- `net.minecraft.world.level.levelgen` + - `NoiseRouterData#caves` no longer takes in the `HolderGetter` for the `NormalNoise$NoiseParameters` + - `WorldDimensions#keysInOrder` now takes in a set of `LevelStem` keys instead of a stream +- `net.minecraft.world.level.levelgen.blockpredicates` + - `TrueBlockPredicate#INSTANCE` is now final + - `UnobstructedPredicate#INSTANCE` is now final +- `net.minecraft.world.level.levelgen.feature` + - `AbstractHugeMushrromFeature` + - `isValidPosition` now takes in a `WorldGenLevel` instead of the `LevelAccessor` + - `placeTrunk` now takes in the `WorldGenLevel` instead of the `LevelAccessor` + - `makeCap` now takes in the `WorldGenLevel` instead of the `LevelAccessor` + - `BlockBlobFeature` now uses a `BlockBlobConfiguration` generic + - `Feature` + - `FOREST_ROCK` replaced by `BLOCK_BLOB` + - `ICE_SPIKE` replaced by `SPIKE` + - `IceSpikeFeature` -> `SpikeFeature`, not one-to-one + - `SpikeFeature` is now `EndSpikeFeature`, not one-to-one + - `NUMBER_OF_SPIKES` -> `EndSpikeFeature#NUMBER_OF_SPIKES` + - `getSpikesForLevel` -> `EndSpikeFeature#getSpikesForLevel` +- `net.minecraft.world.level.levelgen.feature.configurations` + - `HugeMushroomFeatureConfiguration` is now a record, taking in a can place on `BlockPredicate` + - `SpikeConfiguration` -> `EndSpikeConfiguration` is now a record + - The original `SpikeConfiguration` is now for the ice spike, taking in the blocks to use, along with predicates of where to place and whether it can replace a block present + - `TreeConfiguration` + - `dirtProvider`, `forceDirt` have been replaced by `belowTrunkProvider` + - `dirtProvider` commonly uses `CAN_PLACE_BELOW_OVERWORLD_TRUNKS` + - `forceDirt` commonly uses `PLACE_BELOW_OVERWORLD_TRUNKS` + - `$TreeConfigurationBuilder` + - `dirtProvider`, `dirt`, `forceDirt` have been replaced by `belowTrunkProvider` +- `net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacer` + - `createFoliage` now takes in a `WorldGenLevel` isntead of a `LevelSimulatedReader` + - `placeLeavesRow`, `placeLeavesRowWithHangingLeavesBelow` now take in a `WorldGenLevel` isntead of a `LevelSimulatedReader` + - `tryPlaceExtension`, `tryPlaceLeaf` now take in a `WorldGenLevel` isntead of a `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacer#placeRoots`, `placeRoot` now take in a `WorldGenLevel` instead of a `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.stateproviders` + - `BlockStateProvider#getState` now takes in the `WorldGenLevel` +- `net.minecraft.world.level.levelgen.feature.treedecorators` + - `TreeDecorator$Context` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `level` now returns a `WorldGenLevel` instead of the `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer` + - `placeTrunk` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `setDirtAt` -> `placeBelowTrunkBlock`, now taking in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `placeLog` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `placeLogIfFree` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `validTreePos` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` + - `isFree` now takes in a `WorldGenLevel` instead of the `LevelSimulatedReader` +- `net.minecraft.world.level.levelgen.placement.BiomeFilter#CODEC` is now final +- `net.minecraft.world.level.levelgen.structure.TemplateStructurePiece#template`, `placeSettings` are now final +- `net.minecraft.world.level.levelgen.structure.pools.alias` + - `DirectPoolAlias#CODEC` is now final + - `RandomGroupPoolAlias#CODEC` is now final + - `RandomPoolAlias#CODEC` is now final +- `net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings#CODEC` is now final +- `net.minecraft.world.level.levelgen.synth.PerlinNoise#getValue` no longer takes in the `boolean` for whether to flat the Y value instead of applying the frequency factor +- `net.minecraft.world.level.material.FluidState` now takes in an array of `Property`s and `Comparable` values instead of one value map, and no longer takes in the `MapCodec` +- `net.minecraft.world.level.pathfinder.PathType` + - `DANGER_POWDER_SNOW` -> `ON_TOP_OF_POWDER_SNOW` + - `DANGER_FIRE` -> `FIRE_IN_NEIGHBOR` + - `DAMAGE_FIRE` -> `FIRE` + - `DANGER_OTHER` -> `DAMAGING_IN_NEIGHBOR` + - `DAMAGE_OTHER` -> `DAMAGING`, + - `DANGER_TRAPDOOR` -> `ON_TOP_OF_TRAPDOOR` +- `net.minecraft.world.level.saveddata.maps.MapItemSavedData#tickCarriedBy` now takes in a nullable `ItemFrame` +- `net.minecraft.world.level.storage.loot.functions` + - `EnchantRandomlyFunction` now takes in a `boolean` of whether to include the additional trade cost component from the stack being enchanted + - Set via `$Builder#includeAdditionalCostComponent` + - `EnchantWithLevelsFunction` now takes in a `boolean` of whether to include the additional trade cost component from the stack being enchanted + - Set via `$Builder#includeAdditionalCostComponent` + - `$Builder#fromOptions` -> `withOptions`, now with overload to take in an optional `HolderSet` + +#### List of Removals + +- `net.minecraft.SharedConstants#USE_WORKFLOWS_HOOKS` +- `net.minecraft.client.data.models.BlockModelGenerators#createGenericCube` +- `net.minecraft.client.Minecraft#delayCrashRaw` +- `net.minecraft.client.gui.components.EditBox#setFilter` +- `net.minecraft.client.multiplayer.ClientPacketListener#getId` +- `net.minecraft.client.renderer.Sheets` + - `shieldSheet` + - `bedSheet` + - `shulkerBoxSheet` + - `signSheet` + - `hangingSignSheet` + - `chestSheet` +- `net.minecraft.client.renderer.rendertype.RenderTypes#weather` +- `net.minecraft.data.loot.BlockLootSubProvider(Set, FeatureFlagSet, Map, HolderLookup$Provider)` +- `net.minecraft.gametest.framework.StructureUtils#DEFAULT_TEST_STRUCTURES_DIR` +- `net.minecraft.nbt.NbtUtils` + - `addCurrentDataVersion` + - `prettyPrint(Tag)` +- `net.minecraft.server.packs.AbstractPackResources#getMetadataFromStream` +- `net.minecraft.server.players.PlayerList#getSingleplayerData` +- `net.minecraft.util` + - `Mth#createInsecureUUID` + - `LightCoordsUtil#UI_FULL_BRIGHT` +- `net.minecraft.world` + - `ContainerListener` + - `Difficulty#getKey` + - `SimpleContainer#addListener`, `removeListener` +- `net.minecraft.world.entity.ai.memory.MemoryModuleType#INTERACTABLE_DOORS` +- `net.minecraft.world.entity.monster.Zoglin#MEMORY_TYPES` +- `net.minecraft.world.entity.monster.creaking.Creaking#MEMORY_TYPES` +- `net.minecraft.world.entity.monster.hogling.Hoglin#MEMORY_TYPES` +- `net.minecraft.world.item` + - `BundleItem#hasSelectedItem` + - `Item#getName()` + - `ItemStack` + - `isFramed`, `getFrame` + - `setEntityRepresentation`, `getEntityRepresentation` +- `net.minecraft.world.item.component` + - `BundleContents` + - `getItemUnsafe` + - `hasSelectedItem` + - `WrittenBookContent#MAX_CRAFTABLE_GENERATION` +- `net.minecraft.world.level.block.LiquidBlock#SHAPE_STABLE` +- `net.minecraft.world.level.levelgen.feature` + - `Feature#isStone`, `isDirt`, `isGrassOrDirt` +- `net.minecraft.world.level.levelgen.material.WorldGenMaterialRule` +- `net.minecraft.world.level.storage.loot.functions.SetOminousBottleAmplifierFunction#amplifier` + +## Appendices + +The pages below are retained as navigation and supporting material: + +- [Repeatedly Changing Systems](repeatedly-changing-systems.md) +- [Detailed Primers](detailed-primers/README.md) diff --git a/src/repeatedly-changing-systems.md b/src/repeatedly-changing-systems.md new file mode 100644 index 0000000..7da8251 --- /dev/null +++ b/src/repeatedly-changing-systems.md @@ -0,0 +1,133 @@ +# Repeatedly Changing Systems + +This page is the guard rail for the direct port. + +When the same subsystem changed in multiple intermediate versions, do not treat the earliest migration note as final. Use the latest applicable version as the source of truth, but still apply the older chapter first so the intermediate API transitions make sense. + +## Rendering and graphics + +Relevant chapters: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md) +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md) +- [1.21.6 -> 1.21.7](detailed-primers/1.21.7-from-1.21.6.md) +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +How to read them: + +- `1.21.2/3` changes GUI blits, shader JSON structure, and render-state assumptions. +- `1.21.5` is the first large rendering infrastructure rewrite around `RenderPipeline`, `GpuTexture`, and render passes. +- `1.21.6` changes GUI rendering flow again through prepare/render state separation. +- `1.21.9` changes how features are submitted for rendering. +- `1.21.11` changes samplers, render types, terrain split, and atlases. +- `26.1` is the final authority for block/item rendering, materials, tint sources, fluid models, particle layers, and backend-facing rendering APIs. + +Practical rule: + +- Treat `26.1` as the final rendering target. +- Keep `1.21.4` client items and `1.21.6` GUI flow as still-active requirements, not obsolete history. + +## Item models and item metadata + +Relevant chapters: + +- [1.21.2/3 -> 1.21.4](detailed-primers/1.21.4-from-1.21.2-3.md) +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +What sticks: + +- `1.21.4` client items are the baseline for item rendering data. +- `1.21.5` removes more hardcoded item-class assumptions in favor of components and equipment data. +- `1.21.9`, `1.21.11`, and `26.1` further change how items participate in rendering and metadata pipelines. + +Practical rule: + +- First convert item assets to client items. +- Then port behavior and metadata around components. +- Finally validate them against the `26.1` rendering and item-instance model. + +## Tags, registries, codecs, and validation + +Relevant chapters: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md) +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.5 -> 1.21.6](detailed-primers/1.21.6-from-1.21.5.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +What sticks: + +- `1.21.2/3` is where `Holder` and `HolderSet` start affecting large parts of the codebase. +- `1.21.5` changes tag access, parser behavior, codec-based reads and writes, and saved-data construction. +- `1.21.6` changes tag provider building and nudges more code toward generic encoding and decoding. +- `1.21.11` contributes rename churn that affects registry and identifier-facing code. +- `26.1` finalizes more codec-driven infrastructure with loot type unrolling and validation overhaul. + +Practical rule: + +- The earlier chapters tell you how to get onto holder- and codec-based APIs. +- `26.1` is the final target for validation and loot registration shape. + +## Data components + +Relevant chapters: + +- [1.21.1 -> 1.21.2/3](detailed-primers/1.21.2-from-1.21.1.md) +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +What sticks: + +- `1.21.2/3` introduces important component-facing migrations such as consumables and recipe-related data moves. +- `1.21.5` expands component-centered behavior for tools, armor, weapons, and general data access. +- `1.21.11` adds more component types. +- `26.1` continues with initializers, dye components, and more component additions. + +Practical rule: + +- Expect items and recipes to get less class-driven and more component-driven as you move forward. + +## Saved data and world state + +Relevant chapters: + +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +What sticks: + +- `1.21.5` moves saved data to `SavedDataType`. +- `26.1` splits primary level data further into dedicated saved-data objects. + +Practical rule: + +- Do the `1.21.5` migration first, then revisit every level/world persistence assumption again in `26.1`. + +## Developer tooling, tests, debugging, and permissions + +Relevant chapters: + +- [1.21.4 -> 1.21.5](detailed-primers/1.21.5-from-1.21.4.md) +- [1.21.8 -> 1.21.9](detailed-primers/1.21.9-from-1.21.8.md) +- [1.21.10 -> 1.21.11](detailed-primers/1.21.11-from-1.21.10.md) +- [1.21.11 -> 26.1](detailed-primers/26.1-from-1.21.11.md) + +What sticks: + +- `1.21.5` overhauls game tests. +- `1.21.9` overhauls debugging and management-server shape. +- `1.21.11` adds a permission overhaul and gizmo-focused visualization work. +- `26.1` adds Java 25 and more minor tooling-facing changes. + +Practical rule: + +- Port gameplay code first. +- Then re-enable your debug, test, and operator-only tooling against the later chapters. diff --git a/src/source-and-attribution.md b/src/source-and-attribution.md new file mode 100644 index 0000000..a1a9158 --- /dev/null +++ b/src/source-and-attribution.md @@ -0,0 +1,41 @@ +# Source And Attribution + +This docs tree was assembled from the upstream primers in: + +- Repository: `https://github.com/ChampionAsh5357/neoforged-github` +- Branch: `update/26.1` +- Primer root: `primers/` + +## Coverage used for this compilation + +The compiled direct-port guide includes these upstream primer steps: + +- `1.21.1 -> 1.21.2/3` +- `1.21.2/3 -> 1.21.4` +- `1.21.4 -> 1.21.5` +- `1.21.5 -> 1.21.6` +- `1.21.6 -> 1.21.7` +- `1.21.7 -> 1.21.8` +- `1.21.8 -> 1.21.9` +- `1.21.9 -> 1.21.10` +- `1.21.10 -> 1.21.11` +- `1.21.11 -> 26.1` + +## Attribution + +Per the upstream `primers/README.md`: + +- Primers for versions `1.12 - 1.15` were written by `@williewillus`. +- Primers for versions `1.16 - 1.17` were written by `@50ap5ud5`. +- All newer primers, including the ones used here, were written by `@ChampionAsh5357`. + +## Licensing note + +The detailed primers copied into this docs tree remain under their upstream licenses and attribution requirements. + +For the exact license text and upstream breakdown, refer to: + +- `repo/primers/README.md` +- `repo/primers/LICENSE-CHAMPIONASH5357` +- `repo/primers/LICENSE-50AP5UD5` +- `repo/primers/LICENSE-WILLIEWILLUS`