I’m sorry but if you’re just gonna copy the code, I’m afraid you will not gain any knowledges from this.
I see that your ServerScriptService variable is not presented, which is why it gives that error. I encourage you to create a variable which gets this service and use it to refer ReplicaService.
This depends on DataStoreService itself, as every custom data storing modules, every module has the same limit of data you can set and call. Please read this APJ page for more info:
You don’t have to change much of your code, just change your template to your desired template.
Thank you for this guide.
Regarding ReplicaService you write: ‘Along with that, we wanna make sure to destroy their replica token when they leave the game…’
Perhaps I’m missing something but I can’t find where the replica token get destroyed when they leave?
This function will be called when a player leaves the game, inside it we destroy their replica by setting it to nil in the dictionary. That’s essentially how you remove something from a dictionary, which is assigning the key’s value to nil.
I get replication to work but when I try this on a live server with multiple people and leave and enter again I get the following message ‘Token for replica class “replica name here” was already created.’
The relevant code I’m using is this:
local UserID = player.UserId
PLAYER_REPLICA[player] = ReplicaService.NewReplica({
ClassToken = ReplicaService.NewClassToken("PlayerReplica_"..UserID),
Data = profile.Data,
Replication = player,
})
game:GetService("Players").PlayerRemoving:Connect(function(player)
local profile = Profiles[player]
if profile ~= nil then profile:Release() end
end)
profile:ListenToRelease(function()
Profiles[player] = nil
PLAYER_REPLICA[player] = nil
end)
The ListenToRelease is running. I’ve tested with a print statement.
Any help with this would be greatly appreciated.
Yes. And everything work just fine but only the first time.
The problem is when I leave and enter the server again (another player keep the server alive). It’s as if the Replica Token is not removed when the player disconnects so when ReplicaService tries to create the Token it is already there from previous connection. But the ListenToRelease triggers correctly when I disconnect so I’m quite puzzled why it’s not working.
I forgot to mention that you have to destroy the Replica by using a function, and not just setting it to nil through the table since we are only just clearing the replica from the list, but it is still there, so do me a favor.
Inside the Profile:ListenToRelease() function, after setting both player profile and Replica to nil, add a next line where you reference the player’s Replica and call :Destroy() on it, like so;
Thank you, but sadly that didn’t do the trick.
Here is my complete PlayerAdded.
local function PlayerAdded(player)
local profile = GameProfileStore:LoadProfileAsync(
"Player_" .. player.UserId,
"ForceLoad"
)
if profile ~= nil then
profile:AddUserId(player.UserId)
profile:ListenToRelease(function()
PLAYER_REPLICA[player]:Destroy()
PLAYER_REPLICA[player] = nil
Profiles[player] = nil
player:Kick()
end)
if player:IsDescendantOf(Players) then
Profiles[player] = profile
PLAYER_REPLICA[player] = ReplicaService.NewReplica({
ClassToken = ReplicaService.NewClassToken("PlayerReplica_"..player.UserId),
Data = profile.Data,
Replication = player,
})
else
profile:Release()
end
else
player:Kick('Could not load player data, please try again.')
end
end
I tried with only Destroy, It had the same result.
I get no errors in Studio and not the first time running on a live server.
The second time on a live server it says the token is already created and points to the line with:
ClassToken = ReplicaService.NewClassToken(“PlayerReplica_”…player.UserId)
It seems like the backends of ReplicaService are affecting it, to fix this, go to the ReplicaService module script, find the DestroyReplicaAndDescendantsRecursive function or line 373, and replace the whole function with this line:
local function DestroyReplicaAndDescendantsRecursive(replica, not_first_in_stack)
-- Scan children replicas:
for _, child in ipairs(replica.Children) do
DestroyReplicaAndDescendantsRecursive(child, true)
end
local id = replica.Id
-- Clear replica entry:
Replicas[id] = nil
-- Cleanup:
replica._maid:Cleanup()
-- Remove _creation_data entry:
replica._creation_data[tostring(id)] = nil
-- Clear from children table of top parent replica:
if not_first_in_stack ~= true then -- ehhhh... Yeah.
if replica.Parent ~= nil then
local children = replica.Parent.Children
table.remove(children, table.find(children, replica))
else
TopLevelReplicas[id] = nil
end
end
CreatedClassTokens[replica.Class] = nil
-- Swap metatables:
setmetatable(replica, LockReplicaMethods)
end
If so, you could just set the new value by telling the function that you’re going to set a new table for the Money key, and throw in the table for the Money key.