How to use the Simulation Replication method

French version: https://devforum.roblox.com/t/comment-utiliser-la-methode-simulation-replication-dans-un-jeu/549373

Previous tutorial: How to reduce latency in-game

In my previous tutorial, I explained how to reduce latency in a game, how it was important to avoid
often replication and overload the server.

This method is called Simulation Replication or “sim rep”, it’s about doing simulation work on all clients, for exemple simulate a visual with tweening, as if it was done on the server without it seeing anything, in order to minimize data exchange between server and clients et avoid latency problems.

This tutorial is kind-of like a second part from the previous tutorial, with better exemple and more coding.

  • Exemple 1: An explosion
    Let’s say I want to create a custom explosion with 3D objects which happens at my cursor when I click.

I create a localscript in the StarterPlayerScripts under StarterPlayer which I name ExplosionLocal and insert the following code:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ExplosionEvent = ReplicatedStorage.ExplosionEvent

local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()

--[[
	This function will create the visual effect of the explosion when called,
	it's important to make this a function because we will call it twice in this script
]]
local function Explosion(Position)
	--[[
		You can create the visuals for the explosion here, you will only need the visual, no need to detect enemies or do damage
	]]
end

--[[
	This event fires when the left mouse button is clicked,
	Mouse.Hit.Position refers to the position of the mouse in the 3D environnement, we take its Position since it's a CFrame to start with and
	we only need the XYZ coordinates
]]
Mouse.Button1Down:Connect(function()
	local Position = Mouse.Hit.Position
	Explosion(Position)
	ExplosionEvent:FireServer(Position)
end)


--[[ 
	This code runs when the RemoteEvent is fired from the server through the FireAllClients method which mean ALL the clients will
	simultenaously run this chunk of code
	We verify the OriginalPlayer's Name and compare it to Player's Name and create the explosion only if the names aren't the same
	to not create the explosion twice
	PS: When I say "simultenaously, it's not exactly true because every players internet connection is different
]]
ExplosionEvent.OnClientEvent:Connect(function(OriginalPlayer, Position)
	if OriginalPlayer.Name ~= Player.Name then
		Explosion(Position)
	end
end)

Then I insert a script in ServerScriptService and I insert the following code:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ExplosionEvent = ReplicatedStorage.ExplosionEvent

local EXPLOSION_RADIUS = 5
local EXPLOSION_DAMAGE = 20


--[[
	This chunk of code runs when the RemoteEvent ExplosionEvent is called with the FireServer method from a client,
	we first use FireAllClients to make all the clients run code on their side then we detect the players within explopsion radius and deal damage,
	with the one making the explosion being excluded
]]
ExplosionEvent.OnServerEvent:Connect(function(Player, Position)
	ExplosionEvent:FireAllClients(Player, Position)
	
	local PlayerList = Players:GetPlayers()
	for i = 1, #PlayerList do
		local TargetPlayer = PlayerList[i]
		if TargetPlayer ~= Player then
			local TargetCharacter = TargetPlayer.Character
			if TargetCharacter then
				local Humanoid = TargetCharacter:FindFirstChild("Humanoid")
				if Humanoid then
					if TargetPlayer:DistanceFromCharacter(Position) <= EXPLOSION_RADIUS then
						Humanoid:TakeDamage(EXPLOSION_DAMAGE)
					end
				end
			end
		end
	end
end)

Read the code with the comments, I will make more exemple another time.

21 Likes

I’ve done something similar to this, however, when the server is under heavy load, there’s a lot of input lag. How would I fix this?

You should do all the visuals on the client, even if they’re going to be done on the server for everyone else.

Example: Firing a gun causes a raybeam to be visualised and replicated back down to every client

Instead of replicating it to the server, then rendering, you should render it on the sender’s client before you send it to everyone else. This will remove all the input lag.

1 Like

How do you know the game causes the latency and not the players’ ping is there any way to check this?

The server will start to feel laggy the more players there are in a server and all the players in that server will feel it.