Hello, for my game I’m attempting to have a unique table on the server that is returned to the client upon request from a remote function . Right now, the issue is that my tables seem to all combine into one, so every player is receiving the same table when requested. I’ll attempt to post the relevant parts of my code bellow, let me know if you need anymore context
--server
game.Players.PlayerAdded:Connect(function(Player)
local PlayerInfo = Info:Clone()
PlayerInfo.Parent = Player
local PlayerData = Data:Clone()
PlayerData.Parent = Player
local PlayerData2 = Data2:Clone()
PlayerData2.Parent = Player
local ActiveCards = {}
for i=1,#PlayerData:GetChildren() do
PlayerData[i].Changed:Connect(function()
UpdateDeck (PlayerData, ActiveCards)
print("Did an update for "..PlayerData.Parent.Name)
end)
end
GetCards.OnServerInvoke = UpdateDeck
UpdateDeck (PlayerData, ActiveCards)
end
function UpdateDeck (PlayerData, ActiveCards)
table.clear(ActiveCards)
for i=1,#PlayerData:GetChildren() do
if PlayerData[i].Value ~= "empty" and tonumber(PlayerData[i].Value) > 0 then
--print("added "..PlayerData[i].Name)
table.insert(ActiveCards, tonumber(PlayerData[i].Name))
end
end
game.ReplicatedStorage.GetActiveCards.OnServerInvoke = function(_, ind)
return ActiveCards--[ind]
end
print("Updated deck "..#ActiveCards)
end
--client
local Deck = game.ReplicatedStorage.GetActiveCards:InvokeServer()
OnServerInvoke is an assignable callback. Like any other variable only the most recent assignment will be kept and the rest will be discarded. Here, OnServerInvoke is overwritten every time a new player joins to return said new player’s table, so other players will get that same data. Do note you have this same problem in UpdateDeck where it’s defining an OnServerInvoke every time its called.
If you want to create a new table for every player then divorce the assignment logic from PlayerAdded so that your PlayerAdded function is only creating the player’s card deck. Anything in that PlayerAdded function should only be initialising components specific to that player and other code should be placed outside of it such as at the top.
A typical scenario might look like this:
local Players = game:GetService("Players")
local RemoteFunction = game:GetService("ReplicatedStorage").RemoteFunction
local playerData = {}
local function getMyData(player)
return playerData[player.UserId]
end
local function playerAdded(player)
local myData = {}
playerData[player.UserId] = myData
end
local function playerRemoving(player)
playerData[player.UserId] = nil
end
RemoteFunction.OnServerInvoke = getMyData
Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
This should provide you a template or way of thinking in terms of how to structure your code.