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.