Bug with Mining System with OverlapParams

I am currently making a mining system for my game. When I change targets, it keeps the same result (prints out “nothing”) as it did for the character. As you can see in this video, it should directly print Common_Node, but it firstly prints out “nothing”:

I use OverlapParams to handle the hit detection

local Activate_Pickaxe_Event = game.ReplicatedStorage.Activate_Pickaxe_Event

local Radius = 5

--SoundEffect.SoundId = "rbxassetid://11257724986"
local SoundEffect = Instance.new("Sound")

local Params = OverlapParams.new()
Params.FilterType = Enum.RaycastFilterType.Whitelist

Activate_Pickaxe_Event.OnServerInvoke = function(Player)
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local Pickaxe = Character:FindFirstChild("Pickaxe")
	
	SoundEffect.Parent = Pickaxe
	
	local AbleToHitArray = {}
	
	--Puts all Nodes in the array
	for index, node in ipairs(workspace.Nodes:GetDescendants()) do
		if node:IsA("MeshPart") and game.ServerStorage:FindFirstChild("Nodes"):FindFirstChild(node.Name) then
			table.insert(AbleToHitArray, node)
		end
	end
	
	--Puts all Characters in the array except local character
	for index, OtherPlayer in ipairs(game:GetService("Players"):GetPlayers()) do
		local OtherCharacter = OtherPlayer.Character or OtherPlayer.CharacterAdded:Wait()
		if OtherCharacter ~= Character then
			table.insert(AbleToHitArray, OtherCharacter)
		end
	end
	
	print("AbleToHitArray: ",AbleToHitArray)
	Params.FilterDescendantsInstances = AbleToHitArray
	
-- Handle Hit Detection here and return the sound id depending on the hit
	local TouchedArray = workspace:GetPartBoundsInBox(Pickaxe:FindFirstChild("PickaxeHead").CFrame, Vector3.new(1, 2.6, 2.9), Params)
	print("TouchedArray: ", TouchedArray)
	if TouchedArray and #TouchedArray > 0 then
		for index, TouchedPart in ipairs(TouchedArray) do
			print(TouchedPart)
			if game.ServerStorage:FindFirstChild("Nodes"):FindFirstChild(TouchedPart.Name) then
				print("we mine")
				SoundEffect.SoundId = "rbxassetid://11257724986"
				return SoundEffect
			elseif TouchedPart:IsA("BasePart") and TouchedPart.Parent:FindFirstChild("Humanoid") then
				print("we kill")
				SoundEffect.SoundId = "rbxassetid://11257724986"
				return SoundEffect
			end
		end
	else
		print("nothing")
		SoundEffect.SoundId = "rbxassetid://11257724986"
		return SoundEffect
	end
end

Thank you

Without seeing the Localscript that connects to the RemoteEvent I cant be for sure, but I think the problem is that the server and the client are not coordinated with each other.

It looks to me that when you click, only an animation plays and the RemoteEvent fires. this means that the server checks what the player hits blindly with no regulation or expectations. Kinda wordy, but in summary: the script doesn't account for ping. When you click, the Pickaxe event and the animation are received by the server at the same time (or sometime near), meaning the server checks the pick’s overlap the moment it starts receiving the animation which leads to the pickaxe is not actually down when checking overlap. The ping delay also means that the player on the server lags behind where you are visually. Leading to false negatives when running up on something and immediately mining.

An easy fix to this would be to detect the thing that the pickaxe hit on the client and let the server check if the player can actually hit that object.

Again, without seeing the localscript behind this I can’t be certain, but if this was the problem, great! If not or you already accounted for client-server delay, send me the localscript so I can take a look at it. Hope this helps :grin:

this maybe because you are using the pickaxe head to detect its current cframe on the server and there is client server delays from when the animation happens on the client and the server checking the getpartsboundsinbox you may want to detect hitting in a different way

How would I “re-detect” on the server if the player actually hit the object?
I cant solely rely on the client or else, its easily exploitable

Once the client tells the server what it wants to hit, the server can check:

  • if the player is close enough,
  • is allowed to mine the node,
  • has a pickaxe in the first place,
  • swinging cooldown has cooled completely,
  • and any other measures that you want

There isnt a true 100% way to prevent exploiting, but the exploits you can make have such a miniscule advantage that its just not worth the effort.

(If you do any distance checks from the player, use their HumanoidRootPart)

1 Like

as rabbit mention above all those are good check the one you probably would want to use is the distance remember though the player may still not be right up on the mine block when the client fires to the server so maybe give them a stud or 2 you can run some distance testing prints on the server and get an average for this

the touched event is even still can option but if not done properly can cause some lag like issues

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.