Introduction
Hello so I will be showing how you will create a desync in Roblox that utilizies the hookmetamethod feature on most executors. This way is simple, but it works.
Defining Variables
Uh so we will be using localplayer and runservice so we will define those.
local runService = game:GetService("RunService")
local localPlayer = game:GetService("Players").LocalPlayer
Type.
Making our table for the desync
We want to know if its on or not so we will make an enabled one, we will also make something to store the location of the desync
local desyncT = {
enabled = true,
loc = CFrame.new()
}
runservice loop to update the desync position
runService.Heartbeat:Connect(function()
if desyncT.enabled and localPlayer.Character then
end
end)
we want to check if the desync is enabled or not, and if our localplayer character exists so yea. next we will be making the deeessssyyyynccc via the table.
runService.Heartbeat:Connect(function()
if desyncT.enabled and localPlayer.Character then
local character = localPlayer.Character
local root = character:FindFirstChild("HumanoidRootPart")
if root then
desyncT.loc = root.CFrame -- setting the real cframe to where we are
local newCframe = desyncT.loc -- storing the actual cframe
newCframe = newCframe * CFrame.new(0, -5, 0) -- moving our player down 5 studs (via the desync)
root.CFrame = newCframe -- setting our root cframe to the new cframe we made (no u will not be able to see this on ur client)
runService.RenderStepped:Wait() -- waiitiititt
root.CFrame = desyncT.loc -- reset our players cframe back to where we were beforehand
end
end
end)
ok now we make the hook….
local desynchook = nil
desynchook = hookmetamethod(game, "__index", newcclosure(function(self, key)
if desyncT.enabled and not checkcaller() and key == "CFrame" and localPlayer.Character and self == localPlayer.Character.HumanoidRootPart then
return desyncT.loc
end
return desynchook(self, key)
end))
incase u are wondering why we dont define the character or humanoidrootpart at top of code its because we die and it doesnt update unless we make another loop for that and theres just no need its such short code
combining it…
local runService = game:GetService("RunService")
local localPlayer = game:GetService("Players").LocalPlayer
local desyncT = {
enabled = true,
loc = CFrame.new()
}
runService.Heartbeat:Connect(function()
if desyncT.enabled and localPlayer.Character then
local character = localPlayer.Character
local root = character:FindFirstChild("HumanoidRootPart")
if root then
desyncT.loc = root.CFrame -- setting the real cframe to where we are
local newCframe = desyncT.loc -- storing the actual cframe
newCframe = newCframe * CFrame.new(0, -5, 0) -- moving our player down 5 studs (via the desync)
root.CFrame = newCframe -- setting our root cframe to the new cframe we made (no u will not be able to see this on ur client)
runService.RenderStepped:Wait() -- waiitiititt
root.CFrame = desyncT.loc -- reset our players cframe back to where we were beforehand
end
end
end)
local desynchook = nil
desynchook = hookmetamethod(game, "__index", newcclosure(function(self, key)
if desyncT.enabled and not checkcaller() and key == "CFrame" and localPlayer.Character and self == localPlayer.Character.HumanoidRootPart then
return desyncT.loc
end
return desynchook(self, key)
end))
— how much of this code is unnecessary? i do not know and dont wanna find out