Replica - Server to client state replication (Module)

“Replica” by loleris

(Successor module to ReplicaService)

[GitHub repo]

(WARNING: Full documentation is not done yet - Replica functionality is similar to ReplicaService, but there were changes to some member and method names. You can also find short API docs inside the Replica scripts!)

Read documentation here: (NOT FINISHED)
Replica wiki (Click me)

Get the module here:
Roblox library (Click me)

(If you make a tutorial for this module, please contact me and I might share the link here!)

:moneybag::moneybag::moneybag:
Consider donating R$ to the creator of ProfileStore (Click here) if you find this resource helpful!


Replica is a Roblox server to client state replication solution which lets the developer subscribe certain players to certain states.

Individual states in the Replica module are called “replicas”. Replicas can only be created and changed server-side, both server and client can connect clean-up tasks for the moment of replica destruction, state changes can trigger listeners on the client-side.

Changes from ReplicaService

Replica is a successor to ReplicaService - you will find that these modules are very similar, but Replica has much shorter member and method names, yield safety in signal listeners, luau types for autocompletion, Roblox streaming support with Replica:BindToInstance() and several minor performance improvements.

  • There is no longer a Replication argument in the Replica constructor - all new replicas are not replicated by default until Replica:Replicate() or Replica:Subscribe(player) are called or the new replica is parented to an already replicated replica.

  • The Parent argument in the Replica constructor has been removed - You will have to use Replica:SetParent() after creating a replica instead.

  • For listening to Replica destruction, instead of Replica:AddCleanupTask() you will now have to use Replica.Maid:Add() - these are functionally the same.

Basic example

Server-side

local Replica = require(game.ServerScriptService.ReplicaServer)

local replica = Replica.New({
    Token = Replica.Token("GlobalData"),
    Data = { -- Passed table reference will be used
        Score = 0,
        Nested = {
            Value = false,
        },
    },
})

replica:Replicate()

task.spawn(function()
    while true do
        replica:Set({"Score"}, replica.Data.Score + 100)
        task.wait(1)
    end
end)

replica:Set({"Nested", "Value"}, true)

Client-side

local Replica = require(game.ReplicatedStorage.ReplicaClient)

Replica.OnNew("GlobalData", function(replica)

    print(`Replica received client-side! Data:`, replica.Data)

    replica:OnSet({"Score"}, function(new_value, old_value)
        print(`Score has changed from {old_value} to {new_value}`)
    end)

end)

Replica.RequestData() -- Must be called once anywhere in game code client-side

Other resources:

Check out ProfileStore - DataStore wrapper for handling player data

17 Likes

Consider donating R$ to the creator of Replica if you find this resource helpful!

Your support helps me make more epic open source code :sunglasses: :+1:
Of course, Replica is completely free to use! :eyes:

2 Likes

Loleris classic, helping roblox be less garbage as usual!

But good question, when is roblox going to remake their engine? And maybe switch to a language that isnt older then most of its developers… twofold…

Or add basic features like actual decent godrays, functionality in their server to client communication so something like this wouldnt have to be created.

I mean there is literally modules for networking bro, NETWORKING… because firing 2 remote events at once is a little to hard for poor old buddy in the back.

Sorry for my rant. But im so glad you made this, replica service is already crazy useful but this?

I mean come on, its like you asked god for instructions on how to make this, its like serenity met with sigma and created Replica.

Looks good! :fire: It will be great to use Replica with ProfileStore.

Is there any particular reason why some signals were combined into the OnChange signal? It just seems a lot less convenient compared to ReplicaService.

Can’t wait for full documentation to come out. The instance binding seems pretty interesting

How could we use this with ProfileService? I already use ReplicaService + ProfileService and I was wondering how I could switch out ReplicaService for the new version!

It’s probably because having 5-20 events merged into one is better for memory and readability of the source code. If I misunderstood, please correct me!

Yeah there were changes to the built-in mutators, but you can still do everything you previously could. These changes were made based on my personal use of the module and also in favor of trying to decrease the memory footprint of Replica.

For example Replica:ArraySet() was just a simple set with one argument moved outside of “path”.

Hey, @loleris! Thank you so much for releasing this module. We really appreciate your work and effort. Looking at the source code for the module, it’s a huge improvement to the old ReplicaService, and I’m really happy for that.

So far it seems to be working just fine. However, I may ask if there’s a way to listen to the data changing on the server. I know it sounds redundant and probably not necessary, but I can assure you if it will have no impact on the performance, then it would be a huge “optional” addition as part of the Replica module.

image

my solutions are:

  1. Make a class / service that contains the replica itself in the server, but only opened itself with methods that also fires BindableEvent or signals to outside.
  2. Make your own dictionary implementation with signals (over engineered but it works for me)

kinda self explanatory from the title of post, there’s no methods for server to server.

Hey, thanks for the follow-up. I’ll fork my own signal then. Thanks so much.