NeoForge
NeoForge copied to clipboard
FluidResource and ItemResource proof of concept
Currently throwing ideas around...
FluidStack
and ItemStack
are very convenient, but they are also mutable. There are cases where we want to prevent mutation of fluid and item stacks. There are also many use cases where we would really like an immutable and count-less stack, for example for filtering, recipe ingredients, or other logic that should not depend on the count/amount.
This proof of concept is motivated by the move of ItemStack
(and FluidStack
) from NBT to data components. Data components are immutable. This makes exposing an immutable abstraction of a stack very practical, as we just need to expose 1) the item or fluid, 2) the count or amount and 3) an immutable data component map.
The goal is to provide the necessary abstractions in this PR for modder that want to move to immutable stack handling.
Right now this PR adds:
-
FluidResource
: immutable fluid and component map. Can be seen as a countless immutableFluidStack
. -
ItemResource
: immutable item and component map. Can be seen as a countless immutableItemStack
. -
IResource
is a supertype of these two, in preparation for more generic handling of resources. -
ResourceAmount
is a simple record of a resource and an amount. This can be used as an immutable stack.
Note that thanks to stacks being shallow-copied, stack copies have become cheap. Calling stack.copy()
will allocate exactly two objects regardless of the stored components. The backing component map is only copied lazily if one of the stacks is mutated.
Conversions:
- From stack to resource:
FluidResource.of(fluidStack)
. - From resource + amount to stack:
fluidResource.toStack(amount)
. - From
ResourceAmount
to resource:resourceAmount.resource()
. - From resource + amount to
ResourceAmount
:new ResourceAmount<>(resource, amount)
. - From stack to
ResourceAmount
:stack.immutable()
. - From
ResourceAmount
to stack:FluidStack.of(resourceAmount)
.
- [x] Publish PR to GitHub Packages
Last commit published: 5e560876876237b60e9cda4cbc9dbdba71061c61.
PR Publishing
The artifacts published by this PR:
Repository Declaration
In order to use the artifacts published by the PR, add the following repository to your buildscript:
repositories {
maven {
name 'Maven for PR #715' // https://github.com/neoforged/NeoForge/pull/715
url 'https://prmaven.neoforged.net/NeoForge/pr715'
content {
includeModule('net.neoforged', 'neoforge')
}
}
}
MDK installation
In order to setup a MDK using the latest PR version, run the following commands in a terminal.
The script works on both *nix and Windows as long as you have the JDK bin
folder on the path.
The script will clone the MDK in a folder named NeoForge-pr715
.
On Powershell you will need to remove the -L
flag from the curl
invocation.
mkdir NeoForge-pr715
cd NeoForge-pr715
curl -L https://prmaven.neoforged.net/NeoForge/pr715/net/neoforged/neoforge/20.5.0-alpha.24w11a.20240318.171240/mdk-pr715.zip -o mdk.zip
jar xf mdk.zip
rm mdk.zip || del mdk.zip
To test a production environment, you can download the installer from here.
Can you add methods like toImmutable() to ItemStack and FluidStack, you know, java doesn't have extension methods and it's a pain to use these factories.
toResource
/getResource
is probably a better name
toResource
/getResource
is probably a better name
Yeah, that's what I meant.
Updated with more codecs, and convenience methods.
While we are not there yet, here is what I think that a good objective would be. You should be able to replace the following ItemStack
code:
ItemStack stack = getStack();
stack.shrink(16);
stack.set(COMPONENT_1, someComponent);
stack.remove(COMPONENT_2);
// No need to call setStack(stack) because we are mutating the stack directly...
by the following code based on immutable resources:
ResourceAmount<ItemResource> stack = getStack();
stack = stack.shrink(16);
stack = stack.with(resource -> resource
.set(COMPONENT_1, someComponent)
.remove(COMPONENT_2));
setStack(stack);
@Technici4n isBlank
-> isEmpty
in IResource
?