#ItemStack DataComponent API

1 messages · Page 1 of 1 (latest)

agile obsidian
#

https://github.com/PaperMC/Paper/pull/10845

Adds the ability to directly edit certain item data that mirrors the vanilla representation of the newly introduced data components.

This allows item manipulation that is separate from the item meta system.

Feedback

Please take a look at the task list on the pull request as we are trying to collect feedback on some of the points listed there.

Note: Some data types, most noteably components that contain just nbt blobs (entity data, etc) will not currently be exposed.

Non-Goals

This is not meant to replace ItemMeta, but to allow a more powerful way of interacting with items that may otherwise violate the inheritance tree defined by ItemMeta.

Examples

Old

ItemStack itemStack = new ItemStack(Material.CROSSBOW);
itemStack.editMeta(CrossbowMeta.class, (meta) -> {
    meta.setMaxStackSize(10);
    meta.setChargedProjectiles(List.of(new ItemStack(Material.FIREWORK_ROCKET)));
});

After

ItemStack itemStack = ItemStack.create(Material.CROSSBOW);
itemStack.setData(DataComponentTypes.MAX_STACK_SIZE, 10);
// All data types will go through a builder
itemStack.setData(DataComponentTypes.CHARGED_PROJECTILES, ChargedProjectiles.chargedProjectiles().add(ItemStack.create(Material.FIREWORK_ROCKET)).build());

New api!

Material.SNOWBALL.getDefaultData(DataComponentTypes.MAX_STACK_SIZE); // What's the default snowball stack size?
itemStack.resetData(DataComponentTypes.MAX_STACK_SIZE); // Lets reset the stack size back to its normal value

ItemStack itemStack = ItemStack.create(Material.BUNDLE);
itemStack.unsetData(DataComponentTypes.BUNDLE_CONTENTS); // A bundle that can't hold anything....
royal kiln
#

it's very verbose. I don't really have any concrete suggestions on improving that, but itemStack.setData(DataComponentTypes.CHARGED_PROJECTILES, ChargedProjectiles.chargedProjectiles().add(ItemStack.create(Material.FIREWORK_ROCKET)).build()); really is terribly long for such a simple thing

sharp karma
#

looks kinda confusing

agile obsidian
#

Yeah, some of the builder types are a bit lengthy for what are otherwise very small types. It can get pretty extensive tho for some component types.

stiff bramble
#

the name "unsetData" also kind of confuses me, is this just removing the component from the itemstack? if so wouldn't removeData() make more sense

royal kiln
#

something similar to setData(DataComponentTypes.CHARGED_PROJECTILES, List.of(new ItemStack(Material.FIREWORK_ROCKET)) would be much nicer in my opinion

agile obsidian
candid socket
stiff bramble
#

wouldnt "resetData" make more sense then if that's what it's doing

agile obsidian
#

WEll no, it doesn't set it back to default.

#

It marks it as "unset", so it has different behavior.

sharp karma
#

so it still exists technically in the item, but its set to disabled?

royal kiln
agile obsidian
#

(enchanted books/normal items)

stiff bramble
#

why not DataComponentTypes.CHARGED_PROJECTILES.create().add(Material.FIREWORK_ROCKET)

agile obsidian
#

How will that work for types that don’t have builders

#

Like repair cost, etc

royal kiln
#

maybe everything gets a builder? idk, also not great

agile obsidian
#

But it should be noted, this isn’t meant to be a super friendly api, this is meant to be powerful. Item meta will still stand and be recommended to people because it truly is better for beginners.

stiff bramble
agile obsidian
#

It’s the syntax equivalent to !

#

!minecraft:bundle_contents

stiff bramble
#

oh i see

#

makes sense

simple talon
# stiff bramble wouldnt "resetData" make more sense then if that's what it's doing

resetData resets the data to the default value, and unsetData removes the data no matter the default value

For example:

ItemStack itemStack = ItemStack.create(Material.BUNDLE);
itemStack.resetData(DataComponentTypes.BUNDLE_CONTENTS); // Makes the bundle empty again, since that's the default value
itemStack.unsetData(DataComponentTypes.BUNDLE_CONTENTS); // Removes the thing that makes it work as a bundle
royal kiln
#

if its that, removeData sounds more fitting

agile obsidian
#

We at one point had this nvm

#

cc @past wagon ?

sharp karma
agile obsidian
#

Oh wait, I am dumb

#

we have a reset and unset type, yes.

royal kiln
sharp karma
agile obsidian
stiff bramble
#

if the comment is describing it as removing the component wouldnt removeComponent() make more sense

#

er

#

removeData()

royal kiln
#

! is described by Mojang as "removing" a component

#

so I would stick with that naming

stiff bramble
#

^

sharp karma
#

that would make sense

royal kiln
#

Components with a ! prefix (e.g. "!minecraft:damage": {}) will cause this component to be removed.
from the changelog for 1.20.5

stiff bramble
#

yeah it's just weird to me that it's described as removing the component everywhere but the name itself

#

ChargedProjectiles.chargedProjectiles() creates a builder for the charged projectiles component right? if so i think ChargedProjectiles.builder() makes more sense for a naming convention

toxic sun
#

Wrapping in builders look great, verbosity is absolutely fine because you're either extracting these into static blocks or you don't care about size because you're constructing them dynamically. Don't give up on the benefit of keeping types open for future API additions for the sake of a few characters shorter code.

I think remove make more sense than unset. Would maybe look into words like negate perhaps? The docs for those methods need to be made clearer anyway.

rocky niche
stiff bramble
#

im just confused as to what this ChargedProjectiles class does besides create a builder

rocky niche
#

especially someone that still isn't familiar with all those methods and doesn't know about the #resetData, they will try to search automatically for #remove to try to remove their data

simple talon
stiff bramble
#

oh i see

#

fair enough

#

it's a nitpick anyway

rocky niche
# agile obsidian

I think the javadoc is a bit confusing here, what about "Forces the absence of this component type on the item"?

royal kiln
#

negateData? I think I still like remove, everything else seems wordy and a bit a hard for non-native speakers too

toxic sun
#

perhaps negate and "Negates the effect of any default state for this component type"

sharp karma
#

negate is a weird word

rocky niche
royal kiln
#

true. remove wouldn't have that issue, its clear you can't remove something that isn't there

stiff bramble
#

remove is the clear choice for me seeing how it's described as that in the doc comment

rocky niche
#

maybe #clearData(DataComponentType)?

stiff bramble
#

maybe but that can get confusing when compared with resetData()

simple talon
#

a more verbosed version of resetData could be resetDataToDefault(...)

rocky niche
#

yeah, too verbose

simple talon
#

yeah

toxic sun
#

i don't think it's too verbose

stiff bramble
#

i think it's too verbose too

past wagon
#

so right now, every single one has a builder which isn't great. And most only have 1 method to just create a builders. What we can do is add more static methods that just return built objects

royal kiln
#

could always just do toDefault(..), but I think its fine too

toxic sun
#

setRemoved might be clear it's actively setting something rather than removing what you already set

past wagon
#

so instead of ChargedProjectiles.chargedProjectiles().add(ItemStack.create(Material.FIREWORK_ROCKET)).build());
it can be ChargedProjectiles.chargedProjectiles(ItemStack.create(Material.FIREWORK_ROCKET));

stiff bramble
#

yeah i like that as well

past wagon
#

plenty of them don't need builders atm, like ones that are just an int or literally only 1 non-collection thing

toxic sun
#

why not just have everything be immutable and only add builders if needed later?

past wagon
#

well everything already is immutable

#

another possible improvement would be also allowing builders to be passed into the setData methods

#

similar to how adventure has ComponentLike which builders also implement

half fulcrum
past wagon
#

non of these are mutually exclusive, we can do both, add more static factory methods and allow builders

#

and also remove builders for the super simple types

#

like this doesn't need a builder

#

this one doesn't need a builder cause its just a string

royal kiln
#

how would it look with the componentlike approach?

past wagon
#

so like

stack.setData(DataComponentTypes.LOCK_CODE, LockCode.lockCode().lock("test"));
#

you wouldn't need to do the .build(), that'd be optional

#

and that setData would call .build()

toxic sun
#

these are auto-generated right?

past wagon
#

no

toxic sun
#

well in that case, just lockCode(code) surely?

#

no builder at all

past wagon
#

yeah, that's what I said above for lock code

toxic sun
#

yeah that sounds best

past wagon
#

was just demoing the ComponentLike-style approach as well

toxic sun
#

only add a builder if there's like 3+

royal kiln
half fulcrum
#

i would propose smth like that

stack.setData(DataComponentType
  .unbreakable(true)
  .customModelData(1)
);
rocky niche
half fulcrum
#

for more complex data a builder would be great for example

stack.setData(DataComponentType
  .enchantments(PaperItemEnchantments
    .showInTooltip(false)
    .add(Enchantment.LUCK, 1))
  .loadstoneTracker(PaperLoadstoneTracker
    .tracked(false))
);
rocky niche
#

this api is made to be as similar to real minecraft item components as possible

half fulcrum
#

sorry fixed it

past wagon
#

also, builders in builders is kinda annoying

#

you get bogged down with indents and paren matching

half fulcrum
#

it would match the text components in some way

past wagon
#

text components are a much more nested stucture, where nested builders at least makes some more sense

#

here, its just adding a builder layer where no nesting existed

#

so is something like this too redundant?

#

BannerPatternLayers is just a list of patterns

#

you've got a builder, but also static methods to create built instances

#

so

stack.setData(DataComponentTypes.BANNER_PATTERN_LAYERS, bannerPatternLayers().add(...).build());
stack.setData(DataComponentTypes.BANNER_PATTERN_LAYERS, bannerPatternLayers(...));
``` are the same
simple talon
#

That looks like a good way of dealing with collections to me

livid zinc
#

Maybe a nicer name for DataComponentTypes?

DataComponentTypes.MAX_STACK_SIZE would be cleaner as something like DataType.MAX_STACK_SIZE

spice brook
#

I would like if DataComponentTypes were "type" safe

livid zinc
#

especially since the methods are like .setData and not setDataComponent

spice brook
agile obsidian
#

We originally had DataType, but moved to the vanilla types because we wanted to stick with their naming.

half wave
#

datatype sounds so vague lol

agile obsidian
agile obsidian
spice brook
agile obsidian
#

yeah

#

whatever is a data component there is api for here

past wagon
#

yeah, all data component types apply to all itemstacks

spice brook
#

So I can get the pattern layers from diamond sword

past wagon
#

correct

#

they might not have any effect atm

spice brook
#

Oh weird

past wagon
#

but determine what they will have an effect on is super data driven, especially for some things

#

like what is dyeable is controlled by tags which are set by datapacks at runtime

#

so there is no way to know what the dyed color component applies to when you compile

rocky niche
past wagon
#

yeah, that's another example

#

or the tool component to make anything a tool

little hawk
#

ngl this looks sick.
Approved by me :3

livid zinc
soft lagoon
#

Love

past wagon
#

I don't think we're set on DataComponent, its just what mojang calls them, not just in the codebase, but in text they've written about like changelogs

patent swallow
past wagon
patent swallow
#

like, what happens if you apply dye color to something not dyable

past wagon
#

it just stays there on the stack, not doing anything

spice brook
patent swallow
#

sounds fine to me ig

past wagon
rocky niche
#

like if you apply a specific tag to an item, you can start feeding cows bedrock

glad wing
patent swallow
#

what was not moved?

spice brook
#

Sounds like a cool change

rocky niche
#

and many more functionality

rocky niche
spice brook
past wagon
#

default item attributs for armor

past wagon
#

default item attributes for non-armor was moved to the implicit data component system

rocky niche
patent swallow
#

I wonder why the default armor stuff was not moved

#

my guess would be shit code all around that

#

or maybe they're planning doing so later on with more changes to the system

past wagon
#

not sure, but the side effect is you can't have armor with 0 modifiers (there's an open issue on the mojira tracker for that)

obtuse bramble
#

I have a kinda related question to this pr, does that allow larger stack sizes than the give command (i.e. 99) or is that somewhere checked deeper than the command?

past wagon
#

nah, that 99 limit is not gonna change

patent swallow
#

99 is mojang imposed limit

spice brook
#

I hope they will implement this for blocks and entities too

patent swallow
#

it won't parse higher afaik

past wagon
#

yeah, vanilla client would blow up if we changed it on the server

spice brook
#

Btw do we know the reason why this was done?

obtuse bramble
#

welp was worth an ask

rocky niche
patent swallow
#

I remember fucking around with max stack size few years ago

patent swallow
#

honestly I would have jsut done what mods do and just make font smaller

#

but mojang has their weird design decisions

#

like making anvil level limit client side

#

so who knows what rules they operate by

spice brook
past wagon
#

to avoid parsing nbt every tick which was happening for some stuff, I think armor trims

patent swallow
#

to make any item be able to have basically any data

#

and that

#

I always wanted to eat bedrock

#

and now it's one command

glad wing
#

thats the main reason they said, but also its just a better system overall

patent swallow
#

on singleplayer, no

spice brook
patent swallow
#

with more players and a lot of nbt data on an item, it was definitely noticeable

#

especially with mods

spice brook
#

Those methods weren't heavy

half wave
#

sponge has had a component system for many years its pretty good

patent swallow
#

I remember hosting allthemods 7 for like 10 people and comparing items via nbt parsing was taking like 70ms per tick sometimes

patent swallow
obtuse bramble
rocky niche
# spice brook Oh I meant why the DataComponentTypes were done

a lot of behaviour now can be defined with those, like just the presense of hide tooltip hides the name lore etc completely, 1. the client needs constant checking 2. it would be terrible if all those item behaviours would be defined in a boolean in an nbt component in an nbt list in an nbt component in an nbt component in item's nbt, imagine getting this every time you need to check for that data

dense solar
#

So that's a builder design pattern? I think I can deal with that

spice brook
#

My only concern is memory usage

rocky niche
obtuse bramble
patent swallow
#

memory usage is not a concern, not on this scale

#

servers usually have more than 4gb of memory

spice brook
patent swallow
#

most people overkill on that front

spice brook
#

I have 64GB of RAM what do I care but I think it can be an issue

patent swallow
#

yep, definitely one of the people who overkill it ^

spice brook
rocky niche
umbral widget
#

What is the reason for the switch to ItemStack.create? Why not just keep the constructor syntax?

royal kiln
#

its a valid concern imo, some people create a lot of item stacks (custom item RPG systems specifically). Though without knowing how much memory is actually being used and how big the difference is, I don't think its really a big issue

past wagon
#

because eventually ItemStack will be an interface, and there won't be any constructor

obtuse bramble
rocky niche
past wagon
#

API-only itemstacks no longer exist with this PR as it just delegates everything to a (Craft)ItemStack field on ItemStack

umbral widget
#

So that is bundled with this change then, or is that separate?

spice brook
#

Btw how far are no patch API changes?

past wagon
royal kiln
#

so we no longer have ItemStacks without an underlying NMS stack? thank god

past wagon
#

yeah

umbral widget
#

Okay, that's probably more noteworthy for me than the rest of the API 😄 (not that the rest is bad though)

past wagon
#

eventually we'll write bytecode fixes to actually change ItemStack to an interface while maintaining ABI, so getting people to use static factory methods is just a thing so they don't have to change their code when that happens

spice brook
#

How far is progress on API decupling from patch system?

past wagon
#

I think its the ToDo+InProgress+InReview that's left

#

other things aren't required

spice brook
#

I saw that in Future Plans

#

It is low priority

past wagon
#

what what are you talking about?

past wagon
#

oh no, that is something else entirely. has nothing to do with API as sources in the repo

spice brook
#

Oh it is in review

rocky niche
spice brook
royal kiln
#

Wasn't that just added?

#

oh nvm that was for deprecation

spice brook
#

At least I promised I would

patent swallow
#

proper @since and @deprecated annotations? what is happening

#

it can't be that easy

spice brook
spice brook
#

But since it is a massive change code wise I am waiting for no patch API

patent swallow
#

I was jsut taking a jab at the fact that it's been over 10 years and bukkit/spigot still dont have that shit

patent swallow
#

I can imagine

rocky niche
spice brook
outer jetty
#

Quick question.

Material.SNOWBALL.getDefaultData(DataComponentTypes.MAX_STACK_SIZE); // What's the default 

this only lets me read default data right? I cannot change the default item behaviour of every item that has this material.

I am thinking about the following use case:
For example i want every food item to have a stack size of 1. Normally i would have to convert every item stack whenever it is produced.

patent swallow
#

nice to see things moving along

past wagon
#

but there might be some things where it would be valid to change the defaults for all items, not sure

#

things where the client isn't really involved (so NOT food or tools)

rocky niche
patent swallow
#

Definitely something that has gone through my head aswell, making most things stack to 99 by default for example

past wagon
rocky niche
#

it's risky that creative etc will break those items

spice brook
#

Seems fine

outer jetty
#

But won't data components make that possible?
Like when i say a certain item type should always have a stack size of 1. I would just manipulate the item stacks that are generated in the api to have those standard values. Am i missing something?

royal kiln
rocky niche
royal kiln
#

though at that point, default PDC would make sense too. Currently I do both in my fork by modifying the registry directly, and that does generally work - but I don't use any items that rely on client predictions anyways

past wagon
outer jetty
past wagon
#

yeah, that might be doable. so not so much changing the default, just always setting a component in the ItemStack constructor essentially (if none was set)

outer jetty
#

Exactly

past wagon
#

changing that would be part of the registry modification API tho, tho it would use types introduced here

obtuse bramble
spice brook
#

We need client side components now not just server side rendering anymore KEKW

#

But the client side components need to be sandboxed

abstract geyser
#

hey small pick here, but why is it named DataComponentTypes with an "s" at the end ? shouldn't such a thing be named as singular ? unless i'm missing something x)

past wagon
#

the actual type is singluar, but the holder class is plural. not sure if it should stay that way, or if the static constants should be in DataComponentType itself

#

like the fields in DataComponentTypes are of DataComponentType.Valued<T> or DataComponentType.NonValued

abstract geyser
#

ah i see i see

sinful oyster
past wagon
#

its just a departure from most of the rest of the API where the constants are in the class itself

#

Enchantment, PotionEffectType, GameRule, etc.

#

ArgumentTypes... we don't contorl the brig ArgumentType interface, so not possible to put them there

#

idk where I fall on what's better

sinful oyster
wicked dock
#

in the end it doesn't even matter 🤓

abstract geyser
#

it very much matters peeporiot

#

fate of the world and all that

spice brook
past wagon
#

Not an enum

spice brook
#

Static values then?

#

Why not enums?

past wagon
#

well we need to subclass it for one,

#

DataComponentType$Valued<T> extends DataComponentType and DataComponentType$NonValued extends DataComponentType

#

and also its in a registry, no enums for anything in a registry

spice brook
#

Oh it's a registry

bleak cargo
#

is there a dev package i can build against to test this

past wagon
#

nah. it'd be cool if we could set that up. I'd just clone the branch, then publish to maven local

robust current
#

This may seem like a dumb question, but why is a non-goal to not replace ItemMeta? I mean this API seems as mentioned more powerful and transparent to how items work natively now w the component-“ification” system.

past wagon
#

the idea is for ItemMeta to eventually just be re-implemented to wrap around these data component types

#

the concept of ItemMeta is still useful as interfaces because they are easier to work with, just case to an interface and call methods on it

#

longer term, basically ever item meta will be castable to any other item meta so you could just use those the same way you use these data component types

#

and the idea of taking a "snapshot" of something is also useful which this doesn't replace

eternal apex
fathom mantle
compact gorge
#

I dont think it should be called DataComponentTypes, i think ItemComponent would be a better name

#

i think it should be very close to nms

sinful oyster
#

I mean, the current name is very close to NMS

toxic sun
#

the point is it may be used for more than just items in the future

#

so item component a bit silly

compact gorge
#

right but i dont think entities will have a max stack size

sinful oyster
#

It is literally designed as a generic system in vanilla

compact gorge
#

fair

toxic sun
#

otherwise we'll end up with ItemComponent EntityComponent etc etc all with identical systems in the backend

compact gorge
#

yeah fair enough

obtuse bramble
late quiver
#

Everything is 😄

wicked fog
#

But I would still like if there wasn't any in the firstplace

spice trout
#

My 2 cents: I don't like that there are going to be two completely different APIs (ItemMeta versus the new one), one being easy to use, and the other being powerful. If you hit a wall with ItemMeta, you would have to learn a completely different API. I'm more a fan of the so-called progressive disclosure of complexity ("simple workflows should be quick and easy, while arbitrarily advanced workflows should be possible via a clear path that builds upon what you've already learned").

So what do I propose? Let's make the new API easy to use, and ItemMeta redundant! 😃 If you use builders everywhere, you can at least simplify the setters:

    itemStack.setData(DamageComponent.of(20));
    itemStack.setData(CustomNameComponent.of(text("Custom name")));
    itemStack.setData(ChargedProjectileComponent.of(ItemStack.create(Material.FIREWORK_ROCKET)));
    itemStack.setData(LockCode.of("test"));```

The components are still wrapped, so if vanilla adds more fields to components you should be safe.

For the getters, things are still complicated unfortunately:

```   itemStack.getData(DamageComponent.class).getDamage()
   itemStack.getData(ChargedProjectileComponent.class).getStacks() 
   Material.SNOW_BALL.getDefaultData(MaxStackSizeComponent.class).getMaxStackSize()```

So it would be nice to keep some convenience methods directly on ItemStack and Material, such as `getMaxStackSize()` and `getDamage()`. So there's still duplicate API in some cases, but at least the methods nicely build upon each other.

```    itemStack.getMaxStackSize()
    itemStack.getDamage()```
past wagon
#

So a lot of what you said about simplying the setters is already done. I just added static methods yesterday on a lot of the components to create them directly in addition to the builders

#

so like LockCode.lockCode("test") and ChargedProjectiles.chargedProjectiles(ItemStack.create(Material.FIREWORK_ROCKET)

#

for the ones that take lists I added lists and a vararg overload

#

some of them tho, I left as just builders, especially the super complicated ones like FoodProperties

wicked fog
past wagon
#

Yeah, they aren’t of methods

hoary zenith
#

I realy like this new api. One thing I am missing would be the PersistentDataContainer. Could this be added to ItemStack directly to avoid using the ItemMeta at all?

late quiver
#

I think that's this one:

minecraft:custom_data, expose or not? Just that one, not the other entity/block CustomData ones

#

Well, PDC would be a subset of that I suppose

hoary zenith
#

yes that contains the pdc data, but i don't think the current pr exposes that, it would require a full nbt api afaik

bright stump
#

(which we wouldn't add)

hoary zenith
#

yes, thats why i would like to have access to the pdc from the ItemStack itself (or maybe from some otherwise opaque CustomData object)

past wagon
#

Yeah, I have some local diff to access PDC from ItemStack

#

It can’t be setup “exactly” the same way as other places, via PersistentDataHolder, but there will be a read-only view and editing via a consumer

#

like

PersistentDataView getPersistentDataContainer(); // only has readonly methods, no set, remove

void editPersistentDataContainer(Consumer<PersistentDataContainer> consumer); // provides a pdc with the normal get/set methods

@hoary zenith

hoary zenith
#

ok thats cool 🙂

random forge
#

You can set the max stack size? Does this work past 64?

sinful oyster
#

Yes, the new maximum when set with components is 99

random forge
#

That's cool but I wish they made it more lol obviously not vanilla base game but for dev purposes

terse quest
#

This API seems like it will remove the need to do this, right?

toxic sun
#

well, not really no

agile obsidian
terse quest
#

Wait what? There isn't just one Color component?

ionic copper
#

there is map_color, dyed_color, and potion color is done inside potion_contents

rocky niche
late quiver
#

You shouldn't be looking to this API for ease-of-use, in general it's going to be harder and/or more verbose than ItemMeta.

terse quest
#

Fair enough. I just thought there would be one color component to work across all colorable items.

severe moat
past wagon
#

use pdc

severe moat
#

as of now

#

cus after update there will be 2 pdc? in item meta and in itemstack

past wagon
#

pdc will be available directly on ItemStack before this change

severe moat
past wagon
#

I mean both ways of accessing pdc store stuff in the same place, from ItemMeta and from ItemStack

severe moat
#

hmm then is there any faster way to do shit with tags?

past wagon
#

I mean... this will be pretty much as fast as possible, what are you looking for?

#

any change to the custom data requires copying the full custom data tag to maintain immutability of CustomData

severe moat
past wagon
#

its not parsing full item meta, wdym

#

if you don't call getItemMeta, its not parsing it

severe moat
past wagon
#

what item meta call?

severe moat
#

or idk smth like that i can't code without intelij 💀

past wagon
#

just don't call that? pdc will be available from ItemStack

#

its not going to use itemmeta to get the pdc, it'll use internals and just access the nms data component CustomData directly

severe moat
#

so nothing would change to pdc than place to access it to faster read the ability in my plugin after 1.21 update

past wagon
#

yes, reading will be as fast as possible because no copying has to take place

#

writing any data does have to copy the entire existing custom tag, but that's unavoidable

eager wedge
#

Reminds me of the keys system from Sponge, I like it

night solstice
#

Is JukeboxPlayable not fully implemented? trying the PR now but cant seem to set JukeboxSong
opened a PR earlier with crucial typo fix and some minor stuff aswell

agile obsidian
#

Didn’t test it yet

night solstice
#

no way to set a sound in it

#

only exposes showInTooltip

agile obsidian
night solstice
#

no builder seems fine
meant that the JukeboxPlayable doesnt let u get the JukeboxSong, like there is no getter

#

also JukeboxSong is just the bukkit interface
doesnt have its own under paper yet like say Food

this is my current impl for serializing a food component

jukebox would look something like this, but the JukeboxSong and SoundEvent stuff isnt there

#

if im understanding it correctly

agile obsidian
#

Ahh yeah

#

I forgot to add the getter oops

night solstice
#

getter is one part of it but u cant build a component rn from a custom sound
like it will only accept the onesvanilla defines

#

like none of this is configurable atm

agile obsidian
#

I’ll take a look

night solstice
#

prayge thanks

agile obsidian
#

I didn’t think it allowed inlined sound events tho

#

Because I’m not sure if those would work? It has to be a disc under the registry

night solstice
#

i might be misunderstanding it then iguess

#

so the soundEvent is registered via datapack with all the stuff here

#

then the component just takes a key essentially which would be sound_id here

#

/minecraft:give @p emerald[max_stack_size=1,custom_model_data=1,jukebox_playable={song:"mineinabyss:orth_waltz",show_in_tooltip:true}] 1
hence this is the cmd i use

#

so yeah something like this and its just missing the getter

night solstice
night solstice
#

not sure on this though as the holder is optional, just .get feels abit wack

agile obsidian
#

Because it’s a holder either

#

@night solstice Yep, look for unwrap

night solstice
late quiver
#

iirc the provider is either MinecraftServer or is on MinecraftServer

night solstice
agile obsidian
#

MinecraftServer#getDefaultBlahBlah

#

@night solstice Go ahead and push whatever you've got

#

But feel free to test the other components if you'd like

night solstice
night solstice
night solstice
agile obsidian
#

Don't worry I will resolve

#

mapitemcolor was wack rest seem fine
Will look into that :_

#

🙂

#

what was "wack"?

night solstice
#

well it used bundle stuff, but fixed it in the PR

agile obsidian
#

oh lol

late quiver
#

Oh that was the one using a bundle builder

agile obsidian
#

Yep

late quiver
#

Wrong type

night solstice
#

can just push what i had now tho feel that unwrap should work

agile obsidian
#

Owen going wild on the copy paste

agile obsidian
night solstice
#

like am i drunk? it is 1am but like pepehmm

agile obsidian
#

I assume you are using the paper api

#

Which, not right type

#

Just provide

#

MinecraftServer#getDefaultRegistryAccess

night solstice
agile obsidian
#

ty

#

ty for ur help btw 🙂

night solstice
#

no worries been waiting on the PR for a bit so might aswell help out the little i can

agile obsidian
#

Feel free to look through and make any more changes

night solstice
#

im sure theres another typo or two pepesit

#

btw does CreativeSlotLock do anything at all?

#

or is this the only spot it does anything?

#

right also was RECIPES meant to take a java.awt.Key and not a kyori Key?

agile obsidian
agile obsidian
#

it only affects the creative menu

night solstice
agile obsidian
#

Will be useful if theres a time we can add our own items to the creative menu

night solstice
#

true true, more and more stuff is becoming accessible, 1.20 and 21 some of my favorite updates ngl

#

just make data driven blocks now so i can be freed from noteblock hell aaaa

agile obsidian
#

TRUE

#

@rocky niche btw merged ur javadocs 🙏

night solstice
agile obsidian
#

correct it should be kyroi key

rocky niche
night solstice
#

free friday? not heading to the land of shadow?

agile obsidian
#

But i'll leave some (am lazy)

rocky niche
agile obsidian
#

perfect perfect

#

i'll leave some and whatever work people want to do, feel free to PR 🙂

rocky niche
#

it'll become a pr to a pr to a pr (merged) to a fork of a fork of a fork of Minecraft XD

night solstice
#

why does CMD not just take an Integer similar to REPAIR_COST and DAMAGE ones?

#

same for MAP_ID i suppose

agile obsidian
#

Kinda a thing that we'll finalize later

night solstice
#

gotcha, yeah just felt more pointless since it just takes a primitive integer anyway
i assume Integer which allows for null would be more logical same as DAMAGE etc

#

anything else thats "left"? would love to see this merged if i could help speed it up

rocky niche
night solstice
#

i guess boneshrug just not sure what more complex they would do with cmd for example

rocky niche
#

may start using a resource location instead of a magic value as a random int for example

#

repair cost may start keeping more data about what influence the repair cost for example

#

etc

night solstice
#

repair cost i can see yeah, fair argument iguess

#

im suprised they didnt merge damage and max_damage into one durability component though

rocky niche
#

I think that's for easier .has(DataComponents.MAX_DAMAGE) in the code

night solstice
#

meant moreso mojang directly but yeah
i just hate the word MAX_DAMAGE describing somethings durability lol

rocky niche
#

yeah, because internally items don't have "durability", only the amount it has been damaged and the damage point when it breaks

night solstice
rocky niche
#

and they never had it

night solstice
#

yeah though this is the only user facing one

#

which is prob why it feels weird

rocky niche
#

because users will be more confused by that damage

#

but components are more used internally and aren't meant to be that common user friendly

night solstice
#

internally i get it
just saying i prefer durability cuz thats what ithink most players are used to due to the only time they "interact" with the value it is called that

#

excluding that yes damage and max damage make more internal sense iguess

rocky niche
#

because they are shown to everyone as object with 0 data

#

but we can't be sure that they won't just decide to add data at any point in the future

night solstice
#

iguess tho nonvalued are just there or not
but yeah in theory they copuld iguess add data to FIRE_RESISTANT down the road and that might be wacky but

late quiver
#

The lower level you get the more powerful but also the more likely to break with MC updates, that's nothing new

#

I would expect some part of this API to change every other MC update for a while

agile obsidian
#

Correct

#

This api will generally be “unstable”

#

Item meta will still be a very good alternative

rocky niche
#

Still I think possible breaking should be minimized

rigid oak
#

no break everything

late quiver
#

The problem is if you want to make something like this less likely to break you need everything to do take a class instead of unvalued or a primitive

#

And then you need to try to convert/patch any differences later or at least make them still compile

#

Like if custom model data changed to use a resource key instead of an integer the class would still take an integer that just wouldn't do anything

#

That API would be even more of a PITA to work with though

#

And as changes happened would get more and more confusing

agile obsidian
rocky niche
#

Then could there be a DataComponentType.Valued<T>#getType which returns Class<T> to check compatibility?

little hawk
#

I think I agree with powercas. Make it break once it chances, but specify in the docs it does. And maybe make it optionally take just a raw object which internally paper just parses to the required type, so that you can pass your data cross-version to different formats

rigid oak
#

where’s the docs pr @agile obsidian

rocky niche
#

Enchantments now also uses data components

#

techically this is also possible (client can't receive that)

var item = new ItemStack(Items.DIAMOND_SWORD);
item.set(EnchantmentEffectComponents.DAMAGE_PROTECTION, List.of());
return CraftItemStack.asCraftMirror(item);

Will those Data Components be in the same class as the item data components or will you move them?

past wagon
#

yeah, we need to figure out how we want to do that in the API.

#

I think there really has to be some separation with probably an EnchantmentDataComponent type that shares no inheritance

rocky niche
#

Wasn't the reason why it wasn't called ItemDataComponents so that all the api could be reused?

#

or was it ItemComponents

past wagon
#

Well… some of them apply to block entities, and we aren’t sure how it’ll be expanded to those in the future

#

Like if block entities end up with the same system and they are shared between items and block entities, calling them item components is wrong

rocky niche
#

Maybe then let all be DataComponentType (both item components and enchantment components), just create a separate class that contains the instances (like ItemDataComponents and EnchantmentDataComponents) and if in future they'll be reused, just make the type instance being shared between those classes? And of course just on api side validate the component type before setting it, so no item would have an enchantment data type

past wagon
#

The class that has the fields doesn’t matter. The code probably shouldn’t compile if you try to set an enchantment data component for an item

rocky niche
#

can we be sure that the same PREVENT_EQUIPMENT_DROP from enchantments won't be reused in entities then?

#

since all are DataComponentType, anything can be reused later anywhere

past wagon
#

What types NMS is using is pretty irrelevant I think. They are 2 separate registries.

kind geyser
#

Has this API already been added to the newest version of paper?

royal kiln
#

not yet. see the PR in the pinned messages, its still open

viscid burrow
#

is there a means to compare stacks ignoring certain components?

#

(thinking of stuff like damage being a long term headache regarding itemstack comparability)

wicked fog
#

On that note, when we will have proper itemstack matchers for recipes?

viscid burrow
#

recipe stuff is a seperate mess

wicked fog
#

😔

compact gorge
#

would be nice to check if an itemstack had a superset of components of another one

#

crude method of comparing items but would probably work for recipes

royal kiln
#

Regarding #paper-contrib message

Since this PR was opened I have worked quite a bit with the NMS data components.
The singleton objects aren't really that bad, but it does feel needlessly verbose to need an entire object for something like CustomModelData which is literally just one value.
So unless it's a lot of effort, I would very much prefer direct values, but the way vanilla does it is okayish too

versed torrent
#

having a wrapper even around simple values like CMD at least protects you some amount in case it needs to be expanded or altered in the future rather that it being straight up an incompatible change

royal kiln
#

Yeah. At least with custom model data it wouldn't surprise me if it gets changed in the future, the whole "magic int value that the client uses in predicates" is a bit of a hack

late quiver
#

Wrappers protect you if vanilla adds more fields, it doesn't help if they change it entirely like you're talking about there

agile obsidian
#

Thanks for the feedback!


 ItemStack oakLeaves = ItemStack.of(Material.OAK_LEAVES, 1);
        oakLeaves.setData(DataComponentTypes.HIDE_TOOLTIP);
        oakLeaves.setData(DataComponentTypes.MAX_STACK_SIZE, 1);

        ItemStack otherOakLeavesItem = ItemStack.of(Material.OAK_LEAVES, 2);

        Assertions.assertTrue(oakLeaves.matchesWithoutComponents(otherOakLeavesItem, List.of(DataComponentTypes.HIDE_TOOLTIP, DataComponentTypes.MAX_STACK_SIZE), true));
#

Using this new matchesWithoutComponents method allows you to exclude certain components / ignore stack size when comparing an item.

rigid oak
#

i don’t like setData

agile obsidian
#

That’s been finalized, I think. 😛

But feedback would be appreciated on this new method.

rigid oak
#

method name is a little long

agile obsidian
#

Unsure of a better name

#

Maybe just matchesWithout?

#

matchesWithoutData

#

Decided to keep map color as a singleton due to its default value

#

cc @royal kiln

trim copper
#

Is there a matchesWithData method?

rigid oak
#

what are the other “matchesWith/without” methods

agile obsidian
agile obsidian
#

(Indicated by the Boolean flag)

rigid oak
#

the components in the name feels weird then

agile obsidian
#

There’s no more component in name only data

agile obsidian
# paper fern This ^

Thing is these types are gonna change alot, like this api is meant to be kinda bleeding edge in terms of MC version support. But at least for the types I changed, no way mc is gonna change that for a while.

#

Except model data

paper fern
#

Well we'd want it to not be completely bleeding edge, otherwise there is 0 benefit over just using nms

#

While we cannot promise as much backwards compat, having the ability to at least attempt it, is something I think is worth it

viscid burrow
#

It's 2024

#

We can either pretend that backwards compat is a huge ass given

#

or, we can accept that stuff changes and just accept that people over the years are going to have to deal with breakages

#

A lot of these rawish data interfaces are going to heavily mirror internals, outside of going sponge level of property based access where we can tell people query everything before you set, we are effectively going to just end up mirroring what mojang did

#

over time, mojang will stabilise this stuff, and if needs be, we can work on documentation teaching people how to deal with versioning if needs be; We're long past the snowball of pretending that mojang changes nothing

patent swallow
#

I'm not sure how willing people will be to educate themselves about versioning. Uberjars are expected by most people nowadays. There's a slight shift, but it's going slowly

#

Just yesterday I've seen a random plugin drop paper because some breaking change, now sure what that was about

#

going into sponge context-like system seems like more rational approach

rocky niche
# viscid burrow over time, mojang will stabilise this stuff, and if needs be, we can work on doc...

If compatibility with this api breaks so easily, what's the use case for this API? Libraries will continue to use nms, since nms was and will always be more powerful, and will even retain spigot support. Plugins will not want to use this so eagerly, since they want easy multi version support, I don't think anyone nowadays wants to start making a public plugin that will not retain support for at least 1 major version older, so for matters that ItemMeta won't be sufficient, they'll just use good old nms in different modules for which plugin authors will be able to find hundreds of guides, examples and more support outside of this server. Because multi version support for this api would mean some unchecked castings, where a new version could change it, and because plugins usually use the oldest supported version's api and may not notice a change in a never version, it'll be much more dangerous to use than using nms directly in different modules with letting java make its compile time checks. Also promoting such API may result in the fact that server owners will upgrade their servers to newer versions much slower, since a lot more plugins will need updating to add support for newer versions, not only the ones using nms anymore

viscid burrow
#

The API has never promised backwards compat

#

The entire goal of the API is to expose safe access to internals

#

If you want to take advantage of newer features, you are going to tie yourself closer towards mojang moving stuff around

#

i.e. how many servers these days are relying on things like data packs?

#

The refusal to break stuff ever is literally how we got into the situation where ItemMeta is broken as all heck

patent swallow
#

noone here says never break stuff forever

#

but aiming to design the api to not break is not bad either

rocky niche
# viscid burrow The API has never promised backwards compat

yeah, I understand, but such a fast breakage just could make things unusable for anyone, at least fast deprecation policies, like if api was added in 1.21, and in 1.21.1 something broke, give time with some backwards compatibility until 1.22, don't break plugins the moment something changed

patent swallow
#

breaking api every version is exact extreme opposite as spigot's unwillingness to break at all

viscid burrow
#

I'm not saying it should be designed to break every version

#

What I'm saying is is that there is going to be some level of acceptance that the components themselves will need to change across versions

#

we shouldn't be trying to avoid that as it just creates the snowball we've already seen

patent swallow
#

the more I see on the topic, the more I believe we need api version separate to minecraft version

viscid burrow
#

Part of the issue is that as time goes on, exposure towards the internals is going to become more important

#

The goal is to isolate that sorta stuff over to data generated stuff

#

but, the core of the API should generally be stable

rocky niche
viscid burrow
#

but, we're not going to provide backwards compat for generating entries into the registry, for ex

#

I mean, there isn't really much you can do to avoid primative types changing, not unless you wanna overcomplicate the design

half fulcrum
viscid burrow
#

maintaining wrapper data classes will let you shim some level of that

patent swallow
half fulcrum
#

if you are already making a paper plugin and compiling against paper you are basically required to adapt to changes
otherwise dont use paper features

rocky niche
viscid burrow
#

Pretty sure I did say to go more towards a wrapper, I, er, brain spin

#

but, a primative type changing would still likely end up screwing you over

#

the only way a "sponge esque" type thing would make it easier would be that plugins could query the data type and pass in the correct thing

#

they'd still need to handle doing the update, but, backwards compat would be cheap

patent swallow
viscid burrow
#

only problem is that sponge stuff tends to be scary

#

(and like, a whole investment to do)

patent swallow
#

yea, sponge has that stuff figured out in a pretty nice way

#

if we could even get as much as close to that

agile obsidian
#

So like it should be noted most types use wrappers, the only types I moved over is the lock code value, custom model data, and map id.

late quiver
#

This last bit of discussion feels like an argument for killing the project and just doing some events as a fabric mod

viscid burrow
#

I mean, the strong reason for spigot and such still existing is that they didn't go blazing fire scorched earth

#

ItemMeta will still exist, just it's been in a weird state for years

#

We shouldn't design stuff to just blindly break, but, also, outside of masking certain sorta things, if you want to come to interacting with lower level stuff, you're going to need to be ready for it. We can deal with some levels of breaking changes, but, we're very unlikely going to be dealing with breakages inside of the registry/datapack stuff that we end up with

night solstice
#

is the current PR been rebased to 1.21.1 yet? need to publish it locally as wanna test i tout again in my plugin

#

nvm got it to work, was using a bad commiot hash rikothumb

past wagon
#

whatever, its not that big a deal to have wrappers

#

I'm not for having a wrapper for like durability

#

but wrappers for map id, custom model data, lock code, make sense to me

#

those I can easily see changes in the future, 2 are just random numbers, 1 could have further customization

patent swallow
#

it's still not intuitive to me tbh, the entire durability -> damage change

night solstice
#

im confused what custommodeldata would change to in the future?
like mapid could perhaps be a key i suppose, but what would CMD be if not an integer?

patent swallow
#

it's not likely that it will change

#

but it can change

#

that's the crux of the problem

#

how to design an api that does not break if such change happens

night solstice
#

imean i suppose, feels like a weird change but mojang does funky things so

past wagon
#

those are much better identifiers

#

they recently changed attribute modifiers from UUID to resource locations

#

things like damage, max damage, max stack size, I think those should stay as "ints"

night solstice
#

yeah just so used to it being an int that couldnt see it being a key lol but makes sense
would honestly fix some RP issues aswell cuz rn the overrides for a model HAVE to have their CMD values in order, 2 cant be defined before 1 etc

#

would be abit odd still as the override would probably still have the model-path AND a cmd-key which would prob be the same but

late quiver
#

Watch 1.22 they make damage a double

night solstice
#

is bee component removed? or is that part of the blockdata one now?

late quiver
#

I thought this PR didn't have API for all the components

night solstice
#

might leave out some, just faintly recall some todo comment about it and other block-related components

late quiver
#

Some of them require additional API larger than this PR to set up things for this PR to actually call

night solstice
#

would it be feasable in theory in the future to register custom datacomponents in a bootstrapper?
not sure how that all works here or we still delegated to relying on pdc/custom_data component for that stuff?

past wagon
#

we aren't adding API for a specific few on purpose

past wagon
late quiver
#

Custom data components are basically in conflict with PDC

#

Err, I meant the custom_data component

#

Not entirely new components

#

For entirely new components you either have to hide them from the client (breaks creative mode) or have a client mod so the client knows to expect them

night solstice
#

Gptcha ok. Well customdata component does the job so no biggie. Thought maybe client had some logic for it like it does other registries that are now datadeiven

past wagon
#

I don't know what we are adding the custom_data component, just keep using PDC via the ItemStack

night solstice
past wagon
night solstice
past wagon
#

we aren't adding, at least initially rn, any CustomData one, so custom_data, entity_data, bucket_entity_data, block_entity_data

#

debug_stick_state I think isn't in yet either

#

and bees

night solstice
#

Alright well the most crucial ones are there

agile obsidian
#

Aighty I’ll readd those wrappers

past wagon
#

So I think only 3 should be primitives, max stack size, damage, and max damage

#

we def don't be builders for a lot of those simple wrappers tho

agile obsidian
#

That’s fair

past wagon
#

I think if its only 1-2 required fields that aren't collections, we don't need builders

patent swallow
#

you can take a l👀 k how minestom handles item components

agile obsidian
#

Wrappers have been added, but dont use builders now @past wagon

trim copper
#

What’s lockCode again?

versed torrent
#

adventure mode stuff iirc

rigid oak
#

a code that locks

rocky niche
# trim copper What’s lockCode again?

if you have that component on some block items like chests, after you place the chest, you'll be able to open it only with an item named exactly as the lock code

late quiver
#

Doesn't work for doors, fail 😛

rocky niche
#

yeah, seems like only containers

agile obsidian
#

Yeah only certain block entities

past wagon
#

so not a big fan of the name PossibleEffect for FoodProperties

#

well maybe its fine... idk, its wierd that the probablity is inside of it

past wagon
#

ok @agile obsidian so we don't have a way to turn data components back into builders... so you get a data component and you want to change smth about it on the stack, you have to manually copy stuff over

#

what is the best way to do that, are people using "toBuilder" methods, or static methods that take an instance of the component that return a builder?

agile obsidian
past wagon
#

should we have methods on the data component to "change" stuff, but just return new instances, like adventure does?

#

if we did that, we probably would want to get rid of more of the builders, since they'd kinda be redundant for some of the simpler types then

past wagon
#

ok, pushed a ton of javadocs

#

regarding matchesWithoutData, should we just keep with the isSimilar method name

#

isSimilarIgnoring(stack, excluded)

#

I don't think we need an "ignoreCount" boolean

agile obsidian
agile obsidian
#

(Which I find likely to change in future)

trim copper
#

If there is an isSimilar it makes sense to have an isSimilarIgnoring instead of matchesWithoutData

versed torrent
late quiver
#

What does adventure do?

versed torrent
#

Buildable#toBuilder, BuildableComponent extends Component, Buildable<...>; it stinks that you have to cast Component to BuildableComponent

#

although adventure also has with-ers (just, without the with prefix), Component.style(Style), Component.color(TextColor), TextComponent.content(String) etc return a new Component
but you do have the ability to turn it into its Builder type if you want to

agile obsidian
past wagon
#

yes

#

people almost never care about stack size

viscid rampart
#

I was using itemStack.damage() fine on 1.20.4 to damage as it says the item so it lose durability, now in 1.21, what is the new method?

#

It wasn't marked as Decapred

#

Is it this?

past wagon
#

I don’t think any method was removed was it?

night solstice
#

whats the default material of the item?

viscid rampart
#

It was between 1.20.4 and 1.21

#

I skipped 1.20.6 so Idk

night solstice
#

is it STONE or DIAMOND_PICKAXE or que?

past wagon
#

It’s possible it was deprecated in 1.20.6. I still don’t know exactly what method you are talking about. There is still a damage method in ItemStack

night solstice
viscid rampart
#

You need a living entity to damage an ItemStack?

#

That's a weird concept

royal kiln
#

No, you just use setDamage on Damageable

#

The living entity method is for when you want to trigger enchantments and stuff

viscid rampart
#

Yeah that's how I did it

agile obsidian
#

@past wagon so what do you think we should do. Should we have a to builder and have interfaces similar to adventure

half fulcrum
#

my opinion wasnt explicitly asked but personally i would prefer that

past wagon
#

yeah, lets start out with a few toBuilder methods for the more complicated components (food & tool). Maybe later we can add direct methods to change specific things without going through the builder

#

ok, gonna also change to isSimilarExcluding...

#

and will make it also have a varags option as well as a collection

#

are there any other "equality" checks that might be wanted?

#

like an opposite to isSimilarExcluding? only check these specific components, an isSimilarIncluding

half fulcrum
#

only testing components equality ignoring the material maybe

agile obsidian
#

Idk about ignoring material

agile obsidian
royal kiln
#

Ignoring material sounds useful

past wagon
#

I mean at that point, you are just comparing 2 collections of data components

#

I think, then, you can just do the comparions yourself, getting the various ones and checking if they are equal to what you are expecting

agile obsidian
past wagon
agile obsidian
trim copper
#

But if you only want to check if the damage is the same?

past wagon
#

if the method is on ItemStack, we aren't gonna have methods to ignore item type, that seems super dumb

#

if/when we add dedicated "map" types that just hold data components, maybe those can go there

agile obsidian
trim copper
#

You can still check for more properties

#

Sometimes it makes more sense to check including properties instead of excluding properties. Just from a perspective of understanding the code.

past wagon
#

ok, I added one toBuilder method for FoodProperties. Not sure what the best way to populate the builder from the implementation is. Currently, its just using the builder methods themselves, but maybe a BuilderImpl ctor is better, less likely to miss smth then

rocky niche
#

Yay, the food component from this api is no longer valid

#

(changed in new snapshot)

night solstice
#

to add onto the convo in #paper-contrib ithink it makes sense for this to act as a "version exclusive" api
aka have breaking changes like food component in 1.20.5->1.21.1 and then consume component breaking that in 1.21.2
otherwise this is likely gonna be on hold for ages cuz mojang gonna probably keep changing stuff

itemmeta is there if u wanna use the more version safe stuff
and if u want cross-version logic, that should be up to the project to handle not this experimental direct component approach

viscid burrow
#

That is generally what I said eons ago

#

the closer you get to the metal the more you're going to have to risk breakage

#

ItemMeta is stupider and will likely not survive another 10 years, but, can serve as some level of bridging for now

trim copper
#

Yeah I think that would be a good idea.

untold schooner
#

I agree, reality is Mojang is gonna keep making changes almost every snapshot I think developers are going to have to accept more breaking changes for more modern API.

late quiver
#

Unless you go back to ItemMeta's "expose the concept/feature/functionality, not the implementation" and come up with a completely different API I don't think you're going to be able to avoid breaking changes here

#

You can paper over minor ones but a component completely changing how it works, splitting up, etc you really can't

#

A higher level API to be more immune to Mojang changes would probably either look like a better (and flatter) ItemMeta and probably still couldn't handle removing components or would look more like Sponge's API where it's more fine-grained and you still probably can't handle removing components

#

To handle removing components you have to expose that they exist and that means when Mojang moves something from one component to another you have to have a breaking change to reflect that

#

Unless you just do a flat ItemMeta and only talk about components for the API to remove them but that's still going to have breaks if someone wants to remove food but then food gets split in half

trim copper
#

I think specifying it as experimental and putting a disclaimer in every jd that is remotely related to IDC api is the only thing you can do 🤷🏼‍♂️

versed torrent
#

idk if experimental but maybe some Unstable annotation

#

because the components are by nature unstable while the api itself is (or, well, will be, eventually) no longer experimental

toxic sun
#

yeah just needs to be something that shows up in docs - don't need the ide warnings

trim copper
#

Sadly many people do not read docs

toxic sun
#

yeah but are those people gonna suddenly pay attention to yellow highlighting in their ide? no

#

so let's cater to the good devs who don't need suppress warning annotations everywhere

trim copper
#

Good point.

versed torrent
#

not to mention this is a lower level "if you know what you're doing" api 😅

trim copper
#

Still, a message in the jd could be added as well but yeah, no need for a warning

late quiver
#

It's a lower level API but it's the one everyone is going to want to be using

untold schooner
#

I see no reason we need to consider version compatability when we actively push people to be on the most modern version.

late quiver
#

It's faster, more powerful, less buggy (conceptually anyway), and easier to understand if you do technical MC because it matches what you can find on the wiki and in commands

#

Well, the more likely plugins are to break between versions the less likely people are actually going to be on the latest version

agile obsidian
#

Yeah thats the thing, this api is sort of meant as a powerful alternative (but not replacement) for item meta, but also is 100% not as "user friendly" as item meta, and obviously with it more closely representing how MC actually handles items it will just be prone to being a bit more unsafe.

#

(Like future plans is to move item meta to actually just use this api implementation under the hood)

#

This is similar to the whole brig api, I think.

viscid burrow
#

any blockers on merging this? I can't 100% commit as bootcamp go brr, but, I can try to make myself available for your late-night merge session this weekend or whatever if it would be beneficial to getting this in

#

Might make sense to get it in now as experimental API before .22

agile obsidian
wicked fog
#

merge?

#

MERGE?

late quiver
#

Redo the food stuff was to prepare for 1.21.2

#

If you merge before then and just have 1.21.2 show people this API really is unstable then you can leave it

agile obsidian
#

Well my thought is the food would be merged with stuff deprecated for removal, saying that this will be removed next update to align with MC's new representation for consumable items.

viscid burrow
#

I mean, it makes sense, either we hold back what people can do or try to find as much of a viable middleground for moving forward as is possible

agile obsidian
#

hehe

agile obsidian
#

But the thing about this api is that there will always be item meta, so I am less worried about having more agressive changes with this (experiemental/unsafe?) API as there is always the long standing alternative.

wicked fog
#

which way should be takled by plugins wanting to support a range of versions which have breakage?

#

in that sense, if there is a way to pass things like SNBT or other way the componets without sustaining compile errors?

late quiver
#

The APi would break because the actual components changed

#

So your SNBT wouldn't work either

#

Or your commands, etc

wicked fog
late quiver
#

If you just wanted to make a static item you could serialize an ItemStack and store that somewhere, when loading it would go through DFU and might still work like you expect on new versions

wicked fog
#

not a bad idea...

#

is it recommended somewhere?

#

but.. won't SNBT also allow DFU conversions?

late quiver
#

Not usually, no

wicked fog
#

I mean, how would one serialize and put an Item into source code?

late quiver
#

It doesn't have any kind of versioning in it iirc

#

Serialize and base64 then copy/paste into the code or a config file

#

Or serialize and save to binary file and ship that in your jar as a resource

wicked fog
#

why would it need to be binary when SNBT exists?

late quiver
#

Because SNBT stuff usually doesn't have MC version in it so it doesn't know what DFU pipeline it should go through

wicked fog
#

unless SNBT has format changes like with forbidding [] or whatever, but that might be a way to store readable dat?

late quiver
#

And there is no API for loading SNBT anyway iirc

wicked fog
#

yes, that is my point, why not adding a serializeToSNBT method?

paper fern
#

I think if we want to offer some backwards compatibility, that has to come from whatever abstraction layer we build on top of the component API

late quiver
#

I think as a part of this PR it was adding some ability to save ItemStacks in to yaml as SNBT that would include versions?

#

Maybe that was meant to be a followup

#

Existing API only gives you binary though (a byte[])

paper fern
#

Like, ItemMeta but more of a "what do I want the item to be, kinda vibes

agile obsidian
late quiver
#

So unless you want your plugin to be 1.21.1+ only you'd need to use the byte[] version to support multiple versions

wicked fog
#

serializeToSNBT() would allow devs to put in a VARCHAR in the DB instead of BLOB to put such items in code while still able to read what it does

agile obsidian
#

Not sure, its not within this PR.

late quiver
#

Probably a bitrotted a bit

#

But yeah, that's a separate thing so this discussion should probably happen somewhere else

wicked fog
#

fair enough

agile obsidian
paper fern
#

Yea. The optics of pushing component API as like, the go to way to create and edit items is kinda bleh

#

it is on the same level of "you know what kind of shit you are doing" as registry modification

late quiver
#

The something new on top would probably look like ItemMeta but flattened to be a single grab bag of data that has more consistent (and tedious to work with) has/get/set methods

paper fern
#

Yea

late quiver
#

But if you want to do any of the fun new stuff like making a stick into a sword you need the component API

#

Or well, you could make the new ItemMeta-like be able to turn a stick in to a sword but you couldn't make it turn it back in to just a stick or turn a sword in to a stick

#

For that you have to know what components are and have an API to remove a component

paper fern
#

Well you could still abstract "I want this item stack to behave like a sword" into a new API

#

People just need to understand that such an API will just do whatever it has to in regards to the component setup to achieve the API calls goal

agile obsidian
#

Or hey, maybe this is the job of a third party api. :P

paper fern
#

outsourcing core API to third party sounds like an owen thing

late quiver
#

Owen, turning Paper into Forge one PR at a time

agile obsidian
#

inventories, commands, screaming

paper fern
#

Like, data components are barely an "API" as is

#

I guess it is an API just, 0 guarantees for any compatibility

#

which makes it effectively useless for a good chunk of developers

agile obsidian
paper fern
#

Yea I mean "representing something that changes" is kinda the entire point of bukkit/spigot/paper

#

We don't need a spigot level of eternal backwards compat

#

but like, "best effort, two three versions" should still be something we strive for

#

e.g. set/getDestroyableKeys

#

its deprecated for removal and potentially data loosing impl now, but for most usecases it still works even tho the entire underlying system changed

agile obsidian
#

Like its possible to add some slight backwards compatibility if data representation within the component itself changes, it just gets tricky tho when you are now moving stuff into different components

#

(hence why we have builders here)

paper fern
#

Now, baking such "2/3 versions of backwards compat" directly into the components is IMO not a winning move

#

Yea for something like "component just changed a little" that works

#

but e.g. for a food component move like .2 will be pulling on us

late quiver
#

The hope is that Mojang will soon stop shuffling data around between components

agile obsidian
#

Yeah I mean even item meta will be kinda killed by that

paper fern
#

Well that type in IteMeta is experimental

agile obsidian
paper fern
#

and it doesn't really have to be killed anyway

#

ItemMeta can just apply two components

agile obsidian
#

True

late quiver
#

Items being data driven would be a registry thing, surely

#

Unless you mean making them data driven by just making a pile of components to register as the defaults

agile obsidian
#

well yes

#

But alot of the properties of items will most likely be controlled via components

#

(see music discs, etc)

paper fern
#

But yea, I think we need like, both systems to exist.
The true version specific data component API that is this, allowing you perfect fine grained control over the items internal makeup.
And a top level abstraction that does not allow you to control components whatsoever, but promises cross-version "make item do x"

agile obsidian
#

They are just moving alot of the logic out of Item and into components

paper fern
#

like, that method could just as well remove the component entirely if I set damage to 0. Most usecases don#t need an itemstack with a damage component of value 0, they just need something that doesn't have damage.

#

So yea, what amaranth said. ItemMeta but kinda all top level

royal kiln
#

isn't that "top-level abstraction" ItemMeta?

viscid burrow
#

Well, Items being data driven would just mean new registry stuff

paper fern
#

Well yea but ItemMeta is not going to be in a usuable state by the time we get there

wicked fog
paper fern
#

md will shit more stuff at it, we will shit more "reset" methods at it to allow component removal. Its gonna be the worst of both worlds by the time we get around to actually think about a top level API like that

royal kiln
#

I mean as long as it still works for the top level stuff, md_5 level shit might be okay

paper fern
#

getFoodComponent

viscid burrow
#

but, like, I don't expect much to change in terms of how stacks are defined to impact us, only real thing will be component defs changing

paper fern
#

getTool

agile obsidian
#

So meta is becoming a weird combo 😛

#

(They did it with music discs too right)

royal kiln
#

because ending up with three different ways of modifying items would be pretty stupid imo

paper fern
#

Well, yea ItemMeta will be that top level until we spoon it I guess

#

or we just pull shit up to ItemMeta and deprecate/remove the stuff that should not be there because it is too close to the internal concept of components (which is exposed via the DataComponent API) once soft utensils exist

agile obsidian
#

But I find it very likely that someone will just make some kind of library that will do it. And imo that's what I kinda prefer. Like inventories theres a billion different opinions of how things should work and people pick what they want. Commands, same thing.

I of course think we can make improvements to item meta tho to unlock some of this functionality in a more supported way, which yeah doesn't directly expose components.

paper fern
#

Well yea, there might be third party libs for items but also like, our project is useless if it does not have a stable API to do the bare minimum

royal kiln
#

I still really think the command stuff should be part of the API too

#

otherwise I might as well start making fabric mods

paper fern
#

I mean, Brig is the stable stuff for commands

#

so is BasicCommand

#

opinionated annotation parser magic is 100% third party stuff

royal kiln
#

yeah but BasicCommand is super limited and not really a great org.bukkit command replacement

paper fern
#

What is missing?

#

Beyond like, integration to HelpMap or whatever

royal kiln
#

nothing feature-wise directly. its just really just basic, while the org.bukkit command API can be pretty easily used to make more complicated command systems

paper fern
#

Both are just instances with execute and suggest?

#

Am I missing "making complicated command systems" features of bukkit commands?

#

beyond switching over arguments and calling other commands

#

but I guess that is besides the point of this channel 😅
In the end, commands have a stable API for commands, one verbose and powerful, one simple and limited

halcyon berry
# agile obsidian *Or hey, maybe this is the job of a third party api. :P*

I actually made an API for that
Any NBT and data component usage is completely made with Java objects

For example:```java
RtagItem tag = new RtagItem(item);

if (tag.hasComponent("minecraft:custom_model_data")) {
tag.removeComponent("minecraft:custom_model_data");
} else {
tag.setComponent("minecraft:custom_model_data", 40);
}

Object component = tag.getComponent("minecraft:custom_model_data");
Integer number = ComponentType.encodeJava("minecraft:custom_model_data", component).orElse(null);

paper fern
#

That is enough for what I think the API should offer in that regard, and I'd be on the same fence for item stacks.

#

A simple and limited API like non-shitty ItemMeta, and a verbose and more powerful but less stable API, in this case data components

royal kiln
#

yeah I am fine with the stability part, just dislike delegating somewhat important features to 3rd party libraries

paper fern
#

Yea me too

#

it is just a fine line to walk to keep the opinionated stuff to a minimum

agile obsidian
paper fern
#

Yea

#

just needs to be clearly communicated like that

#

Like, we should not be pushing that API as the main way to edit items for 99% of developers imo

agile obsidian
#

100% agree

past wagon
#

that's not really comparable

royal kiln
viscid burrow
#

I mean

#

paper will never have a built in economy implementation

#

he says

paper fern
#

slip me my slope

viscid burrow
#

eco is a individual server type thing, you could maybe make some arguments for service style interfaces to exist, but, there comes some level of reality over the current ecosystem

#

stuff like that would be much easier to push as a 3rd party library as then you're not bolted to 1.whatever-we-drop-it-in+

paper fern
#

io.papermc:community-api:1.0.0

versed torrent
trim copper
#

Wasn’t there a paper api?

#

Paperlib

paper fern
#

paperlib abstracts paper api additions over spigot

#

e.g. it falls back to a shitty way on spigot and a cool way on paper

toxic sun
wicked fog
paper fern
#

See, the issue with that is "good"

wicked fog
#

We can't get good stuff it seems 😔

paper fern
#

and also 927

viscid burrow
#

designing API is hard, but the biggest issue is all the other features people want along side that

wicked fog
#

See, Vault hadn't got an update and no one is dropping it. So it seems not that much of a problem

paper fern
#

I doubt anyone would call VaultAPI a good API these days

#

its just a very very popular standart

viscid burrow
#

people use vault because it exists and works, as much as that makes people sad

#

every single replacement pretty much aims to push their own eco plugin

versed torrent
#

this feels like a fever dream

agile obsidian
#

I would say that there’s a better channel for this but there simply isnt

viscid burrow
#

Owen

#

Complains about no discussion in the channel

#

Also Owen

#

Complains about discussion in the channel

#

runs

royal kiln
#

but yes pls merge datacomponent api soon, ty

versed torrent
#

it will certainly get more feedback as it's going to actually be used, yes

#

as opposed to now where you have to go out of your way to test it in code

wicked fog
royal kiln
#

Only thing that worries me a bit is that it seems pretty item-specific. By the looks of it Mojang wants to use the component system elsewhere too, and it would be unfortunate if we end up with several different "component" apis

#

idk how easily that could be abstracted later

paper fern
#

Yea I guess we could switch up the naming a bit

royal kiln
#

Well it also would be weird if there is BlockComponents, EntityComponents and "WeirdPaperItemThingy" kek

paper fern
royal kiln
#

TIL that exists

versed torrent
#

and then lynx fixed it

#

🙌

night solstice
#

seems mojang killed custommodeldata pepothink

rocky niche
rocky niche
night solstice
#

thank the lord

#

well CMD has no purpose now tho does it? like what would it otherwise be used for?

rocky niche
#

you can change item model and in that new model use it for something, like charge amount

night solstice
#

iguess

wicked fog
rocky niche
#

Basically now you can make any armor dyeable with a custom texture, but of course ItemMeta won't allow it, so we need this api

rocky niche
#

but basically this will now be used properly instead of how CMD was used in 95% of use cases

#

CMD is now just an addition to your own custom model (for example mana amount to a wizard staff so you could change something in it based on that)

toxic sun
#

Fortunately, the ItemMeta API is very flexible and quite close to the system adopted by Vanilla in this release.

paper fern
#

@Experimental getDyableComponent stonks

patent swallow
night solstice
#

item_model dictates that
CMD is just another value ontop of that so u can further tweak it iguess

late quiver
#

So you can use CMD and predicates or you can just change the item_model whenever you want a different look

#

I dunno, that feels like CMD is going away

rocky niche
#

for further customization of that custom model

versed torrent
#

predicata

wicked fog
#

:deadge:

#
+        register(DataComponents.CAN_PLACE_ON, PaperItemAdventurePredicate::new);
+        register(DataComponents.CAN_BREAK, PaperItemAdventurePredicate::new);
#

it can't be saved to SNBT :waah:

#

and also can't be used for recipes :waah:

#

and why is it an Item predicate if it's about blocks :waah:

#

and why doesn't it implement Predicate<ItemStack> :waah:

viscid burrow
#

Because they’re not useful being that raw

late quiver
#

Wait you want it to generate actual code?

#

Predicate<ItemStack> is like for a lambda

#

How would you serialize actual code?

wicked fog
toxic sun
#

moreso why can't you use it as a predicate, not to generate code

#

like to pass it directly into a filter method for example

viscid burrow
#

I mean, you could make that class extend Predicate

wicked fog
#

using (S)NBT you would also be able to (de)serialize it

viscid burrow
#

But, you couldn’t accept a Predicate as a thing

late quiver
#

Your SNBT library can solve the halting problem?

wicked fog
#

SNBT can solve everything, P=NP too

paper fern
late quiver
#

Or does it just pretty print the bytecode into a string?

wicked fog
#

why bytecode?

late quiver
#

Being an actual Predicate would not help with SNBT

paper fern
#

Yea idk, their predicate is just implemented by a shit ton of different concrete "predicates"

late quiver
#

An actual Predicate<ItemStack> would just be (itemstack) -> { /* do thing with itemstack */ }

#

How do you serialize that?

wicked fog
late quiver
#

Ok, one of us is definitely confused

#

You're trying to serialize components to SNBT, right? Having that thing implement Predicate<ItemStack> does nothing to help you do that

wicked fog
#

if ItemAdventurePredicate and BlockPredicate are predicates, they could extend Predicate

wicked fog
#

it was an entirely different point

viscid burrow
#

It’s a fairly raw system

#

I’d imagine the intent is to not try to make it promise too much for the future

wicked fog
#

why would it a promise for "too much"?

viscid burrow
#

I mean the concept of scattering it with shiny utility api all over the place

wicked fog
#

it's not "all over the place" but as a Predicate it should extends Predicate?

viscid burrow
#

I mean all over that new API

#

making it a predicate<X> implies that you can test X out of band