Skip to content

Commit

Permalink
Fabric for Minecraft 1.20.2 (#55)
Browse files Browse the repository at this point in the history
* Fabric for Minecraft 1.20.2

* Fix diff codeblock

---------

Co-authored-by: modmuss50 <[email protected]>
  • Loading branch information
apple502j and modmuss50 authored Sep 12, 2023
1 parent 2257a06 commit 3ef140a
Showing 1 changed file with 190 additions and 0 deletions.
190 changes: 190 additions & 0 deletions _posts/2023-09-12-1202.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
layout: post
title: Fabric for Minecraft 1.20.2
ref: 1202
---
Minecraft 1.20.2 will be released in the near future, again with some changes that impact many mods.

As usual, we ask players to be patient, and give mod developers time to update to this new version.

Here is a list of all major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.

## Fabric changes
Developers should use Loom 1.3 (at the time of writing) to develop mods for Minecraft 1.20.2. Players should install the latest stable version of Fabric Loader (currently 0.14.22) to play 1.20.2.

### Loom 1.3
Loom 1.3 includes fixes to debugging, Kotlin 1.9.0 support, reproducable builds by default and many other smaller fixes and improvements.

### New Fabric API changes
With the help of many contributors, Fabric API has received several new features since the last update blog post:

<!-- yeah, sort it (alphabetical of module name) -->

- Client Tags: add support for partially synced client tags. (dexman545)
- Particles v1: add event for preventing particle tinting for colored blocks. (Juxxel)
- Registry Sync: add dynamic registry API (Juxxel)
- Transitive Access Wideners: some more TAWs for block creation and block loot tables (Shnupbups)


### Breaking changes and deprecations
The following deprecated APIs were removed:

- `fabric-networking-v0`
- `fabric-loot-tables-v1`
- `LootEntryTypeRegistry` from `fabric-content-registries-v0`
- `CriterionRegistry` from `fabric-object-builder-api-v1`

In addition, there were some module-wide deprecations. Deprecated modules were previously removed from the JAR used by developers by default, while still being distributed to all players. We have not previously classified this as a breaking change, since the deprecation has no effect on players.

This opt-in system, however, caused great confusion among developers during the Models API deprecation process. For this reason, **deprecated modules are now available by default** in the development environment.

To restore the old behavior and **disable deprecated modules**, use the following:

```groovy
modImplementation("net.fabricmc.fabric-api:fabric-api:0.88.2+1.20.2") {
exclude(module = "fabric-api-deprecated")
}
```

#### Breaking change: custom registry tags
Tags for static custom registry entries (created with `FabricRegistryBuilder`) must now be placed under `/tags/registry_namespace/registry_path/`, instead of `/tags/registry_path/`. For example, if the registry is `my_mod:tiny_potato`, the tags should be placed under `/tags/my_mod/tiny_potato/`.

This matches the behavior for custom dynamic registries that is recently introduced to Fabric API. **This does not affect vanilla tags** like blocks, items, or entity types.

#### BlockSetType and WoodType
To make the API easier to use, `BlockSetTypeRegistry` and `WoodTypeRegistry` are now replaced with builders, `BlockSetTypeBuilder` and `WoodTypeBuilder`. The registries were deprecated.

```diff
- BlockSetTypeRegistry.registerWood(TEAL_TYPE_ID);
- WoodTypeRegistry.register(TEAL_TYPE_ID, TEAL_BLOCK_SET_TYPE);
+ BlockSetTypeBuilder.copyOf(BlockSetType.OAK).build(TEAL_TYPE_ID);
+ WoodTypeBuilder.copyOf(WoodType.OAK).build(TEAL_TYPE_ID, TEAL_BLOCK_SET_TYPE);
```

#### Transfer API
`Storage#exactView` was deprecated for removal due to lack of use and its complexity.

Two methods from `Storage` moved to `StorageUtil`. They are: `simulateInsert` and `simulateExtract`. The methods in `Storage` are now deprecated for removal. This allows `simulateExtract` to work on `StorageView`.

#### Models API replacement
*This section is currently incomplete. Please check back later!*

#### Rendering Data Attachments replacement
*This section is currently incomplete. Please check back later!*

## Minecraft changes
Minecraft 1.20.2 introduces some breaking changes to major developer-facing APIs.

### Networking
While the developer-facing breaking changes to Networking API were minimum, the API's implementation was rewritten to use the new configuration stage, between login and play stages. This change hopefully resolves the longstanding issue with proxy servers.

However, some mods need to change the code to utilize the configuration stage. Here is the summary of the changes; those who work on the raw networking stack (to develop cross-platform APIs or proxies) should read [the protocol proposal](https://github.com/FabricMC/fabric/pull/3244).

**Mods that use `ServerPlayNetworking`, for non-configuration purposes, are likely unaffected.** Mods that use `ServerLoginNetworking`, or implement configuration syncing/mod version checking feature, should check the note below.

- Before 1.20.2, most of the server-client communication took place during gameplay, via `ServerPlayNetworking`. Mods who wanted to communicate before the player joined had to use `ServerLoginNetworking`.
- In 1.20.2, after the player authenticates, but before the player joins the world (and `ServerPlayerEntity` instance is created), there exist a phase where the client and the server can communicate to configure each other. This is the "configuration stage".
- During this stage, the server executes "tasks" one by one. For example, you can define a task that queries the client's mod version and disconnects the client if the versions differ.
- Once all tasks are completed, the player joins the world.
- Importantly, the code allows the server to force a player back to the configuration stage. This feature is not used in vanilla. For example, a minigame server might use this feature to move players between the lobby and the minigames.
- Configuration stage is designed to allow mods to reliably exchange packets before the player joins. If you previously have used `ServerLoginNetworking`, it is highly recommended to switch to configuration stage, with `ServerConfigurationNetworking`.

Example of implementing one-way syncing, from server to client:

```java
// define ConfigS2CPacket; see https://gist.github.com/apple502j/9c6b9e5e8dec37cbf6f3916472a79d57

ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> {
ServerConfigurationNetworking.send(handler, new ConfigS2CPacket("data"));
});
```

Client side:

```java
ClientConfigurationNetworking.registerGlobalReceiver(ConfigS2CPacket.TYPE, (packet, sender) -> {
// do something with packet
});
```

Example of sending a packet to, and receiving a packet from, a client:

```java
// define ConfigC2SPacket, which is sent as a response to S2CPacket

public record ConfigTask(String config) implements ServerPlayerConfigurationTask {
public static final ServerPlayerConfigurationTask.Key KEY = new ServerPlayerConfigurationTask.Key("my_mod_id:my_mod_config");

@Override
public ServerPlayerConfigurationTask.Key getKey() {
return KEY;
}

@Override
public void sendPacket(Consumer<Packet<?>> sender) {
sender.accept(ServerConfigurationNetworking.createS2CPacket(new ConfigS2CPacket(this.config)));
}
}

ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> {
// This if block is required! Otherwise the client gets stuck in connection screen
// if the client cannot handle the packet.
if (ServerConfigurationNetworking.canSend(handler, ConfigS2CPacket.TYPE)) {
handler.addTask(new ConfigTask("config"));
} else {
// Optional; if you want to require certain mods, disconnect the client.
handler.disconnect(Text.of("You need to install Tiny Potato Mod!"));
}
});

ServerConfigurationNetworking.registerGlobalReceiver(ConfigC2SPacket.TYPE, (packet, handler, sender) -> {
// Check packet here
// Warning: if you do not call completeTask, the client gets stuck!
handler.completeTask(ConfigTask.KEY);
})
```

Client side:

```java
ClientConfigurationNetworking.registerGlobalReceiver(ConfigS2CPacket.TYPE, (packet, sender) -> {
// do something with packet
// send a response
sender.sendPacket(new ConfigC2SPacket("response"));
});
```

There is one breaking change to Networking API: `ClientPlayNetworking#createC2SPacket` now returns `Packet<ServerCommonPacketListener>` instead of `Packet<ServerPlayPacketListener>` (and similar changes with `createS2CPacket` as well.)

### Status effects
Status effects are now stored using string ID, instead of integer ID. **Fabric does not migrate the data by itself.** We expect someone to make a mod for data conversion.

This change also meant that Registry Sync module no longer has to keep track of the raw IDs of registry entries on disk. The tracker file will NOT be automatically deleted. API-wise, this means `RegistryAttribute#PERSISTED` is gone.

### Recipes and advancements
Recipe and advancement code was refactored to use records. In addition, `RecipeEntry` or `AdvancementEntry` is used in many places where a raw recipe or advancement is used previously. As the name suggests, this is a pair of the ID and the value. If you want to get the recipe/advancement itself, call `.value()`. In `RecipeProvider`, `exporter` is now of type `RecipeExporter`, not `Consumer<RecipeJsonProvider>`. The usage remains the same; to output a recipe, call `accept`.

Recipes and ingredients are serialized to and from the disk using Codecs. Fabric API's `CustomIngredientSerializer` now has `codec` method that returns codec, instead of `read`/`write` taking `JsonObject`. (`read`/`write` taking `PacketByteBuf` still exists.) To make the migration easier, you can use `Codecs#fromJsonSerializer` - though this is deprecated.

Yarn mapping received a couple of renames. Most significantly, "input" and "output" are now called "ingredient" and "result".

### Trading
A new experiment for rebalancing villager and wandering trader trades is added. While this is labeled as an experiment, it is an officially-supported feature that can be enabled in a release.

While the internal changes to villagers were minimum, there were substantial changes to how wandering trader offers are picked in the experiment.

Previously, the trades were selected in a similar way to villagers, where level 0 indicated common items and level 1 indicated rare items. The experiment replaces this with a pool-based method; there are several pools, and from each pool the game picks certain numbers of offers.

We are currently designing an API that supports the experiment. For now, the current code works for existing worlds and newly created worlds without the experiment.

### GUI
Two `Screen` related changes: `onMouseScrolled` method now takes both horizontal and vertical scroll amount. Most mouses do not support horizontal scrolling, so use that feature with caution. Another change is that `renderBackground` method now takes mouse positions and `tickDelta`.

In `EntryListWidget#mouseClicked`, the mouse button is now automatically checked. Override `isSelectButton` to allow right-clicking entries to select one. The checks in individual entries are now redundant.

Texture rendering methods have changed; `drawTexture` calls should be replaced with `drawGuiTexture`. Note that since the game no longer uses atlases in GUI textures, there is no need to specify UV.

### Miscellaneous changes
- `MessageDecorator` is now synchronous.
- `MeleeAttackGoal#canAttack` was added. This is checked inside `attack` method.
- In Yarn, several classes relating to session, player reporting, and telemetry were moved to a new package, `client.session`.

0 comments on commit 3ef140a

Please sign in to comment.