QuiltMC / quilt-standard-libraries

A set of libraries to assist in making Quilt mods.
Apache License 2.0
154 stars 84 forks source link

Plans on 1.19.3 Item Group API #214

Open EnnuiL opened 1 year ago

EnnuiL commented 1 year ago

(i apologize if this mega-issue is less clearer than i intended to; on the time of writing, i'm not really on a great mood)

I have to admit: I was never really a fan of the Item Group APIs that existed in the wild before 1.19.3; I never liked how we ported Fabric's API instead of working on a better solution, but the fact that Minecraft's own item group organization was a mess didn't help matters. But they have changed that for 1.19.3, and it's about time we address our own organization issues on the modding ecosystem.

The Fundamental Problems

These issues have always existed since eons ago, but it's only now that Minecraft is allowing (and is encouraging) to address them. So, here are the problems that I believe we need to address:

Mod Tabs are being mixed with Content Tabs

So, first of all, let's introduce terminology: mod tabs are item groups that are organized with the goal of containing the entirety of a mod's content. These are the "Mod Name" tabs, the ones that are separated from anything else. Now, the problem here is that while it can work well as a way of organizing content, it's only one way to do it. I've seen Vanilla+ mods use an alternative approach: add to content tabs. Content Tabs are item groups that have its own content category (ex: "Tools and Utilities)" and its goal is to organize with that category in mind, with Minecraft providing these as its default tabs.

Both ways of organizing content are valid, and the content tab-based approach? It is perfect for tiny content mods that don't add much and that fits in the Vanilla content tabs' scope. But when you add too much, the scope doesn't target one tab cleanly, and/or fits none of the content tabs, a mod tab suddenly looks more attractive.

With 1.19.3 introducing the possibility of an item targeting more than one item group, going for both approaches is more sustainable, but having a chaotic blend of mod tabs and content tabs still hurts the organization a lot, and it's even worse when one is favored over another, and the inability to filter through tabs also still is a thorn to the prospect of encouraging appending to content tabs.

A barely-interconnected chaos is hard to organize

If we try really, really hard to encourage mods to organize their content in a better way, we still will have some sort of trouble! After all, mods can do whatever they want to, and that means that they can also do shenanigans that can be harmful to the whole process. An user-side way of fixing issues manually must be investigated.

The proposal that I push:

Yep, if the structure of this issue seems familiar, it's because it quite is! But I don't wanna do everything this time, I just want to push hard for a way to target these issues, without leaving anything unaddressed. So, here are the stages (and misc stuff) that I propose:

Stage 1: Establish a hard split between Content Tabs and Mod Tabs

What I propose are two views for the creative inventory: a Content View and a Mod View. The content view is the main view, it contains all the content tabs, like all the Minecraft ones and such. The mod view would be the same as the content one, but with one major difference: it doesn't display content tabs, it displays per-mod ones. This means that in theory, all Minecraft tabs would instead be displayed as a single "Minecraft" tab, and mods are free to add their own mod tabs. For the content view, mods can still add content tabs, but they aren't encouraged to do that, instead, they must establish their own conventions, and QSL could also provide few convention content tabs of its own! But it can't simply add Mod Name tabs there, that's the job of mod tabs, and therefore, they're restricted to the mod view.

There are many different approaches we can go for here, like having the mod view somehow replace the Search tab, with something acting as an "All Items" view instead (refer to the misc. for more). It'll be interesting to explore the concept of the two views somehow, but I believe that most potential issues come from how the content can end being cumbersome, but well? I have another stage to address that!

Misc: @LambdAurora had the nice proposal of making the Search tab's search bar universal, in a way that you could search everywhere. In my opinion, maybe a toggle for restricting it to the selected tab's content might be interesting? But yeah, it's proposal is a really interesting one.

Stage 2: Implement Item Group Subgroups(/Sections/Categories???)

Welp, I'm changing terminology here; First, I called them categories, then sections, and now subgroups; So, subgroups are a way of filtering through the content of the parent group. They're meant as a subset of the main content but they could always have some extra content, but it means that the root must have 99% of everything. The way that it would work would be having something like this to the left of the creative inventory:

A sketch of a sidebar containing a page selector for tabs and a scrollable bar for subgroups

The idea is that you could select one subgroup at a time but there could be sub-subgroups that could be selected multiple per time.

Ultimately, the problem that it targets is the potential difficulty of sifting through a creative tab in order to find something. Also, with the addition of a sidebar to the creative inventory, we could take advantage of it as a new place for the tab page selectors!

Stage 3: Data-drive the whole system!

Yes! This should be data-driven! But yeah, despite the best of our efforts, ultimately, it would be necessary for the user to modify few things there and there, so, that's why we need to have this data-driven.

The idea is to have a tag-like system that isn't really like tags. Item groups would be composed of item stack groups, and these item stack groups could be composed by even more item stack groups, with this recursing being made more practical through allowing the JSON to also define these sub-stack groups. Maybe we could also allow for dynamic stack groups, in which a mod could add content to it through code, but ultimately, the idea is that it'll eventually be part of a data-driven one.

This could be integrated to the Material API somehow, which is an interesting possibility

This is only my proposal!

While I believe this trifecta will cover everything, there may be better solutions for it, or even ones that could complement it! But yeah, we do need to discuss a lot, because we really need to do something about the whole situation, and we better have the best solution for the ecosystem overall, not just a conservative "adapt to 1.19.3 changes and mess it up" approach.

JieningYu commented 1 year ago

https://github.com/AlphaMode/DataTabs There already has a mod that implements the data-driven item groups.

justliliandev commented 1 year ago

This sums up a lot of the problems I have with the creative screens and has ideas to solve them. Especially stage 2 is something I really look forward to. A concern I have with adding modded content to the vanilla content tabs is that vanilla content might be harder to find, because the tab might get a lot bigger, but is potentially the only content not findable in subgroups. This could be mitigated by having a misc subgroup that contains all items not in other subgroups.

About selecting subgroups: I think it could be useful to have placeholder items in the main tab to open a specific subgroup view when clicked. As an example I think that suspicious stew, enchanted books, potions and potion arrows could use a dummy item that, when clicked, opens a subgroups with all enchanted books, stews etc. . This could help keeping tabs reasonably small and also potentially fix my concern mentioned earlier, so a misc subgroup might not be needed. These subgroups could also benefit from being hidable from the left list, as they are already discoverable by the item

I would like to help with the development of this feature.

lukebemish commented 1 year ago

Okay, here's my main question here. How do you handle a mod that has a ton of items getting shoved into a single content tab? Like, if we have a content tab where vanilla puts ores in now - that's great, mods should shove their ores there. But one mod dumps 200 ores there, and now the tab is basically unusable. Do you already have a good solution to this that I missed?

Additionally, just my two cents: I think we probably shouldn't replace the vanilla search tab or add its functionality to all tabs. The former seems a bit out of scope, since some of us would just like to use the vanilla search functionality. The second seems like it would limit options for developers, though I think an easy solution would be to add it to vanilla tabs, and QuiltItemGroup/FabricItemGroup tabs, and only add it to other tabs on an opt-in basis, so that if a developer doesn't want it on their tab they can opt out of it.

I think making stuff data driven here is a good approach, however, I think the actual item group logic may need non-data driven (or optionally data-driven) bits - after all, someone may want to do weird stuff with the icon on their item group: cycle through a series of items, etc.; also, some people don't have lists of items at compile time, and do stuff dynamically, and while I could probably generate and inject the data as necessary at runtime, it would be far easier to have a code path to add it still. (Basically, the vanilla way of making an item group with items in it should still work)

LambdAurora commented 1 year ago

Icon rendering is definitely dependent on non-data driven bits, which probably will take the form of an icon renderer registry with an arbitrary DFU-serializable object passed as parameter.

I also would like to note that any QSL API with data-driven capabilities mean that there will be a code-only path, to me it's something obvious.

lukebemish commented 1 year ago

Alright, thank you for the clarification on both points; the second point is not necessarily obvious, which was why I asked. I'd also add that it's not just about allowing a code-only path, but about allowing the vanilla path to work on its own. After all, any fabric mods that have custom icon stuff will be using a mixin to expand the item group array and shoving their own group into it, just like QSL currently does, so this API will need to know what to do in that case.

DanielGolan-mc commented 1 year ago

Alright, thank you for the clarification on both points; the second point is not necessarily obvious, which was why I asked. I'd also add that it's not just about allowing a code-only path, but about allowing the vanilla path to work on its own. After all, any fabric mods that have custom icon stuff will be using a mixin to expand the item group array and shoving their own group into it, just like QSL currently does, so this API will need to know what to do in that case.

I think they can just be treated as mod tabs.

lukebemish commented 1 year ago

Yes; I had just assumed there'd be issues since there's no way to tell what mod they come from or anything

DanielGolan-mc commented 1 year ago

Yes; I had just assumed there'd be issues since there's no way to tell what mod they come from or anything

Creative Tabs have identifiers iirc? We can just assume the namespace is the same as the mod id.

If they don't have namespaces (don't remember...), Or there's another issue, we can just assign them to Fabric API.

lukebemish commented 1 year ago

Nope, just fabric/quilt added ones do. Ones added through a mixin-and-array-expand don't necessarily, and that's not an insignificant number of tabs in mods

DanielGolan-mc commented 1 year ago

Nope, just fabric/quilt added ones do. Ones added through a mixin-and-array-expand don't necessarily, and that's not an insignificant number of tabs in mods

Then we can just assign them to subcategories at a "more..." tab or something, or add them as mod tabs with an empty/default namespace.

TwilightFlower commented 1 year ago

I agree that a way to sort by mod and by content type is a good idea. However, I have UI concerns. Simple pagination is an intuitive UI that doesn't really require any explanation, but having multiple views and subcategories is anything but, let alone changing the search function. I'm also concerned that it goes beyond the scope of simply making vanilla's tab system usable by mods, and into redesigning the entire creative inventory UI, which feels a little out of scope for a modding API.

lukebemish commented 1 year ago

That's basically exactly what my worries are too. Thanks for phrasing it so well

DanielGolan-mc commented 1 year ago

Simple pagination is an intuitive UI that doesn't really require any explanation, but having multiple views and subcategories is anything but [simple]

Correct, but if all tabs have an "all" subcategory, that is selected by default, you could just ignore the subcategories. I think it'll be pretty intuitive if designed correctly.

let alone changing the search function

Did we talk about it? Anyway - I don't think it should be changed, search should be kept to the "all items" vanilla tab - maybe added to some mods' tabs too - for example, botania or create that are really big - but you could make this togglable by the modder (I, specifically, don't support it, because of stuff like Create add-ons)

I'm also concerned that it goes beyond the scope of simply making vanilla's tab system usable by mods, and into redesigning the entire creative inventory UI, which feels a little out of scope for a modding API.

I kinda agree, but I also think we should make a standard here. It may be a little out of scope but the sheer gain outweighs it.

Additionally, will we allow for mods to add a subcategory to another mod's tab? Maybe make a "parity" feature built-in, that'll add a "parity" sub category to each tab that'll contain items from this or other mods that are added only by installing said 2 mods?

LambdAurora commented 1 year ago

Additionally, will we allow for mods to add a subcategory to another mod's tab? Maybe make a "parity" feature built-in, that'll add a "parity" sub category to each tab that'll contain items from this or other mods that are added only by installing said 2 mods?

In theory, if we apply the plans for the API and if modders follow it, such feature wouldn't make the most of sense since the idea is to not have per-mod creative tabs but categorize stuff in actual meaningful categories.

And because we can't entirely eliminate the concept of mod tabs there was this idea of still allowing to filter by mod using sub categories.

So far an actual prototype is yet to be seen to determine the best course of action.

DanielGolan-mc commented 1 year ago

So far an actual prototype is yet to be seen to determine the best course of action.

I'll make a prototype in java swing, making it in the game itself will be unnecessary for now (wanna check if there are some stuff that can improve the model that I won't think of while using MC's UI system)

Update

image it works now I only need a to add subcategories, tab pages, and bottom tabs, plus I need a list of dumb item names

another one

My finger real hurts and it almost fell off so nvm I can't do that (almost as in I had luck, not as in hospital saved me)

falkreon commented 1 year ago

I had mixed feelings about the original Fabric creative menu API and GUI changes. I was there when it was created, and my concerns were almost universally overruled.

I like the idea of subgroups being tucked into fake items, but it's worth looking at lib39 fractal's setup too, because subgroups have been needed for so long that there's already a library for it.

EnnuiL commented 1 year ago

I had mixed feelings about the original Fabric creative menu API and GUI changes. I was there when it was created, and my concerns were almost universally overruled.

* I wanted us to have a favored path for a mod to swap in a new creative gui, like FRAPI does with renderers.

* I wanted to make the page arrows bigger and put them on opposite sides of the tab bar in the default gui.

* I wanted some way to take in data about item subgroups, even if that data wasn't used or rendered in the default gui.

I like the idea of subgroups being tucked into fake items, but it's worth looking at lib39 fractal's setup too, because subgroups have been needed for so long that there's already a library for it.

Ah, about una's thing? It does look interesting, however, yeah, subgroups being tinier-than-tiny text seems like both an accessibility and a localization nightmare; I feel like with subgroups being represented by an icon that would have a tooltip? We can avoid those problems

falkreon commented 1 year ago

subgroups being tinier-than-tiny text seems like both an accessibility and a localization nightmare; I feel like with subgroups being represented by an icon that would have a tooltip? We can avoid those problems

I don't think localizing subgroup names in tooltips versus localizing subgroup names in displayed text is significantly different, but I could understand an argument that it might easily run off the right edge of the tab in some locales, especially if the font size was increased. And I totally sympathize with frustration about things being too small.

A left bar of tooltipped icon subgroups sounds splendid to me! I just want bigger arrows positioned on either side of the thing being scrolled, instead of small ones squished together on one side.