Schall Recipe Scaling


Adds scaled up version of recipes, in order to get around the game limitation (60 crafting per second) faced by very high speed machines. This allows for true mass production under healthy UPS. Designed for supporting scaled up machines from “Schall Machine Scaling” mod. (Locale: English, Deutsch, 正體中文, Português Brasileiro)

Content
3 years ago
0.17 - 1.1
10.1K
Manufacturing

b [Responded] Incorrect output for Krastorio 2 scaled steel recipe (Not my problem)

3 years ago

Hello,

Now that I have reached Singularity science in K2 it's time to scale up and beacon the bejeezus out of the production chains. So naturally the way to go is using your scaling recipes mod. But while it works fine for things like acids, plastic, copper, iron etc., the steel recipe gets interesting.

Original values: 2 coke + 10 iron plates = 5 steel plates / 16 s

Scaled recipe (x50): 100 coke + 500 iron plates = 12500 steel plates / 800 s!!!!!!!!

Screenshots: https://imgur.com/a/f9gkhmI

The game is running just with Krastorio 2 and Schall Recipe scaling, no other mods.

3 years ago

Hallo Schall, I just ran into another one. The screenshot collection has been updated with the recipes for scaled vs. non-scaled Enriched Rare Metals.

Vielen Dank!

3 years ago
(updated 3 years ago)

I have reproduced your problem.
My initial finding is that Krastorio 2 have modified the (vanilla) recipes into a weird way.
Here is what I observe in dump of definition of the steel plate recipe (with/without mods), by using serpent.block().
(I have merged some lines to make the text more compact, without changing contents.)
Note that my mod is NOT modifying the below original recipes.

Vanilla steel plate recipe

{
category = "smelting",
expensive = {
enabled = false,
energy_required = 32,
ingredients = {
{ "iron-plate", 10 }
},
result = "steel-plate"
},
name = "steel-plate",
normal = {
enabled = false,
energy_required = 16,
ingredients = {
{ "iron-plate", 5 }
},
result = "steel-plate"
},
type = "recipe"
}

Krastorio 2 steel plate recipe

{
category = "smelting",
energy_required = 16,
expensive = {
enabled = false,
energy_required = 16,
ingredients = {
{ "iron-plate", 10 },
{ "coke", 2 }
},
results = {
{ "steel-plate", 5 }
}
},
name = "steel-plate",
normal = {
enabled = false,
energy_required = 16,
ingredients = {
{ "iron-plate", 10 },
{ "coke", 2 }
},
results = 0
},
type = "recipe"
}

Can you identify a problem here?
The K2 normal recipe has the results = 0 line!
I am not sure how the game can still run without complaining this. (Maybe the game can auto-correct this?)
This does not cause a problem to the game run, but is causing a problem to my mod. For unknown reasons (my code already has error checking, but this time seems to be passed by K2 steel plate recipe...), this has led my code to erroneously multiply results of expensive part for a second time, when it is dealing with normal part.

So my initial summary is: this bug is caused by K2 side.
I am not yet sure what can be done on my side, as any other mods may also introduce such strange recipe definitions.

3 years ago

Got it. I will address Linver and Krastor about this issue. Thanks a lot for the investigation!

(And BTW, I think the scaled Enriched Rare Metals recipe works fine. :D )

3 years ago
(updated 3 years ago)

As answered to the_ave:
That is not a bug, these are the modifcation of K2:

-- Chaning steel recipes
krastorio.recipes.overrideIngredients
(
    "steel-plate", 
    {
        {"iron-plate", 10},
        {"coke", 2}
    }
)
krastorio.recipes.overrideProducts
(
    "steel-plate", 
    {
        {"steel-plate", 5}
    }
)

Where the function do:

function krastorio.recipes.overrideProducts(recipe_name, new_products, new_expensive_products)
    local recipe = krastorio.recipes.getRecipeFromName(recipe_name)
    if recipe and next(recipe) then
        -- normal ingredients
        if recipe.normal then
            recipe.normal.result          = nil
            recipe.normal.results         = new_products
            recipe.normal.result_count    = nil
        else
            recipe.result                 = nil
            recipe.results                = new_products
            recipe.result_count           = nil        
        end
        -- expensive ingredients            
        if recipe.expensive then        
            recipe.expensive.result       = nil
            recipe.expensive.results      = new_expensive_products or new_products
            recipe.expensive.result_count = nil
        end
        return true
    end
    return false
end

From MY point of view there are no bugs, because in game:

The prototype explorer output give the wanted ad expected result.
I know that the serpent.block() function is not safe for pointed tables, so:
My modifcation are legals in the game, and the game work, and the results are as wanted, and I can output the right value in the final game load state.
I'm sorry Schallfalke but I can't help u in this case because is a problem about serpent.block() and how u access to the table.

3 years ago

The point is results and new_products are actually tables.
I have not crawled into your code (too massive and time-consuming for me), but your mentioned lines already show the problem:

recipe.normal.results = new_products
recipe.expensive.results = new_expensive_products or new_products

You are simply assigning the identical pointer of the same table to both recipe.normal.results and recipe.expensive.results, assuming new_expensive_products is nil. This is how = operator does to Lua table.
This is exactly why trying to multiply by 2 to both tables will result in the same table of new_products being multiplied by 4.
So it is not about how I accessed the table. This is about how you dealt with Lua table (and pointer).

The proper way to use table.deepcopy(<table>) to create a clone of table, so it will returns a different pointer.
Therefore the solution is simple: just modifying one line:

recipe.expensive.results = new_expensive_products or table.deepcopy(new_products)

PS: This is similar to the case of a friendly mod about new alien units. His code is assigning the pointer of the same table to all of his biters and spitters. Say, he did a loot_alien = { { "loot-1", 2 }, ... }, and perform unit.loot = loot_alien of each of his biters/spitters.
Guess what would happen when loot mods (including mine and others) trying to add another loot items to his new alien units?

3 years ago

I do this many times in loader phase, I don't want slow it and also, I have to modify a sort of 3000 lines of code.. and I stop modding.. so..
I'm only continue support K2 for crash or major bugs. But, have a good luck ur mods.

3 years ago

Thanks Schallfalke, your solution worked just fine! :)

3 years ago

Just because I like u as modder Schallfalke:
https://bitbucket.org/Linver23/krastorio-2/commits/1d27bbfd2d31fdcffeb69c71bfec43a6d5548dc4

But I have not tested completely if this have caused some internal mod bugs, I have not much time to spend on modding so, if that happen without a trace of the origin of the problem maybe, I have to revert it. I can't sacrifice the mod stability for compatibility purpose.

3 years ago

Thanks for applying the code.
Reply of the_ave seems to indicate it is the solution. So problem solved?

Honestly, each data prototype should have its own tables, unless there is a very strong reason that changing one should change all, and really not intended for any mods to modify that.
At least the vanilla prototypes do try to maintain so practice. For example, changing values in collision box of an entity would not automatically (erroneously) changing any other entities.
Think of this, if some of the vanilla prototypes are sharing the same table, then any mod changing the table values of one prototype will change ALL other prototypes. This is a source of mod incompatibilities!
So you are not only doing me a favour, but to yourself, and to anyone who are going to tinker with recipes in K2 bridge mods.

3 years ago

U have right but understand me, I done the work of: requisite analyst, code designer, coder, tester, debugger, of a sort of 50k-75k lines of code.. now I have time only for small fixes, touch something can create an unimaginable amount of side effects, I have to be careful touching things.

3 years ago

@Schallfalke: I have not observed any other strange behavior in my save, using just one change (not both made by Linver, I am on vacation so today I was away from home until evening, going to update K2 with the latest commit and I will look again now).

@Linver: thanks for applying the fix in the mod!

3 years ago

All recipe works properly now?

3 years ago
(updated 3 years ago)

Hi -- this might be an independent issue, but I am also having a problem with Schall recipe scaling and Krastorio 2 (possibly due to Space Exploration and associated dependencies).

Here's a picture highlighting the issue:
https://imgur.com/a/hu5MHzE

The scaled-recipe should take 100s, but instead it takes 750s. Most other Krastorio 2 recipes are scaled correctly (e.g. Silicon + Vulcanite Blocks), however the scaled module recipes for tiers 1-3 all incorrectly have 750s. Modules 4+ are fine.

New response