Artic's Anti-Fly [R15 Characters] #2

Artic’s Anti-Fly [R15 Characters]

Hello everyone so as I said today before this thread today I was working on my Artic’s Anti-Fly Script. I tested it out and works pretty well I could say but I want everyone of you to review it again so let’s get started. Here is the main script. There is also some parts of code that I’ll use in next update. I also like to have scripts to look a little more complicated, so please don’t bully me for any of those reasons.

The download of model is here
Here are some snips of whole code…

Main Script:

--Put this script in ServerScriptService please okay?
local Module = require(script:FindFirstChild("Average"):WaitForChild("ModuleScript"))

local MaxY = 20 --IMPORTANT: Change this to maximum Y position of your game because it's always different!! (This should work on normal BasePlate)
local MaxBoolCaughts = 3 -- Chnage this to how many times you allow player to do mistake before adding a score to script counter
local MaxCounter = 4 -- Change this to maximum counter (caughts)

--Don't change these if you are not sure what you are doing
--Basically you have number from 0 to 1 higher to 1 number is player will have to be more correct 
local AvreageDifference = 0.60
local AverageBoolAndGameTime = 0.50

game.Players.PlayerAdded:Connect(function(Player)
    local ValueS = Instance.new("IntValue")
    local BoolCounter = Instance.new('IntValue')
    local BoolTurnedOFF = Instance.new('IntValue')
    local Yaxis = Instance.new("IntValue")
    local InGameTime = Instance.new('IntValue')
    local BoolValueS = Instance.new('BoolValue')

    ValueS.Parent = script
    ValueS.Name = Player.Name
    
    BoolValueS.Parent = ValueS
    BoolValueS.Name = "RestrictedArea"

    BoolCounter.Parent = BoolValueS
    BoolCounter.Name = "Time"
    
    BoolTurnedOFF.Parent = BoolValueS
    BoolTurnedOFF.Name = "TurnedOFF"

    InGameTime.Parent = BoolValueS
    InGameTime.Name = "TimeInGame"

    Yaxis.Parent = BoolValueS
    Yaxis.Name = "Y"

Player.CharacterAdded:Connect(function(Character)
   

local function WeldToHuman(A,B) 
    B.CFrame = A.CFrame
    local  Weld = Instance.new("Weld")
    Weld.Part0 = A
    Weld.C0 = A.CFrame:Inverse()
    Weld.Part1 = B
    Weld.C1 = B.CFrame:Inverse()
    Weld.Parent = A
    return Weld
end

WeldToHuman(Character:FindFirstChild("HumanoidRootPart"),Instance.new("Part",Player))
Player:WaitForChild("Part").Transparency = 1
Player:WaitForChild("Part").Locked = true

while true do
wait(1)

local function YaxisExists()
   if Character:FindFirstChild('HumanoidRootPart') ~= nil then
     local Yaxis = Character:FindFirstChild('HumanoidRootPart').Position.Y
     return Yaxis
   end
  return false
end

local success, message = pcall(YaxisExists)
Yaxis.Value = message
script:FindFirstChild("Average").Value = tonumber(Module.Average(0,0,0))

while BoolValueS.Value == false do
	script:FindFirstChild("Average").Value = tonumber(Module.Average(0,0,0))
	local success, message = pcall(YaxisExists)
	wait(1)
    InGameTime.Value = InGameTime.Value + 1
	BoolTurnedOFF.Value = BoolTurnedOFF.Value + 1  
	
	if success ~= false then
	 if message > MaxY then
		if BoolValueS.Value ~= true or BoolValueS.Value ~= false then		
		 BoolValueS.Value = true
	     if ValueS.Value > MaxCounter then
		  if BoolCounter.Value/InGameTime.Value < AverageBoolAndGameTime then
			local avg = script.Average.Value
			if avg/message < AvreageDifference then
			if script[Player.Name] ~= nil then
		       script[Player.Name]:Destroy()
		       warn('Player: '.. Player.Name .. ' was caught exploiting')
		       Player:Kick("We caught you exploiting")
		       --Add here things to happen once player is kicked or in PlayerRemoving function
		        end
		      end
		     end
		   end
	    end
     end
   end
end

while BoolValueS.Value == true do
	script:FindFirstChild("Average").Value = tonumber(Module.Average(0,0,0))
	local success, message = pcall(YaxisExists)
	wait(1)
	
    InGameTime.Value = InGameTime.Value + 1
	BoolCounter.Value = BoolCounter.Value + 1
    
  if BoolCounter.Value > MaxBoolCaughts then
	ValueS.Value = ValueS.Value + 1
	BoolCounter.Value = 0
	wait(1)
 end

    if message < MaxY then
	  BoolValueS.Value = false
    end
    
   if success ~= false then
	 if message > MaxY then
		if BoolValueS.Value ~= true or BoolValueS.Value ~= false then		
		 BoolValueS.Value = true
	     if ValueS.Value > MaxCounter then
		  if BoolCounter.Value/InGameTime.Value < AverageBoolAndGameTime then
			local avg = script.Average.Value
			if avg/message < AvreageDifference then
			  if script[Player.Name] ~= nil then
		       script[Player.Name]:Destroy()
		       warn('Player: '.. Player.Name .. ' was caught exploiting')
		       Player:Kick("We caught you exploiting")
		       --Add here things to happen once player is kicked or in PlayerRemoving function
			    end
		       end
		      end
		     end
	        end
           end
         end
        end
      end	
   end)
end)

ModuleScript to get all in game AverageValue of Y axises:

--Literally nothing to change here trust me :D
local module = {}

module.Average = function(a,b,c)
local Players = game.Players:GetChildren()

for i=1,#Players do
	if game.ServerScriptService:FindFirstChild("Artic's Anti-Fly"):FindFirstChild(tostring(Players[i])) ~= nil then
	  local Y = game.ServerScriptService:FindFirstChild("Artic's Anti-Fly"):FindFirstChild(tostring(Players[i])):FindFirstChild("RestrictedArea"):FindFirstChild("Y").Value
	  a = a + tonumber(Y)
	  c = #Players
	  end
   end
   return a/c
end

return module
PROOF that this Artic's Anti-Fly Script works

Make sure to turn on the Server Side view in Roblox Studio to see those values!
afcbf660109bf7dd5de4750ab4a06eab


IMPORTANT

Make sure to open Main Script and change settings only if you are using this model for your game. If you are using this on normal baseplate map this default settings in script should work.

I mean if there is anything that could of been better feel free to reply, I will appreciate help if there is any. Even thought if you want to test this anti fly script feel free to get it for free in roblox market, link is written above at the beggining and don’t forget to add script inside ServerScriptService. I hope you have an amazing day today! :herb:

4 Likes

Are you just checking the HumanoidRootPart’s position on the Y axis? You have to take into account that flinging can occur so you shouldn’t be so fast to kick players, it’d be a lot better to cache their location every few seconds and if you flag them for flying just teleport them to their previous location. There’s a lot of ways to bypass your script like just replacing the HumanoidRootPart or just flying below the detection level of the max Y axis. You can improve this checking more than just 1 axis and checking more than the HumanoidRootPart’s position but the best thing to do is research the actual methods exploiters use to achieve flying and target those.

Your documentation is not ideal, and as a result it makes me not want to read your code.
Examples include this: Basically you have number from 0 to 1 higher to 1 number is player will have to be more correct , which is hard to understand and does not provide an accurate idea of what the variable actually does. I know it’s stingy but I also think comments such as Literally nothing to change here trust me :D should really be more professional, whether it’s a casual project or not, documentation should serve to aid understanding of code and not act as a friendly chat. It is dissuading to a reader when they are met with unnecessary or vague comments.

1 Like

@metryy Yeah I am checking Y axis on the players and the MAX-Y axis which owner of the game has to set it by itself. I was also thinking about this solution by replcaing HumanoidRootPart so as you can see in code I wanted to add an Part in player in case if HumanoidRootPart won’t exist anymore. I am checking the avreage Y axis of all players in game as well of course.

@Shardwielder I know I am sorry about this. “Basically you have number from 0 to 1 higher to 1 number is player will have to be more correct” This was written at AvreageDifference and AverageBoolAndGameTime. AveraeDifference is average Y value of all players in game devided by player’s current Y axis. “Literally nothing to change here trust me :D” I am really sorry about that one. I will delete it in next update and document my script more professional. This text was written inside ModuleScript which returns average Y value of all players in game. I hope this makes more sense.

I would also like to provide one image I created just for you two so you could imagine more esaliy:

I would take a look from my perspective as an exploiter here. He won’t even know which anti exploit is using in server if any. He also won’t know what the max Y axis (which is set by owner) it’s an easy fix to this as a math.random function. I also created that exploiter would have to do that many mistakes so it will be caught as exploiting not as it was only an mistake bounce as in roblox many times happens. I hope this makes more sense for both of you :smiley: , have a nice day.

1 Like

This doesn’t seem like the best solution at all; what if you have one player climb a cliff while all the others are at sea level? The average is slightly above sea level, which causes the player who’s at the top of the cliff to be falsely flagged for flying. The player gets kicked, they leave a dislike and possibly a bad review in other areas (discord, group, etc.).

Instead of focusing on average position or if their Y axis goes too high, you should be checking for irregular movement, i.e. if humanoid.FloorMaterial is air (they’re falling or jumping) but their Y velocity isn’t decreasing/increasing as it should be.

2 Likes

Yeah I agree at this point but also owner could decide the MaxY for his own game let’s don’t forget about this. It will eventually lower the height difference at this point. I think I figured out something, next version is going to be a lot better. I didn’t know for FloorMaterial so yeah made me a little bit sad. Also velocity isn’t changing I agree. Have a nice day and thank you :smiley:

But my point still stands that using the average Y position of all the players is an awful method to check for flying as it’s a very easy way to trigger false positives. Checking Y position in general is bound to fail as Roblox physics aren’t the most reliable; someone’s going to get flung and end up being kicked for something that wasn’t even their fault.

What about if I add an counter for how long he has FloorMaterial as air and then when he get’s enough of caughts and if he has his FloorMaterial for let’s say for 30 seconds, can we count this as flying? And by that kick him from the game? At this point we can’t really say he wasn’t kicked by his fault right? Can flung be more long than 30 seconds, there is really no chance. In next script I am woking on decresing values that if they were in restricted area before and got some of values it’s going to start decresing if they are more time now in safe area.

If someone is falling for a long time, that’s also a bad check. You need to combine FloorMaterial checks with Velocity checks to make sure there’s as little false positives as possible