#Registries Overhaul
4774 messages · Page 5 of 5 (latest)
ObserveRegistryEvent?
The naming of events is conventionally based on when the event is firing
This one is.. more or less RegistryCreationEvent?
how does one even review a PR of this size
thats what I said
I can only really check the few things I'm personally familiar with
I went through every single file lol
Well, Fabric does currently still do the loot table part:
https://github.com/FabricMC/fabric/blob/1.20.2/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/trackers/vanilla/BlockInitTracker.java#L48
Probably that this was an issue back on 1.14 then, but not on recent versions?
this is the 1.14.4 code (thanks snowman)
does that RL really need to be cached
That issue is after the PR was created though.
hmmm not actually the object.getDropTableId(); call was already there before the PR!!!
meh this dates all the way back to the very first implementation of fabric registry hooks
whatever
we'll fix it if it causes an issue in the future
wrote a blog post: https://pr-14.neoforged-website-previews.pages.dev/news/20.2registry-rework/
In this post we go over the changes we made to the registries subsystem of NeoForge,
delivered a few weeks after the initial 20.2 NeoForge release.
FYI
yeah vanilla does this... I was looking at the neoforge project 
we should probably add this in an AddCallback


question... do callbacks work for datapack registries?
good question
the answer is no because the modify event is not even called for them??
the getLootTable call should be in the bake callback and not the add callback
why? does it change?
the vanilla behaviour is in the loop so we should also do it like that
there are multiple bakes but a single registration, so no
vanilla doesn't have callbacks so they probably do it like that because it's the most convenient
is that so? shouldn't we then move the initCache to the add callback
initCache should definitely not be in bake at the very least due to its performance
the add callback doesn't fire for vanilla entries, that's why I added the static block in Blocks back
(and it's also good to keep the static block for discoverability because everyone forgot about it... :P)
did that already
It's still a waste because vanilla rebuilds all the caches again when you join a server
But there is nothing we can do about that without integrating ModernFix patches, because it's how vanilla is designed
I checked and if you do Blocks.WATER.defaultBlockState().getFluidState() in a common setup handler you get an empty fluid state without that initShape call 😛
Correct
we could probably do it in parallel if we wanted to
right now the bottleneck is still block creation I think
Shape setup, I believe, yeah
you can't, things explode
I tried it in modernfix a long time ago
better to do it lazily
most unfortunate
maty do the rest of the registry stuff
so we can finish this
i'm busy
yes with the registry rework 
what is the rest?
the only open discussions are the prefix in patches and the modify registry thread I just opened
https://github.com/neoforged/NeoForge/pull/257#discussion_r1392785646 the solution is to fix and fire it
i probably just missed the part where shrimp fired it (since not sure if anyone noticed but most of this is just shrimp's stuff copied over to 1.20.2)
Why should we fire it on datapack registries 
Do we allow appending to those in code?
no, datapack only
bake for example can be useful for caching of values of dp regs. same as with any registry
you can probably do in that in one of the server lifecycle events
I don't think we should, what's the use case?
you would need a mix of listeners, and when dp regs can be reloaded it will break
yeah but you can already do that
I don't care about a hypothetical future 😛
You can already do this by computing on first access and then using a reload listener to invalidate your cache
I would like to use bake to validate the entries because I can't do that in the codec because it is dependent on itself
dpregs don't reload on /reload
they're finalized just before the server starts starting
it would be better to have a DataPackRegistriesUpdatedEvent or whatever IMO
why?
than support modifying datapack registries
ServerAboutToStartEvent already works for that
right
.... what is the point of them being datapack-driven then
add one of the client join events and you're good
I thought the whole magic was that they could be reloaded
they reload on server restart
mods could do this a decade ago
If anything, it has to be called in bake. Doing it in add would defeat the supplierization of dropsLike(Block)/lootFrom(Supplier<Block>)

Ah, true

anyway dpregs don't need registration callbacks because you can cache your derived data when the server starts or lazily evaluate them on first use
#1170668658813575230 message I digress :P
[Reference to](#1170668658813575230 message) #1170668658813575230 [➤ ](#1170668658813575230 message)it's not the worst thing, but it would be good to slowly start thinking about separating client-exclusive code properly instead of relying on lazy classloading
It's fine, the method has effectively zero performance impact on the second call
I know, it's just stupid
I'm not hypothetical either, I already cache dpreg stuff without registry callback events https://github.com/Commoble/exmachina_engine/blob/main/src/main/java/commoble/exmachina/engine/ExMachinaEngine.java#L82
It is really not!
what about my usecase?
but it is technically possible, is what I mean
hmmm?
you can do it ServerAboutToStartEvent
It requires us moving away from source patches....
Which is like never going to happen
that seems like the wrong place to do it
because if mojang makes dpregs reloadable we have a problem
please, let's worry about that when it happens
yeah I literally use server start events to validate the big ol' glob of data I derive from my dpreg stuff
I'd like to do it in the codec itself but A) I can't and B) a registry callback wouldn't help that anyway
and if mojang did make dpregs reloadable I'd just validate-and-cache my data in the /reload event instead 
a reg callback would help?
how would a reg callback not help with validation of big ol' globs of data you derive from your dpreg stuff 
I mean it wouldn't help me with doing validation inside the codecs
as for other things it could potentially help me with, I'm not currently able to conceive of anything it would let me do that I'm not already doing
Are people debating not firing the registry event to attach listeners and whatnot for datapacks dpregs? IMO datapack regs and normal regs should be treated the same in every respect, except for letting people register to them (that is, firing register events). The events to attach callbacks should still fire for them. Otherwise it's an arbitrary restriction - you can't know everyone's use case, so unless there's a very good reason to limit it (not just "someone could misuse this"; that's true of everything) you shouldn't place arbitrary limitations on the API
Arbitrary restrictions on an API aren't cool
(unless there's a large maintenance burden or such accompanying them of course, or it's a substantially high ease of causing bad states that are difficult to diagnose without it)
it needs a number of new injection points yes, frankly I don't feel like researching that and I doubt it was already working before
we are already at version 20.2.96-beta-reg-rework 
@stuck lava do we want to target this weekend for the reg rework?
(to give more time for review)
I'd say Saturday as a target
to whoever does the final merge: don't forget to keep the co-authors
whoops
that's my bad for the 1.20.2 port 🙃
<@&1128776937410670663> the registry rework is targeted for this weekend, please try to review it beforehand
@stuck lava check the blog post draft: https://pr-14.neoforged-website-previews.pages.dev/news/20.2registry-rework/
I'd add a registerBlockItem example in the section for the specialised DRs
I think the Custom registries section is outdated
Minor thing, but some of the tests have changed from using .get() to .value() (with the change to DeferredHolders) any reason for that? (ForgeSpawnEggItemTest for example)
@stuck lava we have problems
probably because they were changed to Holder first and then back to DeferredHolder?
hmm, can we get a HolderLike instead of Supplier. and said HolderLike would have value<T>
that way we can solve all of the ambiguïtés
ah yes, french autocorrect
Oh wait I'm dumb, it's the references to the Attributes in NeoForgeMod which are Holders
ah alright
it doesn't solve anything, the problem we have is that DeferredHolder<R, T> is only Holder<R> but we want a Supplier<T>
so we thought it best to move implements Supplier<T> to DeferredHolder instead of Holder
maybe moving the supplier back to DeferredHolder is the cleanest
should we make an announcement about the "RFC period" until sunday
Likely a good idea to do so
I'd say people should use ::get if they want a supplier of the specific type, or heck, a supplier at all, and call it a day, but that's just my opinion
Holder implementing Supplier is convenient for all the methods that would otherwise need two overloads
and yeah I think ::get is fine
I think the less ::get we need the better
I agree it's not great
someone should update https://github.com/neoforged/NeoForge/issues/37 on the state of things too, as a general overview of what the rework entails
the general overview is the WIP blogpost
assigns you to the issue
do I delete this? it's not used anymore
who originally added it
for the supplier stuff please don't move it back to Holder because all of the suppliers (neo)forge adds require a more specific type and not a Supplier<BaseType> this is most annoying for entity types in spawneggs
you can still do ::get
or in this case I suppose we can just remove the Holder methods
but it's annoying, it means that if you have a normal holder you can't use it in supplier methods anymore
Why do we need a whole pair of deferredregister subclasses for blocks and items?
you can defreg a block+blockitem with a few lines in one static method helper
the answer is 1) to guarantee that custom DR and DH subclasses are possible 2) it adds like 5% of convenience and 3) why not
I wasn't also particularly enthusiastic but it doesn't hurt /shrug
like I use this and it does the same thing in so much less code ```java
private static <BLOCK extends Block, ITEM extends BlockItem> RegistryObject<BLOCK> registerBlockItem(
DeferredRegister<Block> blocks,
DeferredRegister<Item> items,
String name,
Supplier<? extends BLOCK> blockFactory,
Function<? super BLOCK, ? extends ITEM> itemFactory)
{
RegistryObject<BLOCK> block = blocks.register(name, blockFactory);
items.register(name, () -> itemFactory.apply(block.get()));
return block;
}
private static <BLOCK extends Block> RegistryObject<BLOCK> registerBlockItem(
DeferredRegister<Block> blocks,
DeferredRegister<Item> items,
String name,
Supplier<? extends BLOCK> blockFactory)
{
return registerBlockItem(blocks, items, name, blockFactory, block -> new BlockItem(block, new Item.Properties()));
}
tbh I'm not too big of a fan of it either
tbh I don't think ITEMS.registerBlockItem("name", FANCY_BLOCK::get) is that bad
i hate this all value and get tbh, but meh
wdym?
there's holder with value()R and DH with get()T from supplier
supplier is our "patch"
value()R will stay whatever we do (but we can override it to return T)
you want value()T?
yes i think we should get rid of supplier and have a custom FI with just value()T, and we can replace all of our patches of Supplier to that custom FI
and that way we don't need to ::get or ::value
should we replace all of the suppliers with a custom ValueProvider that has a value() method so everything uses it?
get hecked
is Holder gonna implement ValueProvider?
if yes then we're back to the same problem
I don't think it's important for holder to implement supplier
This is meant to be a hook for mods to be able to do filesystem changes (like backups) if the mod version changes
can we not change some of our patches to use Holder instead of Supplier?
If there's something that can provide that super early in the world loading process, this can be scrapped, but if not..
we are not tracking mod versions in the world file anymore at the moment (in the rework) because no registry needs to be persisted anymore
Because I use it when I do SavedData changes - there's no other way to prep those files
can't you add a version field at the beginning of your SavedData file?
Problem ran deeper than that - I had to sync multiple files in unison
So I had to rewrite portions without MC's systems
interesting. so the warning about "mod version changed" will be gone?
I suppose so, yes
I think removing any notification on mod version changes is gonna annoy people. A lot.
I think the rework removes the subsystem Forge used for storing that data entirely
"why'd my shit break? I only went from version 3 to 298?1?! One"
MME gives people an event to at least do their own logging and prep work
is the important part the timing of the event, because we could add back an event that fires at a similar time, but require people to track their data versions themselves
If you MUST get rid of it, please add a hook early in the world load process that has context, yes
that patch would be significantly less complex than having to actually store anything
I can take it from there, but otherwise there's no way in without mixins
People will have to store their own versions, but that's not necessarily a bad thing
in theory the code to store mod versions shouldn't be too bad?
mostly just putting back these functions and only doing the mod version part, not the registries
apparently the link doesn't function
great
the additional saved data methods in CommonHooks
it only functions if GH chooses to open the file you linked to

you're right, damn it
why are we patching things into Holder actually
wait
I thought Holder already had a concept of deferral
it's not a supplier unfortunately
hmm no nvm
is that a problem
can we not do any magic to get the compiler not to complain and to inject a bridge
let's not
don't think so
can't we just let people do ::value if they want a supplier from a holder? and call it a day?
honestly i wouldn't even recommend storing Holder<T> even when it would be DH<T, T>
you're downcasting DH extends Supplier into Holder and then from that creating another supplier
yea we'll just remove the holder methods from the special dr
yeah I don't think storing a Holder makes sense if it doesn't even implement Supplier anymore
and y'all made me make all DH<T, T> into Holder<T> in neoforgemod 
i want to be reimbursed for that wasted time

And me in the testmods
I'll send you my paypal maty
No, it doesn't, the vanilla holder impls must be provided by the registry and are only provided once the object is registered
that's not necessarily true getOrCreateHolderOrThrow is a thing
vanilla holders can exist before the object exists (standalone reference holders are created with an id and have the value bound later), however they cannot exist before the registry exists
DeferredHolder exists to solve the latter, because of custom registries
well actually no, custom registries are created immediately
it exists because
- all holders must be bound, so you can't have them "optional"
- vanilla is annoying and you basically can't have
Holder<MyBlock>hence the double generics of DH
So if you use a regular holder you cannot have a type extending your registry type?
Then you would need defferedHolder?
yes
you probably don't need to use holder
@keen thicket should I update the blog post to remove the Holder example?
(so the choice will be between DeferredHolder and Supplier)
Why would I use the deferredHolder over the supplier then?
I guess if you want the key but I don’t see why that would be needed since you are accessing it already then
because of these methods
if you need them you can have them, otherwise just Supplier is fine
Oh fair
Wait holder is not a supplier like registryobject is?
That’s a bit annoying
Would it be possible even to convert a holder to a supplier?
Holder::value is a supplier 
yes
That works if you have a Supplier as parameter?
but yeah holder is essentially a mojang-flavored registryobject
it should because supplier is a functional interface
Holder::value is a Supplier<BASE>
Oh I never knew that it worked like that
Thought it wanted the Supplier class specifically
supplier is a functional interface
Any method that follows the supplier principle works?
Well I know but I thought you needed specifically that implementation
Makes sense tho
Cuz you can also use lambdas
And that’s also not explicit
any method that matches supplier#get's method signature can be made into a method reference impl of supplier
Ye
Ive been using that for like ever now that I think about it XD
Just a little brainfart
🤣
It’s a bit weird that they are optional tho
Custom registries are created immediately but holders may be made before them, by other mods
Holder is still worthwhile if you don't care about the specific type, so I'd keep it
it's not really no, DH extends Holder and more than that you can't use a holder directly in forge patches of ctors anyways
those forge patches or ctors should be fixed. But fair I guess? I don't keep track of the types of stuff I register so the ability to just yeet that type entirely is useful
Though ::value exists so no big deal
fixed as in how
a lot of stuff wants suppliers of specific types, like fluidblock, or entitytype<T>
and holders can't do that so there's no way the patches can be changed to a holder
Simple™️
just patch everything that uses holder 
ah right, that's not an issue for vanilla as it doesn't use holders there but just the block or entity type directly. I was thinking more anywhere expecting a Supplier<? extends Item>` or similar
But that's a good point. I'd still say there's plenty of reason to use just plain old Holder, so I wouldn't remove that example from the blog post
I just wish I could convince someone at mojang to switch all the holder refs to <? extends T>
It's not how holders are meant to work from what I can tell. The idea is that if you have a holder, all you know is that it contains a member of the registry type - like, think in terms of making stuff (maybe eventually blocks) reloadable - holders could theoretically have the specific type they contain replaced without issue, because you can't depend on that specific type as all you have is the generic
Ultimately you will need to have some guarantee that some particular object is known to be of a specific type, which is currently accomplished by vanilla's static fields - sure the holder generic doesn't guarantee that the type is of type T (rather than R), but this isn't an issue in practice (nor has it been since the introduction of RO)
Its a classic type safety vs usability argument
Eh, that's actually not needed that much in vanilla. There's a few places where it does but generally speaking they've done a pretty good job of yeeting dependence on the specific type
Another thing here is that typically the only instance of a strongly-typed holder should be on instantiation, so the instantiator should know the type
It just pops up far more in modded
Vanilla also has the luxury of adding new methods to Block to erase type-specific dependencies
Yep, definitely. I agree that it's definitely useful for modding (though still possible to avoid in many cases), I just unfortunately doubt vanilla will be switching stuff around to allow that as they've put a good bit of work into not needing that
Does the registry add callback also fire for vanilla entries?
Then we need to add back the loot table resolution in the static block in Blocks, it currently gets patched out
How's that supposed to work? The event would fire for vanilla registries long before mods start loading
new task: move mod construction to before vanilla bootstrap
(that wouldn't break anything, right? right?)
Sure, let's break reality for a while
the funny thing is, if mod construction and initialization happened before vanilla has even been added to the jvm, it would mean people physically cannot use static fields to register stuff and DR/Events would be required :P
go make a PoC
I don't have the time, energy, or patience XD
Is it still patched out? I thought I restored it
No we're not gonna do that for performance reasons
Quilt sorta does this by shoving it basically into a partially bootstrapped but unbaked state, and it works well enough. But it's not truly before bootstrap either. If you were before bootstrap you'd have to be very careful that mods didn't, like, classload the wrong thing and have everything crash and burn
to be perfectly clear: it was a joke.
Quilt doesn't have parallel mod loading though
On second thought, I may be wrong and just misreading the patch
Did you add all the comments tonight?
Yes, the four comments are from 2 hours ago
Or were you looking at the code some time ago?
Yeah, wherever you decided to move the mod ctor injection point, you'd still need DR if you wanted parallel mod loading
maty your description says it isn't going to make the DH change but like it is doing even more than the other one did in that regard by moving over rather than just deprecating
well I will get back to trying to test this later... for some reason when building against it with it in mavenlocal... NG7 doesn't seem to be attaching the mc dep to my project?
uhh what is the way to get the tags from a registry object now that the tag manager and reverse tag system are gone?
or is there no longer a good mostly cached way
Holder#tags(), which the IReverseTag implementation directly referred to anyway
ahh so need to get a holder, okay. Feels a bit odd to look up the holder for the object itself but thats fine
The tag manager did nothing else
@heavy zephyr fix it
well that's enough for tonight... have a local branch of mek that compiles against the rework but crashes when running due to NeoForgeRegistryCallbacks$BlockCallbacks.onAdd but too tired to look into why
gibim log
so, what do we do about the conflict between Holder and Supplier?
Holder contains the ID, which is nicer for e.g. registerBlockItem
IMO: we should use Supplier unless we have a reason to prefer Holder, what do you think?
so we'd have registerBlockItem(String, Supplier) or registerBlockItem(Holder)
(but NO registerBlockItem(String, Holder))
@stuck lava these overloads will only give us problems
This makes sense - if you're storing a reference somewhere always use holder though, I'd say
But yeah that makes a lot of sense
Holder doesn't have the specific type
regex fun!
let's see how many generic conflicts this will cause...
Yeah, so if the specific type is needed, or no reference is stored, use supplier. Otherwise, if a reference is stored, or an ID is needed, use holder - maybe with an overload taking a supplier and RL if it makes sense
registerBlockItem is so convenient for the forge testmods... 😄
oh ffs Holder doesn't know its own ID, only DH knows it
actually no, unwrapKey().get() will work
public DeferredItem<BlockItem> registerBlockItem(Holder<Block> block, Item.Properties properties) {
return this.registerBlockItem(block.unwrapKey().get().location().getPath(), block::value, properties);
}
not great, not terrible
DeferredItem 
missing two overloads for registerBlock
for a second, I read "that implements ItemLike" as referring to "Items", rather than "Special DeferredHolder"
actually it does not contain the id because it is not a Holder.Reference necessarily
remove the supplier overloads if there is no specific reason to have them (always prefer Holder)
we should prefer Supplier, IMO
why?
cause it's a more general construct
a Holder<T> is basically a Supplier<T> (without the specific type) + more info
idk, we should decide what modders are supposed to use
in the case of creative tab we should remove the supplier ones
already did
I removed the Supplier<? extends ItemLike> overloads
the ItemLike overloads are still there
yea the ItemLike ones are vanilla so that is correct
for registerBlockItem I suggest keeping these only:
if you have (String, Holder) you can easily use ::value to get a supplier, but if you have a Supplier you cannot easily call a holder method
another inconsistency is that there are 4 registerItem overloads:
but only 2 registerBlock overloads:
should we add the other two overloads?
here's a thought: why does vanilla not implement Supplier onto Holder
no idea, Forge used to patch that in, but we removed it in the rework in favor of having DeferredHolder<R, T> implement Supplier<T> (Holder would have been Supplier<R>)
registerBlock(String) doesn't really make sense without properties
modders shouldn't construct blocks without any property configured
do default properties for blocks make sense?
I think blocks and items should always have their properties passed along, and never constructed in NF code on the modder's behalf
imo default new Item.Properties() makes sense, especially for block items
you rarely actually have to configure item properties
does vanilla provide an Item constructor that doesn't have a Properties parameter?
we are not vanilla 😛
every single BlockItem in the testmods had no properties
(probably at least 20 call sites)
we may not be vanilla, but that doesn't mean we should necessarily be different from vanilla in every aspect
yeah I agree, that is a lot rarer than needing to construct items with no properties
blocks usually have a sound group or map color or something else even if they don't have any behavior
strength is basically required
yeah that too
I do see that vanilla-Items has a helper for registering blocks that's just the blank Item.Properties, so I'm revising my opinion to allow that no-properties item factory
(which btw I would think is a more constructive reason than just the basis of "not being vanilla")
sure - there's multiple ways one can be convinced 😛
i believe "we're not vanilla" is particularly weak without supporting or derived reasons
by itself, it's just a facsimile of NIH syndome -- denying outside (in this case, vanilla) ideas in favor of orur own
and the NF test mods are hardly representative of the common MC mod
I used that argument against the "we shouldn't do this because vanilla doesn't do this" argument
I was thinking more along the lines of "making the caller always aware of the properties of their item, in the same fashion that Items (and subclases) always require their properties being supplied"
In places I have overloads that take a UnaryOperator parameter
I would prefer using Holder#unwrapKey().orElseThrow() with a sensible exception message mentioning that unbound reference holders and direct holders cannot be used. Having it run into a non-descript NoSuchElementException("No value present") is awful for debugging
I would assume the reason why Item and its subclasses always require an Item.Properties instance is is so the properties of any item is clearly visible at the item's creation point, rather than hidden inside the constructors of Item subclasses
you'd still get a stacktrace pointing to the registerBlockItem call
which I then wanted to apply here, so modders calling registerItem know exactly (by virtue of needing to pass in the Item.Properties) what their item's properties are
I'll change it after I restore the mismatch event
actually, this brings up a thought:
the above cited cases were for block items, which usually don't need to have specific item counts or other such info, which is a common enough usecase (as Item#registerBlock demonstrates)
but does that same logic apply for raw, basic Item instances? (no properties, no subclass -- just an new Item(new Item.Properties()))
I will later, but tldr was me checking if an item was held in my getShape return (because of the block callbacks initializing the cache instantly and that being before items are registered). Though I think I fixed it by checking if it is a level and then only doing that client side (but need to evaluate it further to see if that is valid for my use case and also see if I should be overriding a different getShape
Though I did get errors in datagen about not being able to datagenerate for one of my custom datagen registries so I will need to look into that still
i revise my opinion: yes for a block item factory which doesn't take in a Properties, nay for an item factory that doesn't take in a Properties
yes for basic crafting items
I mean this might be a problem with the rework
I can fix it quite easily
initializing the cache immediately is too earlu
I have this, so I can either register a basic blockitem or a special bunny blockitem ```java
private static <BLOCK extends Block, ITEM extends BlockItem> RegistryObject<BLOCK> registerBlockItem(
DeferredRegister<Block> blocks,
DeferredRegister<Item> items,
String name,
Supplier<? extends BLOCK> blockFactory,
Function<? super BLOCK, ? extends ITEM> itemFactory)
{
RegistryObject<BLOCK> block = blocks.register(name, blockFactory);
items.register(name, () -> itemFactory.apply(block.get()));
return block;
}
private static <BLOCK extends Block> RegistryObject<BLOCK> registerBlockItem(
DeferredRegister<Block> blocks,
DeferredRegister<Item> items,
String name,
Supplier<? extends BLOCK> blockFactory)
{
return registerBlockItem(blocks, items, name, blockFactory, block -> new BlockItem(block, new Item.Properties()));
}
are those common enough to merit having their own dedicated method?
I would personally think not, as the vast majority of items added by mods (in my opinion) add features to items that involve modifying its properties
(and in the minority of cases which are e.g. chock full of crafting items, chances are they've already made some sort of abstraction over their registration to ease having so many uniform items)
IMO norge shouldn't have the helpers for registering blockitems
I have 10 of them
I'd call everything > 5 common enough
they're trivial to mods to write themselves and having them in norge itself foments bikeshed
bigger thing is I don't think they have to be in neo for the initial registry rework release
consider that we already have them written and used everywhere by the test mods
it's only bikeshed if we let it be bikeshed
ah
Tech, you still missed something in the ModifyRegistryEvent docs 😄
It still mentions the DP reg event: https://github.com/neoforged/NeoForge/pull/257/files#diff-8fe9842091c045e7e1d0182809f68ca0fd5154724038d8096803c59912ead4d5R33
Is it intentional that the callback link doesn't have a "link text" to be displayed instead of the code reference itself: https://github.com/neoforged/NeoForge/pull/257/files#diff-8fe9842091c045e7e1d0182809f68ca0fd5154724038d8096803c59912ead4d5R24?

alright the mismatch hooks seem to work
WTF
local diff after running unpackSourcePatches 
Think that's expected? We talked about it earlier
That's my fault. I was reasonably sure that I had rebased the blending PR onto latest properly, but looks like I didn't: https://github.com/neoforged/NeoForge/pull/241/files
I can make a quick PR if you want to make a release for merely two patch headers. Though, I would prefer just including that in the larger patch cleanup PR I want to do later
yeah making a release for two patch headers feels overkill
assuming it doesn't actually cause issues or bugs at runtime
as long as it's fixed in a reasonably related PR ¯_(ツ)_/¯
it just wastes the time of contributors every time they run unpackSourcePatches
turns out I already did this locally 😄
this is what I suggest for loot table and shape computation
Looks reasonable to me
Though, I would describe it as "Init cache" instead of "Init shape" to avoid confusion because at the surface level it's not shape init, the actual shape init happens earlier when the block is constructed
yeah
question: why are the registries only frozen after common setup?
that sounds pretty stupid, they should be frozen right after the registry events
Unfreeze and refreeze currently have dedicated ModLoadingStates and the freeze happens after ModStateProvider.COMPLETE, which means that the freeze happens after FMLLoadCompleteEvent. Breakpoints confirm this
Hmm, that's a tricky question. Doing it after common/sided setup allows computing additional stuff in said setup events which may be needed for the cache init. On the other hand, doing it earlier would make other computations in common/sided setup faster if those use stuff accelerated by the cache
hmmm, as long as the cache is not initialized blocks with a fluid state will for example return EMPTY for their fluid state
so we should probably initialize it early
(cause a variety of other things might depend on it)
Yeah, that's true
can we document why it needs to be done this way instead of in onAdd
done
well with this (plus me figuring out I accidentally removed the register deferred register for one of my registries) it seems like things are working. Was able to get into game with mek at least
To mirror ItemStack we may want to add an overload FluidStack constructor that accepts a Holder<Fluid>
especially with the push the overhaul is making towards using Holders for things
that would be better in a fluid themed PR (the current fluid system is not bug free yet)
Yeah but that's gonna take some time 😛
Need to get caps well established before that can happen
maybe, though this PR given how holder based isn't that far from being the wrong place for that addition. Hence why I was mentioning it
Yeah we could throw it in if it's just a few lines
all that the itemstack version does
may want an Objects.requireNonNull around it
but basically would just be one (maybe two if also doing the nbt accepting one) overload constructors to just call value on the holder and pass to what already exists
why were the Tags.init methods removed? Is it that they aren't really forced to be loaded early anymore or what?
Tags are all loaded at the same time
I remember there was a time where some tags where loaded earlier than others, in vanilla
but that's not a thing anymore
well this is about tagkeys
previously I think they were so that then they were validated as present?
in case nothing accesses the class before tags actually load
tagkeys don't do any validation of tags on construction
they're literally just three resourcelocations stapled together, and they're intended to be existable before tags do
My guess is that the deterministic early init of the tag keys may have been needed for the default entry stuff (i.e. "optional" tags)
ah right tag key creation isn't where the adding tag key to registry happens anymore
and nah it is that the declaration for tags a few tag impls ago used to basically mark it as a default/required tag (I think by interacting with the registry in some way. Sort of as if you called Registry#getOrCreateTag on them now)
Not needed anymore
Used to be an issue. Long gone
Thank god
nice
do we want to allow mods to create intrusive holders for their custom registries? (if so it would require a way to pass the extra parameter to mapped registry)
also uhh when trying to connect to a server with the client: https://gist.github.com/pupnewfster/fb850a424482e2f2956d14dc7b7db0b4.
Server dc'd the client (well really froze it on connect until I killed the process) after it ran into that on connection and also logged
[17:54:05] [Server thread/WARN] [minecraft/Connection]: handleDisconnection() called twice
Not trying right now in neodev without mods so there is a tiny chance something I did in mek broke it... but given we don't touch villagers and which registry is erroring out, I somehow doubt it?
Probably not, intrusive holders are a design error
that will probably be fixed by #1170668658813575230 if it is a neo issue
We need to keep forge-forge connections working
@hoary umbra @lofty citrus @cerulean oxide @past saffron @winged iris @heavy zephyr @stuck lava @keen thicket
It's time for final review, all previous reviews are resolved, please do change request if there are any issues or a comment with
if it looks good
(you are pinged because you left a review or committed to the branch)
We still need to fix client-server connections apparently
if that is a us issue and not a mek issue
did anybody do any testing?
if you and maty didn't then nobody did
(forgedev tests)
nvm I'm stupid I need to disable online mode 😄
Caused by: java.lang.IllegalStateException: Duplicate id 1 for ResourceKey[minecraft:villager_profession / minecraft:armorer] and minecraft:none
wtf
I think we used to have some special magic code for assigning id 0
perhaps it is missing
lol the client has been "connecting to the server" for 5 minutes
why this doesn't use a CF, I don't understand
I think this is going to be replaced anyway so if this is the issue just do a bandaid fix
yeah you're right let's go for something that just works™️
because it probably was written before enqueueWork returned a CF
yeah I suppose
CF is important to not deadlock the client
ok the problem comes from non-defaulted registries I think
hmmm no it is defaulted
🤔
I think it's not happy because it doesn't receive the values in numerical id order
I know this is a fix by the registry rework PR, but how in the heck did this happen previously
I fixed the the deadlock
I already fixed it locally...
this is just a fuzzy patcher issue I think
ah, I see -- it was moved down from an ealier call accidentally
ye
yeah, sounds like the fuzzy patcher being stabbies
(in FlowerPotBlock.java.patch)
to review comment or not to review comment 
wtf is this
i'm not quite sure what "this" is referring to, there
() -> Blocks.AIR
it's consistent with vanilla, at least
I think
anyway, I'm not trying to think too much about the many patches
A supplier shouldn't be needed there, right? As reg replacement is 🦀
the registry rework solves https://github.com/neoforged/NeoForge/issues/60, right? "ForgeRegistry.add slows down with more entries"
yes
the flower pot block maintains a fullPots map of resource locations to block suppliers
best to leave that sort of cleanup after the registry rework
as to not balloon the already-large size of the PR
fwiw the purpose of suppliers in forge code is not primarily for reg replacement, but rather to support delayed registration
it lets you inject the RegObj before it has initialized
yea but IMO we should now use Holder for that if it does not need a specific type
for some things we can not use holders because the suppliers use the specific types
i feel like that Refresh button after a commit is pushed is gonna be the bane of my reviewing experience 
slowly chewing my way through the PR
We should prefer Suppliers IMO unless we need holder methods
why must (review) conversations be marked resolved without an answer to the question the conversation started with 
review sent
OK snapshot application is fixed
@lofty citrus that's gonna be a nope for {@return} with nested tags if intellij can't handle it

i usually write javadocs on the principle that the output in javadoc should be definitive, and that deviations of IDEs from that output are the cause of bugs or unimplemented behaviors in IDEs
yes but that's not how modders are gonna interact with it
I prefer to think of modders browsing the code via intellij
on top of that, I really don't want to bulk update all the javadoc in the PR...
I did remove the <br> usage however cause that is quite gross
ah well, we can update the inline returns in the future, when IDEA cleans up its act
but thank you for yeeting those <br>s
I think it's waste of time to bulk update javadoc to add {@return 😛
I really don't see the value of the inline return tags
they exist to remove duplication between a getter's body of Returns ... and the @return ... block tag
the body is important because the first sentence is used as the summary of the method in e.g. javadoc's method listings on the class page
tech why did you change the handleRegistryLoading again... join is the wrong method to preserve behaviour you should use get
I applied my patch to reduce the diff and log messages in the right order
what's the problem with join?
it hanles it differently
it just changes the type of the thrown exception
get throws a checked ExecutionException whereas join throws a CompletionException
I also tweaked the logic a bit so it would properly report the internal error (instead of failing due to an NPE in subsequent code and reporting that to the user)
yes which clears the interruption
what is causing these interruptions in the first place?
it is a safeguard if anything kills the worker thread that it does not kill the network thread

if we are on the network thread this will be sent to execute on the client main thread
I don't see what could go wrong with interrupts there? if someone interrupts the client main thread it's probably gonna stop anyway, and if the client thread is interrupted I don't see how this propagates to the network thread?
OK then maybe we should not have a @return block? what do you think?
another question: what does "builtin" registry refer to? only the vanilla ones in BuiltInRegistries? or does it also include modded non-datapack registries?
good question
@keen thicket care to elaborate 
or would it be Shadows
or Shrimp!
I mean we choose the wording at the end of the day
my question is: what should it be?
for me builtin is all non dp
that is also what I would use
we could perhaps go the route of a "static registry" term, in reference to registries which are defined on startup of the game (in current terms, non-datapackable registries)
static/dynamic is the fabric terminology, yes
though built-in being the opposite of datapackable is what I would first think of, yes
but vanilla uses "builtin" now so we should maybe follow suit
I mean that's 3 people in favor of builtin
sounds like consensus to me -- shipit
their javadoc tree needs updates in order to support that. I made a pr for fixing the inline return tag itself, but I did leave a note saying that nested tags are broken
does JetBrains have a tracking issue for that? (nested tags being broken)
yes
what's the point of firing the ModifyRegistryEvent once per registry? we could fire it once to modify all registries
these == checks are pointless
should we go all the way and rename NewRegistryEvent -> NewBuiltInRegistryEvent, and also make the modify event be named ModifyBuiltInRegistriesEvent
maybe not
So not a mek issue
indeed
yay or nay to the holder fluidstack constructor overloads I mentioned yesterday? Seemed somewhat split on opinions of if it was close enough to this PR
why not imo
that was my thinking given it is just a few lines and is related via holders
@winged iris gonna add
Looks good to me
OK, we're back to no outstanding comments (except for my own question about isPresent)
I'd say nuke isPresent(). AFAICT it serves the exact same purpose as isBound() and is just a leftover from RO
Unless of course there's a difference between being able to retrieve a holder from a registry (which isPresent() checks for, basically) and that holder actually being bound
There should not be a semantic difference between what isPresent and isBound mean
for the N-th time this week: all requested changes were applied 😄
i shall re-poke soon™️
I mean, do it today if you want to 😛
preferably don't so that we can merge it tomorrow /s
by "soon", I mean "likely later, once I've actually eaten"
I'll fix it tomorrow
I'm fixing it now since we want to merge tomorrow
is anything still open?
if not and no more change requests are coming in until <t:1700413200:f> I will approve the PR for merge
I'm currently working on getting my FramedBlocks environment to compile and run against the registry rework and if that works fine, then it's
from my side
I had to because you didn't 
if anything, it shall be me and pup who will approve and merge 
I mean anyone that made a change request has to approve before it can be merged which are you, me and xfact
I know but it bad 
if xfact and you approve and nobody requests changes until the time i sent I will merge it (because 2 approves means self merge is allowed)
also, 
19th 6 pm you mean? Kekw
yes CEST FTW
imagine being in UTC+1
couldn't be me
Works fine in my testing, including custom registries, on both SP and dedicated server. ID sync for the custom registry also worked on the dedicated server (server and client had different registration order for testing). That's a
from me
My minor testing in single player with mek also seemed to work (haven’t gotten around to testing server side since client server connections have been fixed, though also not sure if I will get around to it)
sci are you still planning on doing another review or does a 2nd review by any non committer suffice
sci is probably asleep at the moment. He still has an open change request btw: https://github.com/neoforged/NeoForge/pull/257#discussion_r1398230553
ok then that is the last thing that needs to be done (but I don't even know what to put into the comment so probably not me)
yes, was asleep
i shall do a second pass later, for changes since last review and the test mods
Once this gets merged I should make a PR fixing Mojang registries to not have an O(n) register method
@keen thicket EXPLAIN 
Well I think that issue is resolved by virtue of it not existing
if the vanilla registries exhibit the same problem, that may not be fixed
Forge & vanilla both have the problem for different reasons
So #60 will indeed be closed, but the performance issue will still exist
Ah we'll fix it after the rework then
<@&1128776937410670663> you have around 4 hours for the final review pass of the regs pr
don't rush me 
when it's merged (with co-authors), don't forget to also publish the registry rework blog post, with an accompanying announcement in #announcements
perhaps even an announcement in GH Discussions
anyone has a link? the actual PR isn't pinned
This PR is targeted for Sunday, November 19th, assuming no critical issues are brought up
Draft Blog Post: https://pr-14.neoforged-website-previews.pages.dev/news/20.2registry-rework/
Notable Chang...
found it in conversations
I'll be there around 6:10 to publish the blog post
oof 208 files changed :P
I don't think I'll be able to contribute a whole review
my focus window is too smol for that
what's the state of https://github.com/neoforged/NeoForge/pull/35?
not ported... stale
close (the PR)?
superceded?
sounds good to me, then
could be merged into 1.20.1 if we make a branch for it?
@past saffron @lofty citrus please do a last approval
ya ha ha
~1 hour and 30 mins left 
2h22m
<t:1700413200:R> ?
yes
i prefer "in stab hours"
@keen thicket it's UTC+1 not +2 for the blog post
@stuck lava can you add yourself as an author on the blog post?
You'll have to supply some metadata (avatar, description)
if someone can tell me what exactly and which format
Just add yourself at https://github.com/neoforged/websites/tree/main/data/authors and in the frontmatter of the blog post
I have no idea what format those yaml files have are there any docs?
is this panik time?
No
Just look at what's already there
We don’t get to panik until after hitting merge
50minutes
T-48
@lofty citrus you approved but there is still an unresolved conversation
if sci doesn't answer I'll resolve and merge
T-19
yep I'm ready
should I use the default commit message or remove the commit titles from the contained commits
MATY ^
@keen thicket
T-12
<t:1700413200:R>
link the post in the commit message
let me update the post real quick
Registry Rework or something
<@&1168623741715107890> Can we merge this?
let schurli do it
Yeah sure
the title but in the body to link the blog post
wrong role also 
Summary of the NeoForge 20.2.X registry system changes.
it's being built
wtf you didn't even remove the .X
WTF
let me take care of the post, just hit merge on github alreaady 😛
i changed it in one place 
There's a role for moderator+maintainers so the role icon is preserved between both :p
didn't notice the summary
good thing I had a TODO everywhere 😛
this ok
yes
Merged
New bug report! Registries deadlocks the game in prod
🎉
Any bets on how long till the first "this neoforged update broke all my stuff" confusion?
Now I just need to decide if I should port my mods to 1.20.2 neforge or wait for caps work
well, i can do my cap-less mods
Looking forwards to updating some of my stuff now that this exists. Probably going to wait on networking though on second thought
ng already broke all my stuff 
oh lawd it's live
I should probably write a trick for that
Oh lawd it comin #builds message
why is the author neoforged team 
does the theme not like multiple authors?
apparently not
As of NeoForge 20.2.59, the **registry rework **has been implemented, which is a breaking change affecting many mods.
If you are a player whose mods suddenly broke, we ask you to wait for the modders to adjust to the new system.
If you are a modder, please refer to the blog post on the NeoForge website for more information.
this exists for as soon as people come and complain that their mods broke

IT HERE





!registryrework
As of NeoForge 20.2.59, the **registry rework **has been implemented, which is a breaking change affecting many mods.
If you are a player whose mods suddenly broke, we ask you to wait for the modders to adjust to the new system.
If you are a modder, please refer to the blog post on the NeoForge website for more information.
That trick is promoted. Consider using </support registryrework:1143596306917494804> instead.
why did that only half work

