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)