Is this an exploit or is this a performance issue with a user?

Over the last week or so I have been getting complaints from other players in the hockey community about a specific user “using an exploit” to get unfair control over the puck. They are sending me videos like this…

https://cdn.medal.tv/source/5630274/1590107464-roblox20200521192958.mp4

https://cdn.medal.tv/5630274/share-24761843.mp4

https://cdn.medal.tv/5630274/share-24761463.mp4

https://cdn.medal.tv/5630274/share-24304494.mp4

As you can see there is major differences in puck control leaving some users frustrated and confused. I believe this is either some performance issue or an exploit he is using to cheat.

I talked to the user myself and he has denied all allegations. He explained to me that he plays on a “Macbook Air” which he thinks is causing the lag or latency that makes it seem like the puck is sticking on his blade better. He also told me he doesn’t think you can exploit on a Mac. Not sure if this is true or not.

I also talked to other players on his team and they explained to me that he isn’t the best programmer and they think he isn’t good enough to program his own exploits.

How the puck works is that it has an ownership script that detects the magnitude of all the players hockey sticks (specifically the blade) and if the puck is less than 5 studs away from the blade it will give that player ownership of the puck. Other than that, everything is just raw Roblox physics except the poke checks and slap shots which use Legacy Body Movers to move the puck.

function FindNearestPlayer()	
    	local nearestPlayer = nil		
    	local dist = math.huge		
    	for i,v in pairs(game.Players:GetPlayers()) do
    		if v.Character and script.Parent.LastToHoldPuck.Value == "" then
    			local hockeystick = v.Character:FindFirstChild("HockeyStick")
    			if hockeystick ~= nil then
    				local magnitude = (hockeystick.Blade.Position - script.Parent.Position).Magnitude
    				if magnitude < 5 and script.Parent.Anchored == false then
    					if magnitude < dist  then	
    						dist = magnitude	
    						nearestPlayer = v.Name
    						script.Parent:SetNetworkOwner(v)
    					end
    				end
    			end
    		end
    	end
    end

    game:GetService('RunService').Stepped:Connect(function()
    	FindNearestPlayer()	
    end)

I want to know if you think this is a performance issue or an exploit?

We have exploiters all the time, but we have never had an exploiter give themselves an advantage gameplay wise before. I am not even sure if programming better puck control is even possible? If you know a way to do this, let me know.

He could have used a weld, but it would be a lot more obvious if he/she welded the puck onto the blade, or something like that. As you can see in the videos the puck moves forehand to backhand a lot so I doubt it’s a weld. If it isn’t a weld I have no clue what it could be. If somebody cheated I think it would be more obvious what they did to cheat.

As for performance, we don’t have very many Mac users. Most of the hockey players use PC, while some use their phones and IPads. I know one Mac user who said he wasn’t even able to touch the puck. It just never let him have ownership for some reason, so he quit. He returned after I fixed it. To fix it I just added the script above. ^

This is a different Mac user though; and a much different problem. Thanks for reading, and let me know what you think about all of this.

1 Like

I have experienced that with other games and my own, it could be that someone is lagging and giving them the upper hand. It’s hard to tell if it is an exploit or if it is a connection problem. I’m not too sure on how to fix it. Sorry if that wasn’t a big help.

There are several ways to make an attack vector out of network ownership, because the client is able to replicate physics and event signals for objects on their network. So lets say the puck has a touchInterest for touch events, if the client has ownership of that part they can remove that touchInterest basically shutting down that event until networkOwnership changes.
Related: https://devforum.roblox.com/t/what-exploits-exist/561509/89

But theres also methods for determining performance issues; you could use this function client-side to get the FPS, which might give you a clue in whether they have lag or not.

1 Like

Lag is more often related to network issues, or ping. FPS is for other performance issues, like the game being visually choppier, freezing, etc. rather than replication issues.

3 Likes

Your FindNearestPlayer function has some flaws:

  • It makes excessive calls to SetNetworkOwner when multiple players are fulfilling the magnitude criteria.
    – You should only call SetNetworkOwner at maximum one time, per call to your FindNearestPlayer.
  • It has no algorithm for “puck is not near any player, so set network-ownership to auto or server”, which could give the player currently having network-ownership of the puck some advantages, even when the puck is very far away from the player, and none of the other players are near it.
  • The code you posted, does not illustrate what happens with script.Parent.LastToHoldPuck.Value. So if that StringValue is set elsewhere to not be an empty string, then FindNearestPlayer is futile to call, as it won’t ever be able to change network-ownership of the puck.

May I suggest a slightly modified function:

local function SetPuckOwnershipToNearestPlayer()
  -- No need to continuously check if anchored in the for-loop,
  -- as that value won't change when doing the for-loop.
  -- So just check it once, here before the for-loop.
  if script.Parent.Anchored then
    -- No need to attempt changing network-ownership of anchored part
    return
  end

  local dist = 5 -- Must be less than 5 studs close to the puck
  local nearestPlayer = nil

  for _,player in ipairs(game.Players:GetPlayers()) do
    if player.Character then
      local hockeystick = player.Character:FindFirstChild("HockeyStick")
      if hockeystick then
        local magnitude = (hockeystick.Blade.Position - script.Parent.Position).Magnitude
        if magnitude < dist then
          dist = magnitude
          nearestPlayer = player
        end
      end
    end
  end

  -- In case a nearestPlayer could not be found, the value is `nil`,
  -- which would then be the server that gets ownership.
  script.Parent:SetNetworkOwner(nearestPlayer)
end

Though depending on how fast-paced your game is, it could also be problematic changing network-ownership of the puck too often, as it does take some fraction of a second to transfer/synchronize this network-ownership to another client (or the server).

3 Likes

I love this reply, thank you! I am going to give it a try and let you know how it worked out.

Also I want to update everyone on the situation. So one of the members sent a video explaining how they think he/she was able to pull off this exploit. I disagree with the logic though. This video looks completely different than what the other videos showed. He used some key bind to teleport the puck to the same spot on his blade. Let me know what you think…

local uis = Game:GetService("UserInputService")
uis.InputBegan:connect(function(inst)
    if inst.KeyCode == Enum.KeyCode.z  then -- z is a random key I guessed
        game.Workspace.Puck.Position = game.Workspace.NAME.HockeyStick.BladeTape.Position
    end
end)

After further testing with Decker004’s script I noticed the puck would slightly stutter and pause. It’s especially noticeable during shots or periods where the puck travels further away. Here is some footage of it…

Final update about the situation. He has came out and admitted he exploited and cheated. He won’t say how he did it, but we can assume from further footage it was some sort of key-bind that sets the pucks coordinates close to the blade. He probably had two keys set up with slightly different coordinates for the blade, and he could switch back n forth between them for forehand and backhand positioning. Here is another video of him doing it…

External Media

All that is left to do is come up with a patch for this. All ideas on how I could possibly prevent this from happening again would be appreciated.