-
-
Notifications
You must be signed in to change notification settings - Fork 198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[21.1+] Data Attachments Codec Support #1163
[21.1+] Data Attachments Codec Support #1163
Conversation
…der for AttachmentHolder
Last commit published: a80233e95d6485bde3db4ba57229444d4b63da54. PR PublishingThe artifacts published by this PR:
Repository DeclarationIn order to use the artifacts published by the PR, add the following repository to your buildscript: repositories {
maven {
name 'Maven for PR #1163' // https://github.com/neoforged/NeoForge/pull/1163
url 'https://prmaven.neoforged.net/NeoForge/pr1163'
content {
includeModule('net.neoforged', 'testframework')
includeModule('net.neoforged', 'neoforge')
}
}
} MDK installationIn order to setup a MDK using the latest PR version, run the following commands in a terminal. mkdir NeoForge-pr1163
cd NeoForge-pr1163
curl -L https://prmaven.neoforged.net/NeoForge/pr1163/net/neoforged/neoforge/21.0.61-beta-pr-1163-feature-codec-attachments/mdk-pr1163.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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IAttachmentSerializer
provides important functionality that cannot be achieved with codecs:
- The ability to capture the
IAttachmentHolder
instance. - The ability to return
null
, thereby skipping writing the entry entirely.
On top of that, I don't see the reason to move away from NBT serialization as long as Mojang continues to do it. Codecs can be used just fine already.
You can still capture the holder -- the syntax has changed slightly but gained more power as a trade-off (
Why would you even want to return null during serialization? Just.. don't serialize then.
Stream Codecs, Syncing over the network, Data Components are already moving that way... |
Okay. I think it's a bit awkward personally but there might not be a better way with codecs.
The use case was not serializing some sort of default instance. @pupnewfster Do you still use this functionality?
Let's not move attachments to that until the objects that they are attached to (block entities, chunks, entities, levels) are themselves moved over. As a side note, I have the impression that this PR only benefits people that make their own attachment holders, and want to serialize them to codecs. To make that use case slightly easier, you're asking everyone who is currently serializing to NBT to move to codecs. That is not fine by me. |
If you need to control this,
Difference of opinion here. I think this is laying foundation work to better integrate with other features of vanilla, and prepare for the future. It's not a particularly large shift in thinking. |
Two things in regards to my usage:
|
@robotgryphon, this PR introduces breaking changes. Compatibility checks
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to have a bunch of uses of TypeResolver
which don't actually seem to be necessary...? The ones on Function
especially need to be removed, cause that's an easy case where modders may have stuff nested in a utility function that ends up making the genercis unrecoverable for typetools. Basically, you can do all the same type safety and whatnot that the use of TypeResolver
seems to be meant to provide, without using TypeResolver
at all -- just toss out the fields you collect but never use, and pass in the one remaining type you're missing in the AttachmentHolder
constructor.
src/main/java/net/neoforged/neoforge/attachment/AttachmentHolder.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/attachment/AttachmentType.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/attachment/AttachmentType.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/attachment/AttachmentType.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/attachment/DataAttachmentOps.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/codec/NBTSerializableCodec.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/common/util/INBTSerializable.java
Outdated
Show resolved
Hide resolved
src/main/java/net/neoforged/neoforge/attachment/DataAttachmentOps.java
Outdated
Show resolved
Hide resolved
return attachment.serializeNBT(provider); | ||
} | ||
}); | ||
public static <T, P extends IAttachmentHolder> Builder<T, P> builder(Class<P> parentClass, Function<P, T> defaultValueConstructor) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This overload with the parentClass
arg is entirely unnecessary. For example, where someone might use
AttachmentType.builder(ChunkAccess.class, chunk -> new ChunkMutableInt(chunk, 0))
With this overload, they can instead just use
AttachmentType.builder((ChunkAccess chunk) -> new ChunkMutableInt(chunk, 0))
With the normal overload and all the type inference will just work -- I just tested this to be sure. So I'd toss this one out entirely
public Builder<T> serialize(Codec<T> codec) { | ||
return serialize(codec, Predicates.alwaysTrue()); | ||
public Builder<T, P> deserialize(Decoder<T> deserializeCodec) { | ||
if (this.serializer == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this have to be called after serialize
? That seems rather weird. Just have it throw on build if the deserializer is set but not the serializer.
* Simplify NBTSerializableCodec * Make DataAttachmentOps work with registries (in theory)
799c7a9
to
a80233e
Compare
Currently working on the stream codec support and sane typing. Turning this back into a draft PR for now while things are in heavy flux again. |
I am still not sold on this PR. I would not invest too much effort in it until there is consensus that it is wanted in the first place. |
Tech, -I- want this support in Neo, since I want better serialization and synced data attachments. That's enough for me to keep working on it. |
I would prefer to focus on the specific features that you need as a user of the API, rather than changing all of the internals. Which feature is currently missing, and why? If it is being able to serialize an
I am absolutely in favor of that. That is however a matter of stream codecs - at least in the core API, and therefore seems unrelated to this PR. Some helper to use |
@robotgryphon, this pull request has conflicts, please resolve them for this PR to move forward. |
This PR aims to add full support for codecs to the data attachment system, since Mojang is moving away from things like NBT Serializable and towards codecs and stream codecs.
The initial phase is to phase out and replace existing usages of pure NBT code, in favor of supporting codecs. It serves as a foundation for Stream codec support and sync-ready attachments.
Attachment Holder Extensions
IAttachmentHolderExtension
is an extension interface which forwardsIAttachmentHolder
API to an exposeddataAttachments()
reference. Using it means that any implementers that wish to have common attachment API simply need to expose an attachment holder, and the interfaces will do the rest.By using this extension interface, it was possible to reduce several patch files by a considerable amount.
Attachment Holders
AttachmentHolder
final, and buildable via a codec.AttachmentHolder.AsField
-- this is now the standard implementation.Internals/Documentation
AttachmentInternals#copyAttachments
to loosenfrom
to only require the interface.AttachmentType
to no longer reference ItemStacks, as items now use data components.Attachment Types
Attachment types no longer support
INBTSerializable
, due to the shift to codecs. This will need to be weighed whether it can be fully removed or if providing a wrapper viaCompoundTag.CODEC
is going to be necessary.In return, the attachment type builder has added functionality to specify a different deserializer than the serializer.
Examples
Replacements for IAttachmentSerializer/Re-capturing a "holder" reference
There is no direct replacement for manually serializing NBT data; you must switch to a codec. If a holder/parent context is needed, it is attached automatically when the attachment is created or initialized from a codec read.
Conditionally serializing data
If one needs to NOT serialize something with a codec, such as in the case of a "default" state, use the
serialize(Codec, Predicate)
override:Specifying a different deserializer than the serializer
Should you need to, you can override the default deserializer for attachment types.
This is done by overriding the
deserialize(Decoder<T>)
function, which takes either a codec or a decoder instance. Note that if the serializer is NOT set when this is called, it will throw an exception.