-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix milling products #71677
fix milling products #71677
Conversation
From what I can see your solution is trying to fix the wrong end of the issue. The For example if you're milling 50x item A with a conversion rate of 0.5, they will turn into 25x item B. Those item B should then all have 50x A as components and recipe_charges should be 25 so nutrients can be calculated correctly. |
Yes, the total number of charges is items * conversion rate, but, as you said, the item is a single item. As far as I could see, with my compiler deciding not to help, there is no way to set a count on the item unless it's one with charges, and those are to be removed. If I remember correctly, there is something used by recipes for their components that deals with counts, and it might be possible to go via that rather than manipulation of an item. Edit: The |
Recipes have two advantages for the purposes of this. The first is that they essentially define the "conversion ratio" as a proper fraction with created items as the numerator and required items as the denominator. And the second is that they also have an explicit batch size and not just convert arbitrary numbers of items. What you could do here as a probably not too bad solution is about this:
2 and 3 are mostly to avoid excessive duplication of components. E.g. if you were to mill 100 wheat into 1500 flour without those steps, you'd get 1500 flour items with 100 wheat as components each, meaning you'd have 150000 wheat in memory and saves for kinda no reason. It's still not perfect for non-integer conversion rates because you could have extra input items that result in the gcd becoming 1, but what you currently have results in |
Clang-tidy 16 / build (src) (pull_request) seems to be screwed up:
Untouched file, and that's not what's on that line, it's
|
I didn't give it a real review, yet, just addressing the clang-tidy issues.
Qrox already has a PR up to fix that, so you can ignore it.
You're supposed to use
You have two loops like that, the first one is the offender that doesn't remove elements and could be changed, the second one is fine because as you said it removes elements. |
Spell checker encountered unrecognized words in the in-game text added in this pull request. See below for details. Click to expand
This alert is automatically generated. You can simply disregard if this is inaccurate, or (optionally) you can also add the new words to |
I like the recipe approach, I think that might be a potential first step in genericizing things like milling, smoking and other automated processing. Currently this causes new issues, though. For one, not all items with milling data actually have recipes. I didn't check all, but found dry wild rice at least. That's only obtainable by milling wild rice if I'm not mistaken. And another is that the code can't find any recipes with suffixes. So if you had two alternative recipes that use different components to get the same item, you could only mill the items from the recipe without a suffix. Another small thing is that with your changes, the conversion rate of the milling data is obsolete (but is still used for item info in a possibly inaccurate way). This together with the above means the |
Good thoughts. It's a fair bit of JSON work, so I'll make a comment to indicate what I'm trying to do (essentially what you suggest):
Apart from the above, I also found the large_bone had a mill entry, but it won't fit into a mill, and it had a conversion factor of 4 while the calcium was 144 times higher than the regular bone (which also had a factor of 4). I just struck the milling entry from the large bone (with a "comment"). Edit: paste_nut and paste_seed only has a quern recipe, missing the mortar and food processor ones. paste_nut are suspect, as it have very low conversion rates, which leads to a suspicion it's meant for individual seeds rather than standard units (it also overrides nutrients). The paste_seed recipe has a much better conversion rate than the milling info does. I went with the recipe. chili-p is inconsistent. Conversion factor 20, but 2 recipes yield 50 and the last 1. I went with 50 for all of them. Also note that there are 2 recipes for chili_pepper and one for dry_chili, but only dry_chili has a milling entry. Finally, dry_chili has 1 recipe, chili_pepper 2, out of the standard lot of 3 for different tools. garlic_powder had a conversion_rate of 5 but a recipe rate of 50. I went with the latter. While there are 3 recipes for garlic_powder, only one of them uses dry_garlic, which has the milling entry. The other two use garlic_clove (and one of those uses an additional heat source). Of course, 3 recipes over 2 ingredient variant means not the standard set of 3 sets of tools is provided for either. Edit 2: There's probably a need for an audit of milling tools, as I don't think they're consistent in how the 3 recipes (when present) are implemented. I won't address that side track, though. skewer_bone gets milled into meal_bone_tainted, for some reason. Doesn't make sense as they're extracted from bones and bone_sturdy, which only contain "normal" bones (although human and demi_human is included). meal_chitin_piece takes insect_dust as an input in 2 out of 3 recipes. It doesn't have any milling entry, and its description does not seem like something you'd actually be able to use for meal production. I leave that for others to deal with. Edit 3: The reason there are as many recipes as there are is that I've tried to use the smallest source material lots possible for each material, as opposed to the crafting recipes that tries to cram everything into a standard package. Code doesn't care about UI clutter, though. |
Yeah, a lot of the stuff is inconsistent (or outright bugged, which is why I made #71768 after reviewing this). But beware of scope creep. It's perfectly fine to just fix the milling mechanics in this PR and address inconsistencies in another one. |
…wild rice yields too many calories for test => same as for dry_rice
I'm stuck with the tests' refusal of accepting flour_wheat_free from rice and wild rice. Apparently factoring out these two from a larger combined recipe runs afoul of the bounds within which the product calories are allowed to lie. Edit: Edit 2: Looks like "null" for |
Further oddities noted:
|
Current test failure looks like the average just needs to be moved. Ping me if it's more complicated and I'm misunderstanding. |
@Maleclypse: I base this on the test error messages, so it might be wrong. I haven't seen the test code. As far as I understand the test attempts to ensure crafted items don't stray too far from the definition of the item crafted. In this case the base definition has 40 kcal while both dry_rice and dry_wild_rice has 240 with a factor of 3, resulting in 80 kcal per unit of wheat_free_flour. The test comes up with different numbers for some reason, but in the same ballpark. There's also the issue that the test itself is buggy, since it doesn't complain about the same yield in the manual crafting recipes (5->15), for whatever reason (my guess is that it's caused by a failure to handle the multiple alternatives sensibly, possible throwing them into a blender rather than picking out min and max). Either of those "solutions" would cause the tests to pass, but I can't judge if either would make sense from a real world perspective. |
What the test does is check all possible permutations of components for a given recipe and averages that out, then checks if that average falls within default calories +/- two times the standard deviation of the permutations (but at least 25%). So you basically found an outlier hidden within a recipe that won't be accepted as their own separate recipe. If all the food and recipe stats are correct, that is indeed a bug within the test. But on a fairly superficial glance it just seems like the conversion rate is wrong and rice should produce more flour. |
I searched the net for calories in a cup of wheat flour and rice flour respectively, threw the values into a calculator to determine a ratio, and then multiplied the calories of "flour" by that ratio, resulting in 57.xxx, which is close enough to the 60 you get with a conversion rate of 4 rather than 3. |
The Aftershock mod adjustment of milling was straightforward, just an modification of the entries, as the list used by the milling recipe had already been extended (and it uses the same factor). |
That's simply because there isn't one. |
Should a maintainer be notified? |
We should probably add a label for Megafauna in the future. |
Summary
None
Purpose of change
Fix #71652, i.e. milling yields the wrong nutrients.
Describe the solution
Note: Changed implementation yet again:
Change the JSON milling info to contain the product (as before) and a recipe id (instead of a conversion factor).
Changed the JSON item definitions with milling entries to reference recipes with the appropriate minimum source / product ratios.
Added milling info entries for copy-from items where the source item had milling info. The overriding milling info typically is for the "null" object, and no recipe is provided.
Find how many of each millable input we have in the mill.
Iterate for each type of source input we have:
Retrieve the corresponding recipe.
Iterate over all input alternatives to find the one we have in the mill.
Calculate how many batches we can make out of that input, produce the corresponding batch results, and remove the number of input items consumed.
Check that there is a recipe that takes the input to produce the milling result and don't accept input if none exists.
Check mill content at mill start and remove any content that won't result in full batches.
Note that the logic is duplicated for mill start and mill finalization, because it's possible to change recipes in between these points.
Describe alternatives you've considered
The first attempt was a 4 line quick fix...
Testing
Played around with cooked acorns and buckwheat.
Additional context
The mill has the luxury of using as many recipes as is needed to handle all the different source / product ratios. The player facing recipes, however, are left as is (with some minor corrections). This PR does not attempt to handle the large number of inconsistencies, omissions, and other oddities in existing recipes beyond that. A number of comments about issues have been left in comments below.
Note that this implementation doesn't actually use the source item's milling conversion factor, but rather that of the (first) corresponding recipe. It also relies on that recipe actually listing all the inputs that produces that particular product.