bibby / factorio-thomas

Really useful engines for Factorio
1 stars 2 forks source link

Multiplayer desync - 0.0.4 #1

Open aarondandy opened 6 years ago

aarondandy commented 6 years ago

Not sure where you want issues to go, but also posted on the factorio site: https://mods.factorio.com/mod/really_useful_engine/discussion/5a5f1b0dadcc441024d773d1

In a dedicated multiplayer server I will desync shortly after Percy (it may impact others as well) is placed. If either I or another player places the engine down it appears that only I will desync even after a client restart. While trying to reproduce the desync we noticed that it occurs when the engine plays a voice line. Happy to help diagnose this issue on our little test map/pack we have going.

Interesting find. We noticed that when I (as a player) disable the talking in my options, it causes other players to also not hear the voice lines. Perhaps the mod uses my settings specifically which may be why only I crash. This could be related as I was the user that generated the map.

bibby commented 6 years ago

Just finding this now, and found it on mods.factorio.com first. I'll repeat the the same reply, and then give another thought with links.

I wasn't sure how this would behave during multiplayer, so please forgive me if it hurts your fun. After the talk interval hits, an area scan is performed looking for nearby trains. This is only done around 'player 1'; but I just thought of a way to make that better (or worse, depending on the cause).

I wonder if the lookup is expensive enough to cause your desync. There might be an alternative. Thanks for the report.

So here is the area scan looking for entities matching a name, say percy-train, and this happens once for each of the six train types. 6 lookups of a 64x64 area might be too much.

Another possibility could be the size of the sound files. I borrowed this implementation from another mod; creating an explosion type sound at an entity's location. This is why everyone hear's the same sound or lack thereof; I was hoping with direction and volume/distance basically for free.

It'll be some time before I can get to it, but I think an improvement might be to maintain an in memory table of trains on the map. So rather than blindly scanning a 64x64 area 6 times every n seconds, we can filter through a table already containing eligible items.

The initial reason I only checked the area around game.players[1] (presumably the host) was that I didn't want each player to trigger their own train, causing them to talk over one another. Also, I had no easy means to test multiplayer. It strikes me today that a simple solution would have been to break out as soon as an eligible train is found at all. With that in mind, a per-player check for nearby trains should be done with players in random order.

aarondandy commented 6 years ago

I don't know Lua or anything about Factorio modding but am willing to help. I would be happy to pair with you when we both have time and we could do some testing with my dedicated host too.

justarandomgeek commented 5 years ago

The problem is your use of lua local/global variables to store data that should be in the factorio-provided global table. Also, the init code at the top that's outside events is generally bad form, you may want to review Data Lifecycle for when to do various things.

Edit: and intstead of game.players[1], you may want to consider iterating over game.connected_players