Before you start, it is important you know about filtering enabled (FE) first. If you don’t know what it is please watch this video.
https://www.youtube.com/watch?v=_jTd4sfCh7Y
For all doccmentation and examples, please read the “docs” file inside the module.
What is ReplicationService?
ReplicationService is a module dedicated to fixing latency in filtering enabled (FE) experiences and improving user experience in general.
As an Australian, we usually average around 300 ms in American servers (which is most servers on ROBLOX) which can be very annoying in parts that require action from the user (such as in survival, building or fps games).
Before filtering enabled, latency usually wasn’t a problem as something called “replication” would bassically replicate a state of an instance in a client to the server.
So no matter how laggy you were, you still always had an enjoyable and satisfying experience.
Unfortunately, filtering enabled pratically removed the entire replication system, leaving us with only remote events and remote functions.
Sadly, most developers still cant fully grasp filtering enabled properly, resulting in them simply directly wiring a remote event/function which can be a HORRIBLE thing for users that don’t have top tier internet or latency, such as me which can make a mechanic very unsatisfying or outright unplayable.
Now, imagine if you were able to use BasePart:SetNetworkOwnership() on practically anything?
ReplicationService absolutely does it all! Plus, it comes included with many many more features to make the experience as fast and secure as possible such
as being able to script your own replication filter and put replication fully in your control!
ReplicationService is also very easy to learn and use, and lightweight as well!
With this module, it brings back replication and enhances the experience while playing with other clients.
Here is how you can set up ReplicationService:
1: Put the module in ReplicatedStorage
2: Make sure RejectCharacterDeletions is Enabled, this will make sure ReplicationService has full replication control.
game > workspace > RejectCharacterDeletions > Enabled
3: Make sure HTTPService is enabled, this is so ReplicationService will have access to the latest properties from: https://anaminus.github.io/rbx/json/api/latest.json
You can enable it in an unpublished game by copying and pasting this code into the command bar.
game:GetService("HttpService").HttpEnabled = true
With that, you should be done!
Demonstrations
With ReplicationService, I can create a Replicator
instance and choose a client, instance, and property.
This is before using ReplicationService:
Now with the Replicator instance I created, I can make the Color
property on a BasePart
replicate from the client to the server, its so cool and satisfying!
local ReplicationService = require(game:GetService("ReplicatedStorage"):WaitForChild("ReplicationService"))
local Replicator = ReplicationService:ReplicatePropertyFromClient(workspace.Part, "Color", game.Players:GetChildren()[1])
Replicator:Run()
This is after using ReplicationService:
Here is a really REALLY important feature that also comes with ReplicationService…
ReplicationService supports a feature called “Secure Replicators”!
With this, you can code a custom filter for a replicator! This allows for extremely secure replication, for example:
The client has only unlocked 3 Materials which are Wood, Plastic and Grass. But the client is trying to change the material of a placed part to Metal which has not been unlocked, so deny the replication request as it is not valid.
--[[
LibraryTemplate.lua
This template lets you create your own security library for safer replication.
[ TUTORIAL ]
On every single client to server update, .OnReplicationUpdate will be fired with these values given.
client: The player that the data is replicating from
instance: The instance that is being handled by the client
propertyname: The name of the property that is being replicated
propertyvalue: The replicated value of the property from the client
replicator: The replicator instance that is handling the replication
With all this data, you can write a script that "filters" the replication inside the .OnReplicationUpdate function.
At the end, you return your status of your check which looks like this:
return true, propertyvalue
These are what the values mean IN ORDER.
proceed: If this is set to false, it will skip the replication and not proceed with replicating the object.
propertyvalue: If you have modified/editted the replicated value, you can put in your own custom value which will be replicated instead.
]]
local SecurityLibrary = {}
function SecurityLibrary.OnReplicationUpdate(client, instance, propertyname, propertyvalue, replicator)
local unlockedMaterials = client:WaitForChild("OwnedMaterials") -- A folder inside the Player istance that contains the names of Materials that are owned.
if unlockedMaterials:FindFirstChild(propertyvalue.Name) then
return true, propertyvalue -- The client owns the material, proceed with the replication.
else
return false, propertyvalue -- The client does NOT own the material, don't replicate.
end
end
return SecurityLibrary
All doccumentation about security libraries and examples can be found inside the actual module itself. Here are a few examples of how to create a secure replicator:
1: Create the secure replicator from source.
local ReplicationService = require(game:GetService("ReplicatedStorage"):WaitForChild("ReplicationService"))
local SecureReplicator = ReplicationService:ReplicatePropertyFromClientWithSecurity(workspace.Part, "Color", game.Players:GetChildren()[1], "ColorExample")
-- The security library we are using is ColorExample, i'll touch in a bit how to install security libraries.
SecureReplicator:Run()
2: Upgrade a regular replicator to a secure version.
local ReplicationService = require(game:GetService("ReplicatedStorage"):WaitForChild("ReplicationService"))
local Replicator = ReplicationService:ReplicatePropertyFromClient(workspace.Part, "Color", game.Players:GetChildren()[1])
Replicator:Run()
wait(5) -- Have the replicator be completely unfiltered for 5 seconds.
Replicator:SwitchToSecure("ColorExample")
-- SwitchToSecure() should only be used in a case where the replicator was originally specified to be a non secure version and you want to upgrade it.
-- Else, you should use the example above.
This is a pretty powerful module in my opinion, plus it makes gameplay THOUSANDS of times better and satisfying with the instant snappy and latency free response that comes with client to server replication.
For example, this gun made by @Rufus14 has had its latency of moving the gun around COMPLETELY removed and results in a satisfying experience.
This module is also being used and featured in a game called Space Wars!
Currently known issues that will be patched soon:
- Localscripts as of now currently don’t interact well with ReplicationService and is pretty buggy when having a property of it replicated.
- Unanchored parts currently have buggy behaviour due to network ownership conflict
- As of now, descendants of a replicated object will not have any server replication updates
So, what are you waiting for?
It’s time to stop having developers directly wire precise mechanics that require user interaction to a remote event constantly, start using ReplicationService now!
Package (constantly updated)