Inserter Fuel Leech


In addition to normal behaviour, all Inserters take fuel from entities containing a burner when they or their drop target have no fuel left.

Tweaks
6 months ago
0.16 - 2.0
86.8K
Logistics

g MP desync

2 days ago
(updated 2 days ago)

The mod desyncs like 5 minutes into multiplayer because inserterDiscovery.lua caches its discovery state in a module local, not in storage. The host's on_init path and the joining client's on_load path then write storage.inserterDiscoveryState asymmetrically (host: never writes, client: writes once).

Sadly the repro is best described as "kinda random" because it depends on hell knows what, but it does produce a consistent source of random desyncs.

The root cause:

inserterDiscovery.lua:46:
local state = makeInserterDiscoveryState() -- module-local

inserterDiscovery.lua:60-64:
local function initInserterDiscoveryIfNeeded(tick)
if not state or state.version ~= InserterDiscoveryStateVersion then
initInserterDiscovery(tick, nil) -- this writes storage.inserterDiscoveryState
end
end

inserterDiscovery.lua:67-69:
function inserterDiscoveryOnLoad()
state = storage.inserterDiscoveryState
end

The same module-local state stuff is in inserterRepo.lua, probably another desync source.

a day ago

That local variable is holding the same table instance as storage.inserterDiscoveryState.
When starting a new game, it gets set by initInserterDiscovery in the first tick via discoverUnknownInserters -> initInserterDiscoveryIfNeeded. That function also puts the very same table into storage.inserterDiscoveryState.
When loading or joining a game, inserterDiscoveryOnLoad is called before that can happen in the on load handler and puts the table instance from storage.inserterDiscoveryState into the local state.

I don't see how the desync would be random. If it's my mod, you should get the desync in the first tick on the host or in the first tick after joining the game.
The state table is written to every tick with discovery enabled (which is the default). Even if discovery is disabled, the state is still checked to be initialized every tick (I probably should change that to save a few CPU cycles in that case). And it is only put into storage.inserterDiscoveryState on init or in the first tick after loading the game on the host (if it malfunctions, it would also do that in the first tick after a join in the joining player's game).

I probably look into this further on the weekend.

New response