Page 1 of 1

Help fixing Mod for Multiplayer

Posted: Sun Mar 05, 2017 4:37 pm
by CobaltEcho
All/Factorian Modders,

I enjoy using the Mod Natural Tree Expansion as it allows trees to reproduce. It works great in Single Player but causes a Desync issue in multiplayer. I believe the issue has been identified but I know absolutely zero about programming. Any assistance would be greatly appreciated! I'll Link the mod and sources as a reply since I can't post URL's on the forum yet!

According to my research:
Try looking for local variables that are kept between ticks and/or initialized in places like on_load or other events.
- orzelek
The reason it desyncs in MP is because you're using local variables to store state data outside of functions.
- Rseding91

Re: Help fixing Mod for Multiplayer

Posted: Sun Mar 05, 2017 4:37 pm
by CobaltEcho

Re: Help fixing Mod for Multiplayer

Posted: Sun Mar 05, 2017 6:04 pm
by Klonan
First thing i notice is this:

Code: Select all

local shuffle_src = {}

for i = 1,freq do
	for j = 1,freq do
		shuffle_src[i * freq + j] = i * freq + j
	end
end

local shuffle = {}

while 0 < #shuffle_src do
	local p = math.random(1,#shuffle_src)
	table.insert(shuffle, shuffle_src[p])
	table.remove(shuffle_src, p)
end
Looks extremely suspicious,
Everytime the game will load, shuffle will be different

This initializes shuffle in a random way, I suggest initializing it a single time and storing it in global

Re: Help fixing Mod for Multiplayer

Posted: Sun Mar 05, 2017 6:57 pm
by Klonan
After some more investigation is seems like the issue stems from player_map,

Since its quite a small table, i suggest keeping player_map in global

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 3:27 pm
by CobaltEcho
Klonan,

I appreciate your reply! I have not done much programming, so please excuse any "newbie" errors. Also new to GitHub. I read what you said, did some research and made the following changes.

I removed the local tag from player_map, it now reads as:

Code: Select all

playermap_freq = 4
playermap = {}

function update_player_map(m, surface)
	mm = m % #shuffle + 1
	mx = shuffle[mm] % freq
	my = math.floor(shuffle[mm] / freq)
  	for chunk in surface.get_chunks() do
  		if fmod(chunk.x + mx, freq) == 0 and fmod(chunk.y + my, freq) == 0 and
  			0 < surface.count_entities_filtered{area = {{chunk.x * chunksize, chunk.y * chunksize}, {(chunk.x + 1) * chunksize, (chunk.y + 1) * chunksize}}, force = "player"} then
			px = math.floor(chunk.x / 4)
			py = math.floor(chunk.y / 4)
  			if playermap[py] == nil then
  				playermap[py] = {}
  			end
Still getting the Desync though. Should I remove all Local references?

https://github.com/CobaltEcho/Factorio- ... 503f4a1412

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 3:41 pm
by CobaltEcho
If there is a "How to code for idiots" guide, I would gladly read it! lol

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 4:37 pm
by daniel34
CobaltEcho wrote:I removed the local tag from player_map
What Klonan meant is to store it in the global table.

Use

Code: Select all

if not global.player_map then 
    global.player_map = {}
and change all other occurences of player_map to global.player_map.

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 5:32 pm
by CobaltEcho
Daniel34,

Thanks for the info. Should i also Change instances like the below? If I'm reading this correctly, its a differnt function:

Code: Select all

local function update_player_map(m, surface)
SHOULD NOT be changed to

Code: Select all

local function update_global.player_map(m, surface)

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 5:51 pm
by daniel34
CobaltEcho wrote:Thanks for the info. Should i also Change instances like the below? If I'm reading this correctly, its a differnt function:

Code: Select all

local function update_player_map(m, surface)
SHOULD NOT be changed to

Code: Select all

local function update_global.player_map(m, surface)
Correct, the function name should stay as it is, only inside the function you have to change it (the playermap[py] parts). I also noticed we used both player_map and playermap. It doesn't matter which one you use as long as you keep it consistent and use the same one everywhere (I suggest playermap as that is what the mod originally uses).

I just looked through control.lua, in the checkPlayerMap() function are 3 instances to replace, and in countPlayerMap() there is 1 (but again, not the function names themselves).
game.players[1].gui.left.trees.playermap has to stay as it is (no global).

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 6:44 pm
by CobaltEcho
Made the updates as you suggested, and it works great in single player.

However, when loaded onto a headless server, it seems to prevent players from loading onto the server. Well, it seems the server loads the map and doesn't respond at the same time. Quite Odd!

SOURCE: https://github.com/CobaltEcho/Factorio- ... e/for-0.14

Re: Help fixing Mod for Multiplayer

Posted: Mon Mar 06, 2017 7:15 pm
by daniel34
CobaltEcho wrote:Made the updates as you suggested, and it works great in single player.

However, when loaded onto a headless server, it seems to prevent players from loading onto the server. Well, it seems the server loads the map and doesn't respond at the same time. Quite Odd!

SOURCE: https://github.com/CobaltEcho/Factorio- ... e/for-0.14
I checked your github and the global.playermap looks correct.

The map loading issue looks like a network problem, I set up a multiplayer game on a new map with the github code (2 clients) and it worked without problems (I let it run a few minutes).

I then enabled the debug window in the config and started a new game, then it always instantly desynced. I changed the code to show the debug window for all players instead of just players[1], but that didn't help. I don't see any obvious errors there but I might further look into it if I have the time.

EDIT: I analyzed the desync report and found the cause, it was the totalgen variable that shows the number of added trees. When a new player joined it started to count from 0 although the server already had a higher number --> desync. Making it global fixed the issue.

I've attached my working control.lua. Changes made: totalgen is global now and the debug window shows on all clients if enabled.

Re: Help fixing Mod for Multiplayer

Posted: Tue Mar 07, 2017 11:00 pm
by CobaltEcho
Daniel34,

What are you looking for in the Desync report (or which file in the report are you viewing)? The mod worked for about 24hrs, then caused a desync when trying to connect. I'm not seeing anything relevant in the Desync Log file.

Once again I really appreciate your help on this.

*EDIT: This desync happened 24hrs or so after implementing the LUA file provided. It could be that there is another Mod causing a desync too.

Re: Help fixing Mod for Multiplayer

Posted: Wed Mar 08, 2017 12:57 am
by daniel34
I'm using a tool called Beyond Compare that will list differences between files.
If I open the reference and desynced level which I still have from the desync report for the debug mode desync and compare the two it looks like this:
factorio-beyond-compare.png
factorio-beyond-compare.png (46.06 KiB) Viewed 5345 times
In the screenshot you can see that the reference level says Added trees: 398 and the desynced level Added trees: 54. I then checked the control.lua of your mod and saw that it's the totalgen variable that stores that value and is different on client and server, therefore I made it global.

I think it's strange if the desync is related to the mod but only happened after 24 hours, since the mod essentially runs the same code over and over and a desync would have happened earlier, but one can't rule it out.

Re: Help fixing Mod for Multiplayer

Posted: Fri Mar 24, 2017 5:43 pm
by CobaltEcho
daniel34,

I just wanted to follow up and say that it wasn't this MOD that was causing the most recent issues, it was another we had installed. The code you posted previously works great! I was going to update the MOD on the mod site (with credit towards you), but with 0.15 coming out in a couple weeks it seems sort of silly to upload at this point. Thanks again!