[2.0.32] Demolishers share resistances

Bugs that are actually features.
DataCpt
Burner Inserter
Burner Inserter
Posts: 14
Joined: Mon Jan 20, 2025 11:16 pm
Contact:

[2.0.32] Demolishers share resistances

Post by DataCpt »

I don't know of any other entity where changing the resistances of one entity also changes the resistances of another. If this is expected behaviour then this is not a bug.

Demolisher resistances are set inside /data/space-age/prototypes/entity/enemies.lua and all use the same demolisher_resistances table. It seems this is setting the resulting resistances to a reference of that table rather than making a copy of the values.

Tested with the following:

Code: Select all

log("START TEST")
local i = 0
for name, unit in pairs(data.raw["segmented-unit"]) do
  i = i + 1
  unit.resistances[1].decrease = i
  log("Setting resistance of " .. name .. " to: " .. unit.resistances[1].decrease)
end
log("Result:")
for name, unit in pairs(data.raw["segmented-unit"]) do
  log("Resistance of " .. name .. " is: " .. unit.resistances[1].decrease)
end
log("END TEST")
Resulting in:

Code: Select all

START TEST
Setting resistance of small-demolisher to: 1
Setting resistance of medium-demolisher to: 2
Setting resistance of big-demolisher to: 3
Result:
Resistance of small-demolisher is: 3
Resistance of medium-demolisher is: 3
Resistance of big-demolisher is: 3
END TEST
It is trivial to bypass this issue by assigning a table.deepcopy of each individual demolisher's resistances before attempting to change them but I felt like it would be good to document anyway.
User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 3865
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: [2.0.32] Demolishers share resistances

Post by boskid »

This topic again... viewtopic.php?p=660790#p660790
User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 3865
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: [2.0.32] Demolishers share resistances

Post by boskid »

I am going to throw this to Not a bug because there are way too many places where tables are shared meaning it was never guaranteed for tables inside of data to be independent. If you want to change those values, you may need to deepcopy them to make sure they are independent, this will make your code resilient against other mods also using shared tables.
DataCpt
Burner Inserter
Burner Inserter
Posts: 14
Joined: Mon Jan 20, 2025 11:16 pm
Contact:

Re: [2.0.32] Demolishers share resistances

Post by DataCpt »

boskid wrote: Tue Feb 18, 2025 1:45 pm it was never guaranteed for tables inside of data to be independent. If you want to change those values, you may need to deepcopy them to make sure they are independent, this will make your code resilient against other mods also using shared tables.
Yeah I made a note of that at the bottom:
DataCpt wrote: Tue Feb 18, 2025 4:58 am It is trivial to bypass this issue by assigning a table.deepcopy of each individual demolisher's resistances before attempting to change them but I felt like it would be good to document anyway.
I do expect a lot of tables to be shared but it definitely took me longer to clock onto this one since I never ran into resistances being shared before.

Is there a simple way to check for this or is it standard to deepcopy every table before modifying it? This isn't advice I've seen or heard before but it's not unreasonable!
DataCpt
Burner Inserter
Burner Inserter
Posts: 14
Joined: Mon Jan 20, 2025 11:16 pm
Contact:

Re: [2.0.32] Demolishers share resistances

Post by DataCpt »

boskid wrote: Tue Feb 18, 2025 9:55 am This topic again... viewtopic.php?p=660790#p660790
the most sane approach i think is to write mods in a way that are working correctly regardless if the data sits in a shared table or in an independent table
Seems like I agree with you, I'm going to personally assume tables are references to avoid this kind of issue from now on.
Post Reply

Return to “Not a bug”