Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
UltimatChamp authored Dec 14, 2023
2 parents a8ea8b3 + 3cfb86c commit fa035b5
Show file tree
Hide file tree
Showing 7 changed files with 701 additions and 14 deletions.
15 changes: 1 addition & 14 deletions content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,7 @@ You can find a direct link to our latest installer files below.
2. Clone this project locally, and get started! Our [Documentation] and the [Modding Wiki] are great places to learn more.

## If you have an existing mod project
You can use neoforge in your existing mod development as well. To do so:
1. Update your repositories to use `https://maven.neoforged.net/releases` instead of `https://maven.minecraftforge.net`
2. Update your ForgeGradle to use NeoGradle 6.0.13 or above:
```
plugins {
...
id 'net.neoforged.gradle' version '[6.0.13, 6.2)'
}
```
3. Update your `minecraft` dependency to use `net.neoforged:forge` and the version as shown above.
### Some things to note
1. At the present time, mods built by either system should be intercompatible between forks.
2. Do note that recently, there were some changes in the recommended way to use ForgeGradle/NeoGradle. Note especially the way that `settings.gradle` has changed, as well as the removal of the `buildscript` section in `build.gradle`. Refer to [The MDK] for an example and more.
Refer to [The MDK] for an example of how to update your build script to use NeoForge.

[The MDK]: https://github.com/neoforged/MDK
[Documentation]: https://docs.neoforged.net
Expand Down
160 changes: 160 additions & 0 deletions content/news/20.2registry-rework.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
title: "The big Registry system update is here"
date: 2023-11-19T18:00:00+01:00
categories:
- News
authors:
- technici4n
- matyrobbrt
- minecraftschurli
summary: |
Summary of the NeoForge 20.2.59-beta registry system changes.
description: |
Summary of the NeoForge 20.2.59-beta registry system changes.
---

## Introduction
A big update to the registry system was just released in NeoForge version 20.2.59-beta!
Our primary goal is to simplify the code as much as possible,
and align it with the registry system in vanilla Minecraft.

This blog post will go through the most important changes that were made,
to act as a migration guide for modders.

This rework is the first of the three big reworks to land
after [our initial 20.2 release](../20.2release/).
The other two systems that will receive an overhaul in the coming weeks
are **capabilities** and **networking**.
Once these also land we will be aiming for a 20.2 stable release.

## Using the registries
Previously, the NeoForge registry system was completely separate from vanilla's.
Now, we use the existing registry system in vanilla, with a few additions that are relevant to mod support.

This means that `IForgeRegistry` is replaced by the vanilla `Registry`.
NeoForge adds a few methods to the vanilla `Registry` type via `IRegistryExtension`.
Here is an overview of the changed methods:
| `IForgeRegistry` | `Registry` |
|--------------------------------|--------------------------------------------|
| `getValue(ResourceLocation)` | `get(ResourceLocation)` |
| `getKeys()` | `keySet()` |
| `getValues().stream()` | `stream()` |
| `getHolder(T)Optional<Holder>` | `wrapAsHolder(T)Holder?` |
| `tags()` | Use `getTag(TagKey)` and the HolderSet API |

The registries that are defined by Minecraft itself should now be accessed via `BuiltInRegistries`:
```diff
- ForgeRegistries.ITEMS.getValue(new ResourceLocation("minecraft:diamond"));
+ BuiltInRegistries.ITEM.get(new ResourceLocation("minecraft:diamond"));
```

The registries that are defined by NeoForge are accessible via `NeoForgeRegistries`.
They are not wrapped in a `Supplier` anymore, and can be used directly:
```diff
- ForgeRegistries.FLUID_TYPES.get().getValue(new ResourceLocation("mymod:fancyfluid"));
+ NeoForgeRegistries.FLUID_TYPES.get(new ResourceLocation("mymod:fancyfluid"));
```

## Registration
Registration still happens in the `RegisterEvent`,
and we still recommend that modders use `DeferredRegister` to abstract over the events.

`RegistryObject` was replaced by `DeferredHolder`, which implements vanilla's `Holder` interface.
When registering objects to a deferred register, we recommended two options:
- If you don't need any of the `Holder` functions, you can use a `Supplier` for the type of your field.
- Otherwise, use `DeferredHolder` with the two generic parameters
(one for the registry and one for your object type).

Here are is an example:
```diff
private static final DeferredRegister<Enchantment> ENCHANTMENTS = DeferredRegister.create(Registries.ENCHANTMENT, "mymod");

- public static final RegistryObject<Enchantment> MAGIC =
- ENCHANTMENTS.register("magic", () -> new MagicEnchantment(/* create enchantment */));
// Supplier only:
+ public static final Supplier<MagicEnchantment> MAGIC =
+ ENCHANTMENTS.register("magic", () -> new MagicEnchantment(/* create enchantment */));
// Access to both Holder and the exact object type:
+ public static final DeferredHolder<Enchantment, MagicEnchantment> MAGIC =
+ ENCHANTMENTS.register("magic", () -> new MagicEnchantment(/* create enchantment */));
```

NeoForge also provides `DeferredHolder` and `DeferredRegister` specializations for items and blocks
that implement `ItemLike`. For example:
```java
// Make sure you use the special DeferredRegister.Blocks and DeferredRegister.Items types,
// NOT DeferredRegister<Block> or DeferredRegister<Item>!
private static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks("mymod");
private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems("mymod");

// If you are registering blocks or items directly, use a normal `register` call:
public static final DeferredBlock<MyBlock> MY_BLOCK = BLOCKS.register("my_block", () -> new MyBlock(/* create block */));
public static final DeferredItem<MyItem> MY_ITEM = ITEMS.register("my_item", () -> new MyItem(/* create item */));

// There are also a few extra helper functions, for example to register "simple" blocks.
// `registerSimpleBlock` to directly register a `new Block` from some block properties:
public static final DeferredBlock<Block> MY_SIMPLE_BLOCK =
BLOCKS.registerSimpleBlock("simple_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE));
// `registerSimpleItem` to directly register a `new Item` from some item properties:
public static final DeferredItem<Item> MY_SIMPLE_ITEM =
ITEMS.registerSimpleItem("simple_item", new Item.Properties().stacksTo(1));
// `registerSimpleBlockItem` to directly register a `new BlockItem` for a block:
public static final DeferredItem<BlockItem> MY_BLOCK_ITEM =
ITEMS.registerSimpleBlockItem(MY_BLOCK);
```

As usual, don't forget to pass your mod bus to your `DeferredRegister`s:
```java
@Mod("mymod")
public class MyMod {
// In case you missed it, mod constructors can now receive a number of optional arguments,
// including the mod's event bus. Unrelated to registries, but still pretty cool. ;)
public MyMod(IEventBus modEventBus) {
ENCHANTMENTS.register(modEventBus);
BLOCKS.register(modEventBus);
ITEMS.register(modEventBus);
}
}
```

## Custom registries
Custom registries are created with a `RegistryBuilder`, and must be registered to the `NewRegistryEvent`.
They can now be held in static fields, just like the registries in `BuiltInRegistries` or `NeoForgeRegistries`.

Here is a registration example, using the helper methods provided by `DeferredRegister`:
```java
// Create a registry key - we don't have a registry yet so give the key to DeferredRegister.
public static final ResourceKey<Registry<Custom>> CUSTOM_REGISTRY_KEY =
ResourceKey.createRegistryKey(new ResourceLocation("mymod:custom"));
// Create the DeferredRegister with our registry key.
private static final DeferredRegister<Custom> CUSTOMS =
DeferredRegister.create(CUSTOM_REGISTRY_KEY, "mymod");

// We can register objects as usual...
public static final Holder<Custom> CUSTOM_OBJECT =
CUSTOMS.register("custom_object", () -> new Custom());

// And here is how to create the registry!
public static final Registry<Custom> CUSTOM_REGISTRY =
CUSTOMS.makeRegistry(builder -> /* use builder to configure registry if needed */);

// Remember to register CUSTOMS in the mod constructor!
```

Another way is to directly create the registry with a `RegistryBuilder`, and manually register it:
```java
// We still need a registry key.
public static final ResourceKey<Registry<Custom>> CUSTOM_REGISTRY_KEY =
ResourceKey.createRegistryKey(new ResourceLocation("mymod:custom"));
// Create the registry directly...
public static final Registry<Custom> CUSTOM_REGISTRY = new RegistryBuilder<>(CUSTOM_REGISTRY_KEY)
// configure the builder if you want, for example with .sync(true)
// then build the registry
.build();

// Remember to tell NeoForge about your registry! For example:
modEventBus.addListener(NewRegistryEvent.class, event -> event.register(CUSTOM_REGISTRY));
```

## That's it!
As usual, ask on our Discord server in the [`#modder-support-1.20`](https://discord.com/channels/313125603924639766/1116211620415283201) channel if you have any question.
Loading

1 comment on commit fa035b5

@neoforged-pages-deployments
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploying with Cloudflare Pages

Name Result
Last commit: fa035b5a5ea30659298e3824c336945850cb0697
Status: ✅ Deploy successful!
Preview URL: https://e0ff4bd4.neoforged-website-previews.pages.dev
PR Preview URL: https://pr-15.neoforged-website-previews.pages.dev

Please sign in to comment.