neoforged / NeoForge

Neo Modding API for Minecraft, based on Forge
https://projects.neoforged.net/neoforged/neoforge
Other
1.13k stars 165 forks source link

Data Driven Registry Alias at game startup for material unification #539

Open TelepathicGrunt opened 7 months ago

TelepathicGrunt commented 7 months ago

Was part of some ideas bounced around on discord between people.

The problem is modpack can have many instances of the same kind of fluid or block or item from many mods. Like xp fluid, potion fluid, tin ingots, etc. Unifying them requires other mods or scripts and can be annoying to get working.

An idea is making the registry alias system data driven and loaded at game startup before mods register stuff. If you have an Brass Block from mod A, B, and C, you would be able to define in a config (or files) the resourcelocation of mod A and B’s block should be pointing to mod C’s Brass Block. Now in game, the blocks from mod A and mod B will be convert to mod C’s. Recipes that take or give mod A or B’s block will instead be mod C’s block.

Perhaps, and a bit more controversial or potentially problem causing, make the deferred registration of the brass block for mod A and B now return mod C’s Brass Block instance instead so now if mod A or B tries to place their block into the world from their block field, it really holds mod C’s block instead.

Perhaps this could more easily lead to crashes if mod A or B was trying to do something specific with the block that mod C doesn’t support but the onus is on the pack maker to test their unification and report issues to devs so workarounds can be done to support this.

This would be a more powerful tool for unification, is opt in, and should be easy to use. Now tear this idea apart lol

KnightMiner commented 7 months ago

Personally, I always found it cleaner to just unify resources via recipes, then hide duplicates. Allows the pack maker to make the final choice on which mod's variant to add (in case one does anything special) and prevents running into edge cases with object aliasing. We had a ton of them back when the fluid registry was not namespaced, and I'd really rather not relive that.

All that has been needed to make this work as a mod is what I have been calling "preference output". Instead of using raw item stacks/fluid stacks as recipe outputs, its a wrapper object that acts as a supplier, selecting the preference based on an order of preferred mod IDs (though you could add more complex criteria)

IchHabeHunger54 commented 7 months ago

Copy-pasting a slight adaptation of the proposal pinned in the relevant Discord thread:

TelepathicGrunt commented 1 month ago

@IchHabeHunger54 Are you still pursuing your idea or should we close this issue report?

RaymondBlaze commented 1 month ago

Are you still pursuing your idea or should we close this issue report?

I've looked into this and made some prototype, however I couldn't find a proper way to make proper datagen support for the proposed tag default recipe output. Recipe serialization has been moved to use Codec now, and we can't provide the tag default recipe output from recipes unless we patch in a field to every recipe that accepts a output. Such patches is not quite feasible due to the amount, and it still needs mods to do the same thing if they wish to use tag defaults in their datagen.

IchHabeHunger54 commented 1 month ago

I still think this is a good idea design-wise, however I do not currently have the capacities to implement this.

HenryLoenwind commented 1 month ago

Here's a random new idea: Self-thinning tags.

Those would be tags (in a special namespace or marked in another way) that have a special behaviour; they can only hold one entry. Everything else that gets added, goes into a collection tag "hidden_items". These self-thinning tags could be used as recipe outputs (as they are now merely aliases and not groups).

This would sort out recipes automagically (given nobody uses the actual item but only the tags), and the "hidden_items" tag could be used to hide items in the creative menu and JEI.

Obviously, thinning tags cannot be used for everything and need to be applied with care. Throwing the same item into two thinning tags would be a very bad idea, and recipe inputs should not use them directly but use normal tags that contain the thinning ones.

Implementation-wise I think this would be a not-too-extensive change. There would be a post-processing step after tags are loaded to thin the thinning tags (easier than doing it on-the-fly, I guess, although this removes the implicit selection criterion "first"), support for tags as recipe outputs, and a tag filter for the creative menu.

(This is similar to the approach Ender IO took in 1.12, where we had support for oredicts as recipe outputs. As those were ordered, we could use the first item in there. This worked reasonably well, only hampered by it being the only mod doing that.)

PS: As always, Mods that want their stuff in the game because they want to do something non-generic with it should not add their stuff to a thinning tag. If your copper dust is edible and gives the player flight, don't put it onto the "please remove this if there are other copper dusts" list. Alias/deduplication systems are not for stuff that isn't a duplicate, duh.

PS2: The selection criterion for the thinning is another discussion point. The result should ideally be saved with the world to stay stable (unless the old winning item's mod is removed), but there should also be a way for a modpack to provide it on a per-installation level. Both should be pretty easy, as the data to be stored is a simple key-value mapping RL->RL that could be saved as a toml file. Initial selection is a bit harder, but a simple rand() can take care of that---and would prevent any gaming of the system like load order or alphabetical could provoke (The ZZZMod's author may become tired of their items never showing up and be tempted...).