I didn’t know that. Nice to know.
Is there any built-in function which detects when a replica is added on the server?
Is there a way I can detect when key changes in a dictionary? Similar to how ListenToNewKey works but just whenever a key is changed or created.
How do I replicate and set values in a nested table? I want to replicate and set values for “Lock”.
local test_replica = ReplicaService.NewReplica({
ClassToken = ReplicaService.NewClassToken("TestReplica"),
Data = {
Chair = {
Basil = 0,
Farm = 2,
NestedTable = {
Lock = 3
}
}
},
Replication = "All",
})
Hi @loleris! I’ve been trying to add a listener to my replica on the client for changes made on the server, but I figured out that ListenToChange() only works with SetValue() and not with SetValues(). The only way I can listen to those changes now is by using ListenToRaw(), so I suppose this is not how it should work/it may be a bug.
how do I even make a listener for server… on your example it looks like I have to create 2 different Data I don’t understand.
This is a god sent module, sad I didn’t swap my games over to this quicker. Very simple module but also allows lots of customizations for very specific usecases
Im not sure, but what I did is require ReplicaServiceListeners instead ReplicaService
Why does it take 1 second to update the value? Is that normal? My game updates the data very frequently, I think it will cause some issues in some scenarios but I didn’t face it yet, I was using only profileservices no replica and there is no delay when updating the data
function DataService:SetData(player,path : string,newDataValue)
local PlayerProfile = self:GetData(player)
local DataReplica = Replicas[player]
if PlayerProfile and DataReplica then
--PlayerProfile.Data[dataToSet] = newDataValue
DataReplica:SetValue(path, newDataValue)
end
end
Yeah apparently requiring it just injects it Lol thank you.
Hello i dont understand this part of documentation very well
All .NewReplicaSignal
and .ReplicaOfClassCreated()
listeners should be connected before calling .RequestData()
! - refrain from connecting listeners afterwards!
If your game has local scripts that may run later during gameplay and they will need to interact with replicas, you should create a centralized module that connects Replica
creation listeners before .RequestData()
and provides those local scripts with the replica references they need.
How to creae this module to give replica reference to local script created at a later point ?
I dont really understand how to move the replicaofclasscreated around
also is it possible to listentochange of a replica without directly putting it in replicaofclasscreated?
thank you
You can send the reference to the replica returned from those listeners via BindableEvent
How do i extract data from the server to the client?
ReplicaOfClassCreated doesn’t signal when using it on a tool’s client script, any solutions so that i can send data to the client?
I have come to rely on ReplicaService for all of my recent projects because it simplifies the server-client communication for data needing to be synchronous.
One request I would like to make for this service is some getter functions. Typing out replica.Data["Some Data"]
can get tiresome afterwhile. I suggest adding functionality that allows you to do replica:get("Some Data")
instead. If you are trying to retrieve a tag instead of data, you could pass a parameter to this function, or you could make two separate functions: replica:getData(...)
and replica:getTag(...)
.
I imagine this change would be relatively easy to implement, and it would have no impact on existing code as this would be an additional interface.
On a complete separate note, I would like to post my solution here for client replica handling. I hope this helps others who have struggled trying to keep up with replicas created on the client.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ReplicaController = require(ReplicatedStorage.ReplicaController)
local ReplicaHandler = {
_replicas = {},
_events = {
ReplicaCreated = Instance.new("BindableEvent")
}
}
function ReplicaHandler:_init()
ReplicaController.NewReplicaSignal:Connect(function(replica)
if self._replicas[replica.Class] == nil then
self._replicas[replica.Class] = {}
end
self._replicas[replica.Class][replica.Id] = replica
self._events.ReplicaCreated:Fire(replica.Id)
replica:AddCleanupTask(function()
self._replicas[replica.Class][replica.Id] = nil
end)
end)
ReplicaController.RequestData()
end
function ReplicaHandler:onReplicaCreated(class, callback)
local replicas = self._replicas[class]
if replicas ~= nil then
for replicaId, replica in pairs(replicas) do
callback(replica)
end
end
return self._events.ReplicaCreated.Event:Connect(function(replicaId)
local replicas = self._replicas[class]
if replicas ~= nil then
callback(replicas[replicaId])
end
end)
end
function ReplicaHandler:waitForReplica(class)
local replica = nil
repeat
local replicas = self._replicas[class]
if replicas == nil then
task.wait()
continue
end
for replicaId, discoveredReplica in pairs(replicas) do
replica = discoveredReplica
break
end
until replica ~= nil
return replica
end
ReplicaHandler:_init()
return ReplicaHandler
Is it possible to stop listening to changes or new keys? I’d rather fully disconnect it rather than use an if statement to prevent it, if possible.
EDIT: After reading Evercyan’s post, I discovered that they can be disconnected like any other event. The documentation does describe it as a ScriptConnection, but that type is not a Roblox standard type and it is not documented.
I’ve recently come across this module, and I can’t see any major advantages of parenting over using a single Replica or creating separate ones besides maybe organization?
Not being able to yield in the listener functions is a major mistake. There is no intuitive understanding that this isn’t something you should do. I thought of the listeners like listeners through :Connect() on roblox events, where you can yield. Only after noticing the subtle inconsistencies of skipping remote event listeners did I discover this downfall. Please just make it automatically run the listeners on seperate threads so this isn’t an issue. I don’t see any reason why this is a problem, and if there is a good reason, it would be great if you could state it in the warning on your documentation site so people don’t take matters into their own hands and just change the module outright, which is what I’m doing.
replicated data doesnt seem to work in guis when the player resets
What I do is I have a “ReplicaManager” module, which essentially stores every Replica whichever side of the network you’re on in a table. This way your LocalScripts can still interact with Replicas.