How do I make this return a unique table for each player?

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.

2 Likes

Perfect! Thank you so much for your help :smiley: