Page 1 of 1

[2.0.23] Productivity bonus incorrect when set by mods

Posted: Fri Dec 13, 2024 4:21 pm
by demonicpigg
My mod (https://mods.factorio.com/mod/progressive-productivity) sets productivity to different amounts in increments of minimally 1%, default 5% when the player gets to a breakpoint in production. When they hit a breakpoint, it notifies them with a game log, and currently, when they hit 105%, it notifies them repeatedly. The issue seems to be that 1.05 is stored internally as 1.04.

In my code I'm doing:

Code: Select all

local function are_doubles_equal(a, b, epsilon)
    epsilon = epsilon or 1e-4  -- Default epsilon value
    return math.abs(a - b) < epsilon
end
And then using it:

Code: Select all


        for recipe_name, prod_bonus in pairs(processed_recipes) do
            if not are_doubles_equal(force.recipes[recipe_name].productivity_bonus, prod_bonus) then
                local display_item_name = {"?", {"item-name."..recipe_name}, {"fluid-name."..recipe_name}, {"entity-name."..recipe_name}, recipe_name}
                game.print({"", {"mod-message.progressive-productivity-progressed", display_item_name, (prod_bonus * 100)}})
                force.recipes[recipe_name].productivity_bonus = prod_bonus
            end
        end
        
I've added a save which shows the issue, if you hover over the furnace it shows the percentage as 104%. I added a couple of logs to debug, and I got:

Code: Select all

 538.765 Script @__progressive-productivity__/utility/product_cache.lua:87: Productivity not equal!
 538.765 Script @__progressive-productivity__/utility/product_cache.lua:88: 1.039999961853
 538.765 Script @__progressive-productivity__/utility/product_cache.lua:89: 1.05
 
Additionally, I tried going into a game with no mods at all whatsoever and ran:

Code: Select all

/c game.player.force.recipes["iron-plate"].productivity_bonus=1.05
which also produced a 104% bonus on the furnace with iron ore in it.

It seems the reason is that the productivity_bonus is floored at 2 decimal places, rather than rounded to 2 decimal places (1.050001 works properly.)

Re: [2.0.23] Productivity bonus incorrect when set by mods

Posted: Fri Dec 13, 2024 4:43 pm
by eugenekay
This sounds like a weird Floating Point / Double issue.

In your game.print call, you are multiplying "prod_bonus * 100"; to convert to a "Per cent" figure. Thus, the internal representation for these two values is actually "0.0105" and "0.01039999961853".... which sounds suspiciously like a Floating Point error. Feeding these numbers into a Handy Calculator yields these interesting numbers:
Screenshot 2024-12-13 113806.png
Screenshot 2024-12-13 113806.png (84.46 KiB) Viewed 381 times
Screenshot 2024-12-13 113821.png
Screenshot 2024-12-13 113821.png (82.73 KiB) Viewed 381 times
0011111110000101100000010000011000100100110111010010111100011011 (0.0105)
0011111110000101010011001001100001010001111010111000010010000001 (0.0103999...)

The divergence occurs from the 17th Binary Digit onwards. My suspicion is that there is a Loss of Precision occurring internally in this calculation as a 16-bit number, but the displayed numbers are from a 64-bit "Double" which has been cast to a Decimalized String for display.

Re: [2.0.23] Productivity bonus incorrect when set by mods

Posted: Fri Dec 13, 2024 7:58 pm
by demonicpigg
My current belief is that the game simply floors the number to 2 decimal places. There's no functional difference between 1.05 and 1.059, which is generally fine, but this leads to the issue of 1.05 doesn't exist in lua, and is instead 1.04999... which gets floored to 1.04, and then stored as 1.03999...

I suspect it's just a funky edge case around floating points and how they handle rounding. I suspect they wanted to be able to differentiate from IE 2.5% (0.025) and 3% (0.03), and round would make them both 3%, so they chose floor, but I don't know if that's the case or it's something else. Fun times with floats!

Re: [2.0.23] Productivity bonus incorrect when set by mods

Posted: Thu Dec 26, 2024 5:19 pm
by Rseding91
Thanks for the report. The productivity bonus is internally stored as a 16 bit signed integer after dropping all values beyond 2 decimal places. So this is working correctly.

Re: [2.0.23] Productivity bonus incorrect when set by mods

Posted: Sat Dec 28, 2024 10:47 pm
by demonicpigg
Okay, so just to make sure, it is expected to, and working as intended to set productivity to 105% and have it instead set to 104%? Just want to confirm, as that is.. well, not expected from my perspective.

I understand that it's intended to drop all values beyond 2 decimal places, which makes sense and works properly, but setting it to 1.05 sets it to 1.04, which again feels not expected from my perspective.