Data storing/presenting using ProfileService and ReplicaService!

I’ll add this into the tutorial, thanks!

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

Do you have any errors that are in the output? I think you could instead setting it to nil, try only just destroying it.

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)

That’s strange.

How about be this? Assign this function to the replica:

PLAYER_REPLICA[player]:AddCleanupTask(function()
    print(PLAYER_REPLICA[player]:IsActive())
end)

Add this code line after you created the Replica under the Players.PlayerAdded scope.

When I run this in studio I get the result FALSE.
So that would mean that the Replica gets removed properly, right?

Yeah, so either you did something wrong or I’m wrong. I’m really unsure, but I’ll test this in studio soon.

1 Like

I FOUND A FIX!

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

Hope this works!

2 Likes

how would i set tables?

like, let’s say my profile looked like this:

Money = {
	Roya = 0	
},

how would I edit the roya value using the setdata function?

1 Like

So is Money inside another table like so?

local PlayerProfile = {
    Money = {
        Roya = 1
    },
    …
}

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.

2 Likes

Would there be a way to replicate the data to the client without using replica service? I’m kind of lazy to learn how to use replica service

Unfortunately, no.

The data provided by ProfileService are only server sided.

1 Like

Yes! Make the client request for full data from the server once the player joins, then replicate only the values that have changed.

4 Likes

Was there a function for this?

You should try to read the docs.

Apologies for the late response
I can’t seem to get it to work.

script.Parent.ClickDetector.MouseClick:Connect(function(plr)
	local plrd = dm:GetData(plr)
	dm:SetData(plr, "Money", {
		plrd.Money.Roya + 5
	})
end)

Hello! I just wanted to say that my module was in early stages when that reply is written and module has been changed a lot since then. Module is a lot more better now.

1 Like

Hello, i am having issues with ReplicaService, There’s no error in output but the script just doesn’t load past ReplicaOfClass Created. Here is the code

local function onActivate()
	print("a")
	ReplicaController.ReplicaOfClassCreated("ProfileToken_"..Player.UserId,function(replica)
		print("e")
		if replica.Data["Fruit"] == "None" then
			Eating = true
			Notifier.Send(Player, "Eating fruit in 3 seconds, cancel by deselecting...", Color3.fromRGB(72,193,50))
			wait(3)
			if Eating then
				Eating = false
				Notifier.Send(Player, "Eating Fruit...", Color3.fromRGB(72,193,50))
				-- Eat Fruit Logic
			end
		else
			Notifier.Send(Player, "You must get rid of your devil fruit before eating a new one.", Color3.fromRGB(165,36,38))
		end
	end)
end

----- Connections -----
Fruit.Equipped:Connect(onEquip)
Fruit.Unequipped:Connect(onUnequip)
Fruit.Activated:Connect(onActivate)

ReplicaController.RequestData()

I believe this should be outside of the scope of function in order to make this work.

Hey, I am also having issues with the ReplicaController. There is no error in console, it just won’t run anything within ReplicaOfClassCreated. print("hello") will not run, for example.

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ReplicaController = require(ReplicatedStorage:WaitForChild("ReplicaController"))

local player = game.Players.LocalPlayer
local PlayerGui = player.PlayerGui

local openBtn = PlayerGui:WaitForChild("RPGStats").openBtn
local frame = PlayerGui:WaitForChild("RPGStats").Frame

openBtn.MouseButton1Click:Connect(function()
	frame.Visible = not frame.Visible
end)

local function updateText(dict)
	for _, v in pairs(frame.DataFrame:GetChildren()) do
		for statName, _ in pairs(dict) do
			if v.Name == statName then
				v.Text = dict[statName].Value
			end
		end
	end
end


ReplicaController.ReplicaOfClassCreated("DataToken_" .. player.UserId, function(replica)
	print("hello")
	local dict = {
		["Level"] = replica.Data.RPGStats.Level,
		["Crystals"] = replica.Data.RPGStats.Crystals,
		["Gold"] = replica.Data.RPGStats.Gold,
		["XP"] = replica.Data.RPGStats.XP,
		["XPNeeded"] = replica.Data.RPGStats.XPNeeded
	}
	
	updateText(dict)
	
	replica:ListenToChange({"RPGStats"}, function(newVal)
		print("rpgstats changed")
		updateText(dict)
		
	end)
end)

ReplicaController.RequestData()