How do I make a safe point where you cannot get killed?

How do I make a safe point where you cannot get killed by a player or npc? I have little scripting skills and can’t find tutorials that will help me understand.

Greatly appreciated for help!

3 Likes
local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(Player)
	
	local Safe = Instance.new("BoolValue")
	Safe.Value = false
	
	Player.CharacterAdded:Connect(function(character)
		
		while table.find(character["RightFoot"]:GetTouchingParts(),"Safezone") and not Safe.Value do
			Safe.Value = true
			task.wait()
		end
		
		while not table.find(character["RightFoot"]:GetTouchingParts(),"Safezone") and not Safe.Value do
			Safe.Value = false
			task.wait()
		end		
	end)

end)

Check if Safe is true when they are taking damage

3 Likes

Do I put this script in a part?

1 Like

Yeah or you could put it in Serverscriptservice

2 Likes

For security purposes, you should be dealing out all the damage from the server. Whenever a player successfully attacks another player, fire a remote to the server from their client containing the player they hit.

Then the server can verify that this hit is indeed valid. First check to see if the player is not in a safe zone, a simple if statement can do the trick here. Then you can check other things such as distance from the player being attacked and whether or not the player attacking is on cooldown.

Remember this does not take into account client latency. If the player attacks another player the remote fires, by the time it reaches the server the player hit could have moved to another location! Meaning, they might be too far away for the hit to be valid.

To mitigate this issue, you can store the locations of the players on the server in a table. Then you can check the location the player was in when the remote was sent and confirm it’s validity that way. Just give the player attacking some leeway, perhaps 200-300 ms, if within that time interval you find the hit would have been valid then deal the damage.

Of course I’m sure there are more things you can think of to make this even more secure as it can vary game-to-game. These are just some basics to get you started.

3 Likes

This won’t work for R6 characters.

2 Likes

He can change it to Right Leg then

1 Like

Then it wouldn’t work for R15 characters.

2 Likes

He could just do both depending on the rig type

2 Likes

How do I do that? (Do I put left and right foot? [im dumb])

1 Like
game:GetService("Players").PlayerAdded:Connect(function(Player)
    if Player.Character.RigType == "R6" then
        game:GetService("RunService").RenderStepped:Connect(function()
            Safe.Value = table.find(Player.Character["Right Leg"]:GetTouchingParts(),"Safezone")
        end)
    else
        game:GetService("RunService").RenderStepped:Connect(function()
            Safe.Value = table.find(Player.Character.RightFoot:GetTouchingParts(),"Safezone")
        end)
    end
end)
2 Likes
local players = game:GetService("Players")
local part = workspace:WaitForChild("Part")
local region = Region3.new(part.Position - part.Size/2, part.Position + part.Size/2)
local tableIntersect = {}

task.spawn(function()
	while task.wait() do
		local touchingParts = workspace:FindPartsInRegion3(region, part)
		for _, player in pairs(players:GetPlayers()) do
			if workspace:FindFirstChild(player.Name) then
				local character = workspace:FindFirstChild(player.Name)
				local charParts = character:GetChildren()
				for i, v in pairs(charParts) do
					if v:IsA("Part") or v:IsA("MeshPart") then
						for index, value in pairs(touchingParts) do
							if value == v then
								table.insert(tableIntersect, v)
							end
						end
					end
				end
				if #tableIntersect >= 1 then
					if not character:FindFirstChild("ForceField") then
						local forceField = Instance.new("ForceField")
						forceField.Parent = character
					end
				else
					if character:FindFirstChild("ForceField") then
						character:FindFirstChild("ForceField"):Destroy()
					end
				end
			end
		end
		tableIntersect = {}
	end
end)

I think this is a better implementation, it works for all rig types & for all parts of the character.

Demonstration:
https://gyazo.com/2b2e8a2651731169ac9bcdf6444d6921

It’s a server script too so everything is reflected across the server to all clients.

2 Likes

Thank you for the script but how do I know if it works based on the video? (I am on mob rn)

1 Like

It showcases how it works, when you’re inside the particular part (which acts as a safe-zone) you get a ForceField which makes you invincible, then when you leave the part the ForceField is removed meaning that you will continue to take damage like normal.

2 Likes

Damage in local scripts doesn’t work anyways. May lower their health bar on the exploiter side. But the server and other clients still see the other player as full health. All touch/damage events should also be server-side rather than the client invoking the server. Otherwise, it is impossible to 100% prove. It can check the distance but nothing stops the exploiter from teleporting and firing the event.

1 Like

Changes to health do reflect to the local client when they are performed within local scripts, but to that particular client only.

1 Like

The client has to have some involvement or how else will the server know a player has initiated an attack. Yes, a player can teleport to every player in the server firing remotes as they go, but that would be fairly easy to account for if you’re storing the player’s locations server-side as I suggested.

1 Like

In your server-side damage script. Rather than just damaging add this. Put table at the very top. Quickly scripted this so might throw an error, debug it if you can. If not just reply with the error and the line where it occurs. I’ll attempt to fix it.

PS. Read Instructions in the table, and the two big thick note lines on top and bottom of the script.

Also, I left notes if you wanna read them to understand to help you learn, rather than just me giving code.

------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
---------------------Insert all of this in script, but outside of damage event/function---------------------
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------

local safeZones = {
--Set zone boundarie values from lowest to highest.
	zone1 = {
		XBoundaries = {-25,25},--XMin, XMax
		YBoundaries = {-math.huge, math.huge},--Covers complete Y axis. Change if you want. YMin,YMax
		ZBoundaries = {-25,25}--ZMin, ZMax
	}
	
} 

function checkSafeZones(player)
-----------------------------Is in bound local function, helps prevent long/nested if statement
	local function inBounds(value, boundariesTable)
		
		local valuemin, valuemax = table.unpack(boundariesTable)--Unpacking Current Zone Boudnaries
		
		if value >= valuemin and value <= valuemax then
			return true
		else
			return false
		end
	end
-----------------------------Checking bounds
	local Root = player.Character:FindFirstChild("HumanoidRootPart")
	if Root then--Make sure player has HumanoidRootPart to check position
		local PlayerPosition = Root.Position--Getting position
		local PlayerX, PlayerY, PlayerZ = PlayerPosition.X, PlayerPosition.Y, PlayerPosition.Z--Unpacking position
-----------------------------Running through all zones to check if player is in one
		for i,v in pairs(safeZones) do--Loops thru all zones
			local XBoundaries = v.XBoundaries
			local YBoundaries = v.YBoundaries
			local ZBoundaries = v.ZBoundaries
			
			if inBounds(PlayerX, XBoundaries) and inBounds(PlayerY, YBoundaries) and inBounds(PlayerZ, ZBoundaries) then--Checking if in the current zone
				return true--Is in zone retrun true and stop the function
			end
			
		end
-----------------------------Not in bounds
		return false--Returning false, if it reaches this point it means player isn't in safezone
	end
end


------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------
---------------------------------Insert this in damage function/event area----------------------------------
------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------

if not checkSafeZones(player) then--checking if in safezone, returning false. checking for not=false
	takeDamage(player)--Set to your damage function or your damage code
end 
	
------------------------------------------------------------------------------------------------------------

--Written by NovusDev
3 Likes

That is what I’m attempting to say. Client damage scripts are as useless as trying to eat soup with a fork.

1 Like

Yes it does have to do some handling, like executing the player making the action. But since it is so little involvement, it’s considered basicly doing nothing, 99% of it should be handle serverSide. The client should just let the server know the player clicked his mouse basicly.

Doing this makes your game very much less exploitable, which in terms makes your game more enjoyable and better.

Gun example - client shoot gun and fires remote event. Remote event to stop the local script from being halted.
Server side makes bullet(ray cast), and part that follows raycast(visual effects or if you want, add to bullet travel for realism.
Agame debris for bullet part, check raycast target, or touch event if you want bullet travel delay to be realistic.
After game debris time disconnect the touch event.

Sword Example - Player swing sword does animation or let server with RemoteEvent handle it and FiresRemoteEvent.
RemoteEvent look for swing animation in player. If it’s playing touchEvent, and animationStopped event.
If touched once again check for swinging animation(doesn’t hurt to double check cause lua speed with server is meh.), make sure player waited the delay(prevent animation spamming exploit) and then damage
AnimationStopped. Disconnect both the touch and animationstopped event.

Or for both depending on amount of players, npcs, or things happening to lower server hit
You can only create the bullet for the gun example. with server remoteEvents.
But have a CharacterAdded function
If one of their character Parts is touched checked the touched item. Run all the checks to see if it’s a bullet or a sword, and the attacker has waited the delay, and with hitDebounce.
Then damage

1 Like