Setting The Value Of A Variable Inside A Function Outside Of The Function

Hello, I have stumbled into an issue. Both of the methods below work, but they are just quite bad. To summarize what needs to happen, I have a function that is binded to the player joining. I have a server event which needs to change a value in the former function when fired. Is there a better way to accomplish this?

-- (Method 1) / This works, but I would like for it to be more efficient.
local playerBinder = {}

connectedPlayers.PlayerAdded:Connect(function(player)
	local playerIndex = table.insert(playerBinder, {player})
	
	while true do
		print(playerBinder[playerIndex][2]) -- constantly checks for a change; strenuous and unnecessary.
		wait(0.1)
	end
end)

characterRequest.OnServerEvent:Connect(function(player, value)
	for _, playerInstance in pairs(playerBinder) do
		if (playerInstance[1] == player) then
			playerInstance[2] = value
		end
	end
end)

-- (Method 2) / This works, but the server event function occurs for each instance of a player in the game which is just unnecessary.
connectedPlayers.PlayerAdded:Connect(function(thisPlayer)
	local value
	characterRequest.OnServerEvent:Connect(function(requestingPlayer, valueToChangeTo)
		if (requestingPlayer == thisPlayer) then -- I would like for this check to not even have to be made in this type of situation.
			value = valueToChangeTo
		end
	end)

	while true do
		print(value) -- this part is much better than method 1's.
		wait(0.1)
	end
end)

I’m still confused as to what is going on. Can you explain in a bit more detail? For me it looks like you you add a player to a table that keeps values, which you can simply just do this:

local Players = game:GetService("Players")

local SessionData = {}

Players.PlayerAdded:Connect(function(player: Player)
   if not SessionData[player] then
      SessionData[player] = {
         Value = ...,
      }
   end
end)

Players.PlayerRemoving:Connect(function(player)
   if SessionData[player] then
      SessionData[player] = nil -- Clean up
   end
end)

Sorry, I am not very good at explaining. Currently, I am using your method in my method 1 example. After a player joins, though, I also start a loop. I can change the values inside this loop using sessionData / playerBinder. However, then the loop has to check constantly for a change that is propagated through a ServerEvent that I respond to in another function already.

So, I tried rewriting this process in order to fix this inefficiency. Instead, I nested the characterRequest.OnServerEvent function inside the playerAdded function. This allows for it to have access to the variable directly. However, this server event isn’t localized to just this single player. So, whenever any player fires it, it happens for every playerAdded function instance. This is also bad because now I have to loop through the same data multiple times for every player that is in the game.

I cannot think of a solution that cures both of these problems.

Hmm I think I understand, though still not fully sure. Maybe using signals can help you, or even just using bindable? Maybe something like this though it’s very messy

local Players = game:GetService("Players")

local SessionData = {}

RemoveEvent.OnServerEvent:Connect(function(requestedPlayer: Player, valueToChange: any, valueOfChange: any)
   if not SessionData[player] then
      return
   end

   local PlayersSessionData = SessionData[player]
   if PlayersSessionData[valueToChange] then
      PlayersSessionData[valueToChange] = valueOfChange
      PlayersSessionData.ValueChanged.Event:Fire(valueToChange) -- Fire the event so it we can react to it's change
   end
end)

Players.PlayerAdded:Connect(function(player: Player)
   if not SessionData[player] then
      SessionData[player] = {
         Coins = 0,
         ValueChanged = Instance.new("Bindable")
      }
   end

   --> You will need to clean this connection
   SessionData[player].ValueChanged:Connect(function(valueThatChanged: any)
      print("Value Changed: ", valueThatChanged)
   end)
end)

Players.PlayerRemoving:Connect(function(player)
   if SessionData[player] then
      SessionData[player] = nil -- Clean up
   end
end)
1 Like

Thanks so much!! I got it working with your BindableEvent system

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.