Status of local variables in scripts when functions are called near simultaneously for multiple players

1. What do you want to achieve?

I’m working on an events manager script that handles events produced as players step on different tiles.

2. What is the issue?

There are cases when the same events are fired near simultaneously which are then handled by functions that contain some amount of looping. I’m unsure what happens to the local variables in these functions in the said situations. For example, if there’s a variable i representing an array’s index, is it reset every time a loop is entered for another player even if it is still running for a prior player?

3. What solutions have you tried so far?

For data specific to each player, I have written a dictionary with the player objects as keys. Should I do the same for every local variable that can potentially be used by many players at about the same time? In the example above, should I ensure that each player gets his/her own unique i?

You can use ValueBases, like StringValue, ObjectValue and many others to control the value instead of making a variable.

1 Like

Thanks for replying! I’ve been making games for some time but only single-player games so basic multiplayer stuff like this I’m quite unsure of still. ValueBases then are standard practice in these cases?

Not necessarily. You could try an OOP approach, use attributes instead of ValueBases, or, well, maybe the issue simply isn’t as complex as you’d worry about it being. (code samples would be helpful here)

1 Like

Perhaps this would do:

local function testFloodFill( player )
	while true do		
		local pd = GameData.playersData[ player ]
		
		local i = pd.tilesToTest[ pd.currentTestI ].i
		local j = pd.tilesToTest[ pd.currentTestI ].j
			
		-- Test in four directions		
		if not testColorLine( player, i, j, -1, 0 ) then -- N
			undoTestFloodFill( player )
			return -- testFloodFill failed
		end
		if not testColorLine( player, i, j, 0, 1 ) then -- E
			undoTestFloodFill( player )
			return
		end
		if not testColorLine( player, i, j, 1, 0 ) then -- S
			undoTestFloodFill( player )
			return
		end
		if not testColorLine( player, i, j, 0, -1 ) then -- W
			undoTestFloodFill( player )
			return
		end
			
		if pd.currentTestI < #pd.tilesToTest then
			-- Proceed to next tile to be tested.
			pd.currentTestI += 1
		else
			-- testFloodFill succeeded: keep colors.
			return
		end
	end
end

If another player triggers this function even if a prior player is still running it, would the variables pd, i, and j be set with new values and mess things up for the first player? I can’t seem to think of a way to test this by myself in studio.

Local variables are local.

Which means, each time when you call testFloodFill(Player1), testFloodFill(Player2), or testFloodFill(Player1) again, any local variables declared inside the testFloodFill functions can be considered as starting from fresh. (Well, unless you’re taking values from elsewhere outside the function.)

To demonstrate with simplified code:

local function doSomething(plr: Player)
    print(var)
    local var = plr.Name -- local variable
end

doSomething(Player1) --> prints nil
doSomething(Player2) --> prints nil

What you’re fearing is probably the equivalent of this:

local var = nil -- variable outside the doSomething function
local function doSomething(plr: Player)
    print(var)
    var = plr.Name
end

doSomething(Player1) --> prints nil (first run)
doSomething(Player2) --> prints "Player1"

Or this:

local function doSomething(plr: Player)
    print(var)
    var = plr.Name -- global variable; not recommended due to being confusing and not as performant as using local variables
end

--// same results as previous example

In the case shown by your provided code, there shouldn’t be any concern about the variables being overwritten when the function’s loop is running for a specific player.

1 Like

There’s a feature under the Test tab that allows you to run in-studio tests that simulate multiple clients/players.

Thank you very much! This is reassuring.

1 Like

Yes, but the specific case I have in mind needs at least two players to move at the same time. Thanks again!.

1 Like