Give my understanding about desync problems.

Place to get help with not working mods / modding interface.
kendoctor
Inserter
Inserter
Posts: 34
Joined: Wed Aug 05, 2020 6:43 pm
Contact:

Give my understanding about desync problems.

Post by kendoctor »

1. Game saved. With a gameState = N
2. One player A join -> download the save with gameState = N -> in his client on_load event triggered => Pass gameState into script => This is point
3. Player A going to play -> triggered M*event -> gameState changed to X, at this time another player B join
4. Player B join -> download the save with gameState = N -> in his client on_load event triggered => Pass gameState into script => The same point with player A at this step. But Playe A and Player B NOW has different gameState X and N
5. Player B begin to catch up, excuting all M*event in his client to reach gameState to X
6. But Player A still going, when Player B catch up, When Player A's gameState = Z, Player B also reached Z, Player B Joined.
7. Player A and Player B in his client , excuting the same events From gameState = N to gameState Z. No desync happned.
8. What will cause desyncs in this catchup period? Even excuting the same events?
9. Give an example: Player A, in on_event1 called random(), this changed gameState, but it did not changed sequences of events and amounts. At the end, when Player A and Player B exuting the same events in the same sequences, gameState will not be equal. random() has different seed in different client at different time.
10. All above just I deduced. If this was true, that will be the basis to avoid the desync problems.

thx, mrvn. again. here, he inspired me.
kendoctor
Inserter
Inserter
Posts: 34
Joined: Wed Aug 05, 2020 6:43 pm
Contact:

Re: Give my understanding about desync problems.

Post by kendoctor »

Another mentioned here. ramdom() function ,if facto rewrites this method using game.tick time. that will be no problem for player A and player B
I just gave an example. random things always can he happened.
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: Give my understanding about desync problems.

Post by orzelek »

random() is using rng stored with map so it's safe.
What you are looking at is usually some difference between mod behavior after game is saved/loaded.

Without actual desync report it's hard to tell more - a lot of theoretical scenarios can cause a practical desync.
kendoctor
Inserter
Inserter
Posts: 34
Joined: Wed Aug 05, 2020 6:43 pm
Contact:

Re: Give my understanding about desync problems.

Post by kendoctor »

Why I seperately reposted this content. I think, lots of new moders have the confusion about the desync problems. New does not mean has no any programming experience. Like me, I have engaged in programming at least 25 years. Even this, only depending on read offical doc, you can not fully understand facto modding. you need more expereiance, more testing ,more practicing, more thinking, more conclusion. That's it.

Offical gives little about demostration of whole architecture data exchange, no graphicial diagram which is direct vision for understanding.

Let me make it more simple. This is my deduced conclusion.
NOTE: facto based Game's tick. This is the first factor.In MP,
1. In every tick, all players or clients gameState data will be sent to server, server will verify the data is equal to the gameState which the server holds
(theroratically, send a hash string of gameState data will be enough, just for example)
2. Server also collecting clients actions and dispatching events to all clients, each event should be excuted in one tick. Event life cycle is very short, one tick.
3. If u know this basis, you will easily understanding how and what will cause desync problems.

1. Same tick, Same script, Same GameState at start, why GameState will be different after a few ticks passed by?
2. Simple, in script, Get a random value in defferent client to evaluate the script, that will lead to different GameState.
3. For example, random thing,
a. using a localized string for gameState related caculation. Different client has different string value.
b. why on_load change global data will cause desync. That because server's gameState will be not changed on_load. after your client changed global data which is loaded from save, will be sent to server to compare. it obvisouly causes desync. Also on_load's lifecycle is one tick.
c. If a bug triggered in your client, but game not crashed, that will possibly randomly change the gameState.
d. Network lag, sometime, you clients due to lag, you lost some of data sending from server. Even one event which will change gameState.
e.broken script evaluate different output
f. using coroutines span more than one tick calculation, espcially you want to reduce heavy codes in one tick based on elapsed time, not tick
Qon
Smart Inserter
Smart Inserter
Posts: 2164
Joined: Thu Mar 17, 2016 6:27 am
Contact:

Re: Give my understanding about desync problems.

Post by Qon »

kendoctor wrote: Wed Aug 12, 2020 3:19 pm 8. What will cause desyncs in this catchup period? Even excuting the same events?

9. Give an example: Player A, in on_event1 called random(), this changed gameState, but it did not changed sequences of events and amounts. At the end, when Player A and Player B exuting the same events in the same sequences, gameState will not be equal. random() has different seed in different client at different time.
kendoctor wrote: Wed Aug 12, 2020 3:37 pm Another mentioned here. ramdom() function ,if facto rewrites this method using game.tick time. that will be no problem for player A and player B
I just gave an example. random things always can he happened.
Wrong. If all clients have the same code and same state then calling math.random() doesn't desync your game. Both clients has executed random() the same amount of times at tick X, so they don't need the tick as seed to get the same sequence at the same ticks.

No, random things don't happen. The game is deterministic. math.random() is deterministic also.
kendoctor wrote: Wed Aug 12, 2020 11:46 pm 3. For example, random thing,
a. using a localized string for gameState related caculation. Different client has different string value.
d. Network lag, sometime, you clients due to lag, you lost some of data sending from server. Even one event which will change gameState.
Using output of string localization is not "a random thing that happens". It's something the modder does deliberately. Just don't do it.
If packets are lost then they will be re-sent to ensure the simulation keeps in sync. Otherwise the game would desync all the time.
My mods: Capsule Ammo | HandyHands - Automatic handcrafting | ChunkyChunks - Configurable Gridlines
Some other creations: Combinassembly Language GitHub w instructions and link to run it in your browser | 0~drain Laser
User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5211
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Give my understanding about desync problems.

Post by eradicator »

kendoctor wrote: Wed Aug 12, 2020 11:46 pm 1. In every tick, all players or clients gameState data will be sent to server, server will verify the data is equal to the gameState which the server holds
Wrong. This is where Factorio is fundamentally different from other games. All Instances - that is the players *and* the sever - simultaenously run a simulation. The severs only job is to distribute input actions (anything a player does) to all connected clients. As Factorio is fully deterministic every machine running the simulation must reach the same result if it starts at the same state and recieves the same input actions. Once per tick the gamestate is hased (crc32 as far as i know) and this hash is compared between all clients. Anyone who has a different hash than the sever is considered to be desynced.

This means that if no player does anything there is no data exchanged between server and clients except for the hash.
There are only very very few exceptions to this, such as LuaPlayer.request_translation().
kendoctor wrote: Wed Aug 12, 2020 11:46 pm a. using a localized string for gameState related caculation. Different client has different string value.
Some things - like localized strings - are not part of the gamestate and thus can not cause desyncs. A mod will only see the un-localized string (a nested lua table) unless it explicitly and deterministically requests a translation from another client. As a rule of thumb mods can not access data that is not already part of the gamestate (aka the engine makes it impossible to do so).
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.
kendoctor
Inserter
Inserter
Posts: 34
Joined: Wed Aug 05, 2020 6:43 pm
Contact:

Re: Give my understanding about desync problems.

Post by kendoctor »

You guys focus the details. That's not what I cares about so much.
I just tell a very simple basis, a very simple diagram, a very simple mechanism to clear when, where, how will cause desync problems . Even somewhere i guessed wrong.
Thanks all of your reply. :D :D :D :D :D :D 不要太杠精
Post Reply

Return to “Modding help”