AsherGlick / ResourceCalculator

A Video Game Resource Calculator
https://resourcecalculator.com
GNU General Public License v3.0
56 stars 30 forks source link

Pulling Recipes directly from minecraft jar (at dev time) #58

Open mmodrow opened 2 years ago

mmodrow commented 2 years ago

I've been thinking and prototyping on the whole "let's parse the recipes from the jsons in the jar" thing. I need some input from you, so I follow your suggestion of opening an issue on that topic.

I whipped something up that pulls all the relevant JSONSs from a jar and started writing the mapping models and the deserializers. Works like a charm so far. I get all the item tag & recipe jsons and fully deserialized & flattened tag objects in fractions of a second.

To properly match your structure I need to map tag references in the recipes back to the actual items. This is fine with e.g. chests (when only using one type of planks that's at max 8 recipes to consider), but quickly results in escalation considering things like barrels (8 slab types x 8 log types = 64 recipes).

Currently the game has 3 recipes where logs/planks/wooden_* meet another tag (both types of campfires & the barrel). To still allow for things like torches from char coal and from coal, I'd like to still allow tags to resolve to different items for different recipes and not flatten them to a single item.

Thinking about your UI I'd aim for a heuristic, that creates at most 4 recipes from a single json. That would result in at most 6 entries (4x crafting, 1x plain item, 1x alternative crafting method like stone cutting or smelting). Does that sound reasonable to you?

Or would you prefer a full dump & pick'n'choose the best ones by hand?

AsherGlick commented 2 years ago

tl;dr: Use requirement_groups and ignore the problem like I did.

This is a very deep rabbit hole I fell into previously.

“Mix and Match” recipes that allow for multiple non-uniform items as requirements are truly a pain to deal with in the resource calculator. Unfortunately, the problem is not as simple as you describe it because each item in the recipe can be a different subtype of wood, not just each item type.

chest barrel

This means that for a chest that needs 8 planks of wood, and there are 8 plank types, would have 8^8 (or 16,777,216) possible ordered recipes. Luckily resource calculator does not care about ordering. So we can reduce that down to only 27,456 possible recipes. This is obviously still too many. To combat this, I originally tried to manually force all recipe’s to contain only the same types of wood. EG: all planks and slabs would be the same type of wood. This matches how the specialized recipes work. EG: in order to make a birch fence gate, you need to only use birch wood. This was not perfect though, and a bit tedious. So I tried creating a step towards a solution in the form of requirement_groups. A requirement_group could contain any number of other items and then could be used as if it itself was an item. This was great, but I never got around to figuring out how this would work in the user interface. Just displaying the possibilities would return us to the 27,456 possible recipes to choose from. So I decided to not solve the problem and instead only show the recipe of the first item in a requirement_group with the expectation I would eventually figure it out in the future. For now the requirement_group just acts as an alias for the first item in the list and I have not received any complaints about it yet.

I am happy to consume some other format that you have extracted instead of having your application match the resource calculator format. This would free your app from needing to obey any schema changes to resources.yaml in the future, such as whenever I figure out what to do with requirement_groups.

Last, something is better then nothing. If you want a validator to ignore everything with a * wildcard and only use this extracted data to validate some recipes, it will still be a step in the right direction, even if it is not the complete ideal. Further thought can be given to how to validate the wildcards in the future.

mmodrow commented 2 years ago

This idea isn't dead. But I currently have very little spare coding time, so it's on the back burner for now. I might get an mvp out soon-ish, but nothing finished in the next weeks.

AsherGlick commented 2 years ago

Given the imminent release of Minecraft 1.19 I have gone ahead an written something along the lines of this, where the recipes are extracted from the .jar file. This does not use java to do the extraction and thus does not benefit from any recipes written in the java code itself. This was added in c18a2ebe5679c6612faecdbb48e539c02aaa062f . The list of changes this brought to the minecraft recipe list can be seen via #62, I was surprised by the number of things that were still wrong.

This initial version is still pretty rough but as I get free cycles I hope to enhance it by removing the various TODOs scattered across it. Though at this rate that might not happen until the next version after 1.19 is on the horizon.

mmodrow commented 2 years ago

Sorry to keep you waiting. A lot of life happened recently. But I am glad to have nudged you into an mvp of your own to improve your data set.

AsherGlick commented 2 years ago

No worries, I mention it not as a push for you to complete your project but an excuse as to why I am stepping on your toes and going ahead with my implementation even though you had started work like this. One thing I have run into is that while I am able to pull the recipe information from the jar I have not yet figured out a great way to automate which recipe should be the default recipe. If you have any ideas as to how to programmatically figure that out let me know.

mmodrow commented 2 years ago

No toe-stepping felt on my end. I also just want to use the resource calculator with the best data possible. If you get through the door faster, than I do, that's a success for ”the greater good”, in my eyes.

No, I have not found a good way for that, as well... I guess one could manually flag a block type per tag/resource group as input data to prioritise in tagged recipes e.g. default to oak_log for #logs, but in the case of multiple possible ways to craft I don't really know how to universally decide that (besides extra efficient stone cutter recipes).

mmodrow commented 8 months ago

I guess we should revisit this idea... The current snapshot 23w43a announced officially, that all new copper blocks will be available in all oxidisation levels, including their individual crafting/cutting recipes per oxidisation level. Also they come both waxed and non-waxed. This might get ugly quickly, if one tried to configure them all by hand and figure out the cheapest method by hand per item...

AsherGlick commented 8 months ago

This was done a bit ago here, but you have reminded me that I have not actually merged in previous mc version's updates yet, https://github.com/AsherGlick/ResourceCalculator/pull/107, that has some updates to it. I should really do that at some point.

Since the jar extractor was implemented the only recipe issues I have received from users have either been: 1) The default recipe should be different (choosing the default is not automated) 2) The issue was wrong and the recipe was actually correct