wisp-forest / owo-lib

Open ωorthωhile Operations, yes the acronym was "totally accidental"
https://modrinth.com/mod/owo-lib
MIT License
192 stars 37 forks source link

[New Features] Data Generation in owo-lib #156

Open Krysztal112233 opened 1 year ago

Krysztal112233 commented 1 year ago

Why and Design

Considering that owo-lib has long had the amazing container and reflection design of the ***RegistryContainer, and provides an easy-to-use registration feature based on it, could we not provide an even easier DataGeneration feature based on this design?

In this case, I tried using annotations to mark up the field and use reflection on it early on, and I think this is a good fit for the way owo-lib uses reflection: use the information about the field to process it accordingly, and use annotations to attach additional information to the field.

Examples

These are some of my early designs and uses.

Basic Infomation Attatch

I considered use annotations to attach infomation to field, this is the most common generic practice.

But there is a downside to this approach, which is that if there is too much information to be attached to the annotations, they can become very lengthy.

Here is an example:

@AssignedName("test")                       // Already in owo-lib.
@Recipe("test_recipe")                      // Maybe we can scanning recipe object and storage it in a hashmap?
@Tag("issues:test", type = TagType.Block)   // Or also scan and storage tag information in a hasmap?
@Model(type = ModelType.NoModel)            // Provide some pre-built models. Here the choice is not to generate.
public static final Block TEST_BLOCK;

Lang

TODO

Tag

TODO

Recipe

TODO

Model

TODO

BlockStates

TODO

gliscowo commented 1 year ago

I do generally think that a better Datagen API could be something useful for owo in the future, however I am quite unsure whether this is the right way of going about it. As you already correctly mentioned, putting all of the required data in annotations will make the resulting field declarations be extremely messy (and, in my opinion, hard to read).

Further, even just supplying the information in an annotation could prove very difficult. Something simple like a tag can easily be declared with just its ID - a recipe though I think is nigh-impossible to declare in a way that is both readable and doesn't take up tons of space.

If you have some ideas about how to address these problems, I'd love to hear about them. Otherwise, I'm afraid this may not be something we're looking for in owo itself

Cheers

noah1510 commented 1 year ago

I can add something to this.

In the process of creating EvenBetterArcheology I can across the same problem.

The first iteration of this was as suggested implemented using Annotations. However like @gliscowo mentioned this got messy and was not flexible enough for custom Blocks/Items which generate their data in the class.

The second iteration was implemented using Interfaces for all the Data types that might be generated and some default implementations of those. This fulfilled my original needs but produced way too much duplicate code and was difficult to keep track of all the function names that are used to generate the various types of data.

The current approach I use is to have one Interface with a generateData method. I created various Presets for things like stairs that have static functions to generate all the parts and just get called from the generate function. I use the postProcessField method to generate the data for all created Items/Blocks that implement the interface.

If you want to use that you can use https://github.com/noah1510/sakura-lib which mostly is the original data generation code but as a separate library.

Small side note I use ARRP instead of fabric datagen. This allows to generate the data files during the game start or in theory even in the background. One advantage of this is that you can insert items into the loot tables during the data generation step but only do that if that mod is loaded.