Replicate your states with ReplicaService! (Networking system)

I think it would be worth adding :GetReplicas() as a supported function to ReplicaService and potentially ReplicaController, although the latter I’m not sure about. I think the use case is narrow but important.

When trying to find data leaks, being able to inspect what Replicas are still active is really useful. It’s easy enough to think we’ve cleaned up objects or otherwise but it’s helpful nonetheless to actually inspect and verify cleanup methods work.

I wrote this inspection function:

local function displayParties()
	local PartyHandler = Store:GetPartyHandler()
	local parties = PartyHandler:GetParties()
	print("--\\ All Parties //--")
	for _,party in pairs(parties) do
		party:Identify()
	end
	print("_Inspecting Replicas_")
	for _,replica in pairs(ReplicaService._replicas) do
		if replica.Class == CU.ReplicaTokens.Party.Party then
			print(replica:Identify())
		end
	end
	print("----- Complete -----")
end

To ensure all the data from parties was being adequately wiped. It’s obviously not recommended procedure to inspect a declared private variable. Given this is only for debugging, I understand it might be better to not give users access through an API as it might wrongly suggest they should use this to edit Replicas.

Is there a way to get if a replica by a name already exists on the server, i have a replica used for a tycoon, and a replica is created at tycoon creation, stuck between having to delete and recreate it each time to tycoon is remade (each rebirth), or try and find old and then continue using that one

With profile service, is it customary to utilize one replica for each player profile (as demonstrated in the example), multiple non nested replicas (inventory data, other table data), or are multiple nested replicas to reconstruct a player profile typically used?

1 Like

Question Loleris if you don’t mind. I am currently having an issue with my datastore, I call datatable very often to set my player’s kills, deaths and gold, but sometimes it does not update at all when using setvalue with replicaservice and sometimes it does, but never yields any errors whatsoever. This would be a big help to me if you could give me any insight in the right direction, and I can provide images or examples of what is going on if need be.

How can I check when a replica is updated? ive tried ListenToChange but cant seem to get it working, my data is nested example:

['Stats'] = {
  test = 0,
  inventory = {},
}

how can i check when stats / inventory is changed?

-- Server
Data.Stats.test += 1
.Replica:SetValue({"Stats"}, Data.Stats)
-- Client
replica:ListenToChange({"Stats"}, function(new_value, old_value)
print(new_value) -- { test = 1, inventory = {} }
end)
1 Like

hi, sorry for my lack of knowledge of datastores. i am trying to get player to access data from the client but I don’t know how am I supposed to… is it even possible?

That’s… sort of the main purpose of this resource. It makes getting server states from the client very easy. A ‘state’ could also mean the player’s data! You can find more information on the resource for ProfileService.

Is there a way I could use this as a replacement for remote functions?

One of the convenience features is a wrapper for RemoteEvents (not RemoteFunctions but you could just use RemoteEvents two ways)

image

image

image

image

image

so I can use these functions to return values?

Sorry to revive this topic after a long time. But I’ve recently tried to start using this module, but I stumbled uppon a problem.

When trying to use one of the array setter functions, it raises an error on the Replica Listener Module, something related to the replica._raw_listeners not existing.

Exception:

Replica Listener Section:

My code ( Server Side ):
Creation of the Replica
image

Error line
image

Some additional informations that may help:
I got the module some time ago, so idk if it auto updates or smt
I don’t know much about the module, so I may forgot to set something on the replica.
I am able to retrieve the replica from client, but I didn’t connect any listeners that tracks changes on the replica. Only a NewReplica Signal that inserts the replica on a module script:
image

Is it only me who experiences this? When a user resets, it doesn’t fire anything… how am I meant to know when they have died and reset all their data (I’m using ProfileService to add their points/money to UI) without listening for Humanoid.Died??

Basically what i would do is listen for when the health is less then or equal to 0 (bascially checking for if the player resets, don’t quote me)
then you would update the thing you need to update

---> Random Function to updaed the player's UI (example)
local function UpdateUI(player: Player)
    --- ....
end


humanoid.HealthChanged:Connect(function(health)
	if health <= 0 then
		
		print(player.Name .. " reset their character.")
		UpdateUI(player)
	end
end)

I was having the same issue as other developers, this worked for me, I suffered 4 hours for nothing, I started hating replicaservice :sob:

Here’s the fix that worked better for me just in case:

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, nil) -- Prevent class lock if the player rejoins
end
``

Hello, I’ve got a question. Would using ReplicaService be optimized for handling enemies? Basically, when a new enemy is created, it will create a new Replica object along with its data such as Speed, Health, etc… And these will be listened to the client alongside the server as par usual. My only commotion is that whether it’d be stable in handling a huge amount of enemies at once. For instance, a single round with over 450+ entities; resulting in THAT many replicas at once. But of course, they’ll be destroyed later with replica:Destroy().

Tldr; Can ReplicaService be used as an alternative to handling enemies over remote events? (i.e: sending CreateEnemy event to all clients to create enemy + fire UpdateEnemy event every 10th heartbeat on the server to update enemy positions)

im having this same problem where ArrayInsert inserts into both the original array and the replica array
it’s only ArrayInsert as well, ArrayRemove works as expected

im not entirely sure on how to fix this.
i think im forced to remove my own table.insert

Am I the only one here that gets this error?

[ReplicaController]: Initial data received  -  Client - ReplicaController:974
ServerScriptService.Lib.ReplicaService:410: attempt to index number with 'Type'  -  Server - ReplicaService:410
Stack Begin  -  Studio
Script 'ServerScriptService.Lib.ReplicaService', Line 410 - function SetValue  -  Studio - ReplicaService:410
Script 'ServerScriptService.Match', Line 53  -  Studio - Match:53
Stack End  -  Studio

When it says that ReplicaController.RequestData() should only be called once in the entire codebase, does that mean that it should only be called once in only 1 LocalScript and no other LocalScripts or is that not the case?

Once in 1 local script.

characterlengthththdjsnsn