I can't understand where does my bug come from? I've tried a load of fixes

So basically i’am making a Ro-Soccer game, I’ve made multiple tools (For now only dribble work), I’ve started Shoot tool to kick the ball with an Angle bar & a Power bar, Those aren’t the problem but When i try to touch the ball I get this error

here is the modules “Functionings”

local Functionings = {}

-- [{ Main Module Requirements }]
local TS = game:GetService("TweenService")
local Client = game.Players.LocalPlayer
local Character = Client.Character

-- [{ Service Requirements }]
local RStorage = game:GetService("ReplicatedStorage")
local Remotes = RStorage.Remotes
local RunService = game:GetService("RunService")

--- [{ Variable Requirements }]
local UsingTool = false
local FootType = "R"

--- [{ Module Requirements }]
local StateManager = require(RStorage.Modules.StateManager)
local GarbageCollector = require(RStorage.Modules.GarbageCollector).new()
local ParametersModule = require(RStorage.Modules.ParametersModule)

-- [{ Function Gameplay }]

function Functionings.Hitbox(Information)
	RunService.Stepped:Wait()

	for Index, Limb in Information.Limbs do
		task.spawn(function()
			GarbageCollector:GiveTask(Limb.Touched:Connect(function(HitPart)
				if HitPart:HasTag("Ball") then
					Information.ReactFunction(HitPart, Limb)
				end
			end))

			GarbageCollector:GiveTask(RunService.Stepped:Connect(function()
				local Parts = workspace:GetPartsInPart(Limb, ParametersModule:GetBallParameters())

				for Index, Ball in Parts do
					Information.ReactFunction(Ball, Limb)
				end
			end))
		end)
	end
end

function Functionings.ClientReact(Ball, MaxForce, Velocity, Cooldown, DebrisTime)
	
	if Ball.Anchored == true then
		return
	end
	
	if Ball.Values.OnCoolDown.Value == true then
		warn("yh")
		
		return
	end
	

	for Index, CorrespondingValue in ipairs( Ball:GetChildren() ) do

		if CorrespondingValue.Name == "BodyVelocity" or CorrespondingValue.Name == "Curve" then

			CorrespondingValue:Remove()

		end

	end


	for Index, CorrespondingValue in ipairs( Character.Torso:GetChildren() ) do

		if CorrespondingValue.Name == "BodyVelocity" then

			CorrespondingValue:Destroy()

		end

	end
	
	if DebrisTime == nil then
		DebrisTime = 0.3
	end
	
	if Cooldown == nil then
		Cooldown = 0.6
	end
	
	Remotes.Gameplay.OutfieldReactOwnership:FireServer(

		Ball, 
		Ball.Position, 
		Cooldown

	)
	
	local ClientSideReactBodyVelocity = Instance.new("BodyVelocity")
	ClientSideReactBodyVelocity.Velocity = Velocity
	ClientSideReactBodyVelocity.MaxForce = MaxForce
	ClientSideReactBodyVelocity.Velocity = Velocity
	ClientSideReactBodyVelocity.Parent = Ball
	
	game.Debris:AddItem(ClientSideReactBodyVelocity, DebrisTime)

end



return Functionings

Here is my LocalScript “Initializer” Under Shoot Tool.

task.wait()

local RepStorage = game:GetService("ReplicatedStorage")
local Funcs = require(RepStorage.Modules.CoreGameplay.Functionings)
local State = require(RepStorage.Modules.StateManager)
local ContextAction = game:GetService("ContextActionService")
local Visuals = require(RepStorage.Modules.VectorViz)
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
player.CharacterAdded:Connect(function(c) char = c end)
local pdata = RepStorage.ClientData:WaitForChild(tostring(player.UserId))
local globalCd = .2

local okPower, PowerBar = pcall(function() return require(RepStorage.Modules.PowerBar) end)
local okAngle, AngleBarModule = pcall(function() return require(RepStorage.Modules.AngleBar) end)
if not okPower then warn("PowerBar require failed:", PowerBar) end
if not okAngle then warn("AngleBar require failed:", AngleBarModule) end

local tool = script.Parent
local active = {}
local animCache = {}
local inputHistory = {}
local isHolding = false
local boundActions = {}
local Equipped = false
local globalCdActive = false

tool.Equipped:Connect(function()
	Equipped = true
	State.SetState(player, "EquippedTool", true)
end)
tool.Unequipped:Connect(function()
	Equipped = false
	for mod, _ in pairs(active) do
		pcall(function() releaseAction(mod) end)
	end
	State.SetState(player, "EquippedTool", false)
	State.SetState(player, "Using", false)
end)

local function playAnimation(animFolder, animName, mod)
	local hum = char and char:FindFirstChildOfClass("Humanoid")
	if not hum then return nil end
	local anim
	local suffix = ""
	if mod and mod.ReliesOnFoot then
		local leg = State.GetState(player, "Leg")
		suffix = (leg == "Right" and "_R") or "_L"
		anim = animFolder and (animFolder:FindFirstChild(animName .. suffix) or animFolder:FindFirstChild(animName)) or nil
	else
		anim = animFolder and animFolder:FindFirstChild(animName) or nil
	end
	if not anim then return nil end
	local cacheKey = animName .. suffix
	if not animCache[cacheKey] then
		animCache[cacheKey] = hum:LoadAnimation(anim)
	end
	local track = animCache[cacheKey]
	if track then
		if track.IsPlaying then pcall(function() track:Stop() end) end
		pcall(function() track:Play() end)
	end
	return track, cacheKey
end

local function pressAction(mod, keyVal)
	if mod and type(mod.react) == "function" then
		local animFolder = RepStorage.Animations.Tools:FindFirstChild(tool.Name) or RepStorage.Animations.Tools
		local track = playAnimation(animFolder, keyVal.Name, mod)
		active[mod] = true
		State.SetState(player, "Using", true)
		globalCdActive = true
		task.delay(globalCd, function() globalCdActive = false end)
		task.delay(mod.ReactTime, function()
			if track and track.IsPlaying then track:Stop() end
			State.SetState(player, "Using", false)
			active[mod] = nil
			inputHistory = {}
		end)
	end
end

local function startHold(keyVal, mod)
	inputHistory = {}
	isHolding = true
	State.SetState(player, "Using", true)
	local animFolder = RepStorage.Animations.Tools.Shoot:FindFirstChild(keyVal.Name) or RepStorage.Animations.Tools.Shoot
	local holdTrack, cacheKey = playAnimation(animFolder, "HoldUp", mod)
	active[mod] = { track = holdTrack, cacheKey = cacheKey, charging = true }
	pcall(function() if okPower then PowerBar.Start() end end)
end

function releaseAction(mod, keyVal)
	local keyName = nil
	if keyVal and keyVal.Name then
		keyName = keyVal.Name
	else
		local kv = pdata.Keybinds:FindFirstChild("Shoot") and pdata.Keybinds.Shoot:FindFirstChild(mod.Name)
		if kv then keyName = kv.Name keyVal = kv end
	end

	if not isHolding and not active[mod] then
		return
	end

	local stored = active[mod]
	if stored and type(stored) == "table" then
		if stored.track then pcall(function() if stored.track.IsPlaying then stored.track:Stop() end end) end
		if stored.cacheKey and animCache[stored.cacheKey] then
			pcall(function()
				local ct = animCache[stored.cacheKey]
				if ct and ct.IsPlaying then ct:Stop() end
			end)
		end
	end

	isHolding = false

	local lastKey = nil
	if type(mod.Check) == "function" then lastKey = mod.Check(inputHistory) end
	local MaxForce, F, Cooldown, DebrisTime, animName
	if type(mod.Release) == "function" then
		if mod.HoldAble then
			local powerValue = 0
			local angleValue = (okAngle and AngleBarModule.GetAngle and AngleBarModule.GetAngle()) or 50
			local ok, res = pcall(function() if okPower and PowerBar.Stop then return PowerBar.Stop() end return 0 end)
			if ok and type(res) == "number" then powerValue = res else powerValue = 0 end
			MaxForce, F, Cooldown, DebrisTime, animName = mod.Release(lastKey, powerValue, angleValue)
		else
			MaxForce, F, Cooldown, DebrisTime, animName = mod.Release(lastKey)
		end
	end

	local animFolder
	if keyName then
		animFolder = RepStorage.Animations.Tools.Shoot:FindFirstChild(keyName) or RepStorage.Animations.Tools.Shoot
	else
		animFolder = RepStorage.Animations.Tools.Shoot:FindFirstChild(mod.Name) or RepStorage.Animations.Tools.Shoot
	end

	local releaseTrack, releaseCacheKey
	if animFolder then
		releaseTrack, releaseCacheKey = playAnimation(animFolder, animName or "Release", mod)
		active[mod] = active[mod] or {}
		active[mod].releaseTrack = releaseTrack
		active[mod].releaseCacheKey = releaseCacheKey
	end

	globalCdActive = true
	task.delay(globalCd or 0.2, function() globalCdActive = false end)

	if releaseTrack then
		local len = (releaseTrack.Length and releaseTrack.Length > 0) and releaseTrack.Length or (mod.TimeAfterRelease or 1)
		task.delay(len + 0.05, function()
			pcall(function() if releaseTrack.IsPlaying then releaseTrack:Stop() end end)
			active[mod] = nil
			State.SetState(player, "Using", false)
			inputHistory = {}
		end)
	else
		task.delay(mod.TimeAfterRelease or 1, function()
			active[mod] = nil
			State.SetState(player, "Using", false)
			inputHistory = {}
		end)
	end

	return MaxForce, F, Cooldown, DebrisTime
end

local function onHit(hit, limb)
	if not hit or hit.Name ~= "Ball" then return end
	if not limb then return end
	local selectedLeg = State.GetState(player, "Leg")
	local limbLeg = (limb == char["Right Leg"] and "Right") or (limb == char["Left Leg"] and "Left") or nil
	if limbLeg == nil then return end
	for mod, _ in pairs(active) do
		local footPref = mod.Foot
		local forceFoot = mod.ForceFoot
		local allow = false
		if footPref then
			if forceFoot then
				if limbLeg == footPref then allow = true end
			else
				if selectedLeg == footPref and limbLeg == footPref then allow = true end
			end
		else
			if limbLeg == selectedLeg then allow = true end
		end
		if allow then
			local MaxForce, F, Cooldown, DebrisTime
			if mod.HoldAble then
				local keyVal = pdata.Keybinds.Shoot:FindFirstChild(mod.Name)
				if keyVal then MaxForce, F, Cooldown, DebrisTime = releaseAction(mod, keyVal) end
			else
				MaxForce, F, Cooldown, DebrisTime = mod.react(hit, limb)
			end
			if MaxForce and F then
				if Visuals and type(Visuals.CreateVisualiser) == "function" then
					pcall(function()
						Visuals:CreateVisualiser("ForceViz", hit.Position, F, {Colour = Color3.fromRGB(165, 21, 255), Scale = 1, Width = 0.15})
					end)
					task.delay(1, function() pcall(function() Visuals:DestroyVisualiser("ForceViz") end) end)
				end
				Funcs.ClientReact(hit, MaxForce, F, Cooldown, DebrisTime)
			end
		end
	end
end

Funcs.Hitbox({
	Limbs = { char["Right Leg"], char["Left Leg"] },
	ReactFunction = onHit
})


local function getInputId(inputObject)
	if not inputObject then return nil end
	local uit = inputObject.UserInputType
	if uit == Enum.UserInputType.MouseButton1 or uit == Enum.UserInputType.MouseButton2 then return uit.Name end
	local kc = inputObject.KeyCode
	if kc and kc ~= Enum.KeyCode.Unknown then return kc.Name end
	return tostring((uit and uit.Name) or "")
end

local function bindKey(keyVal)
	if not keyVal:IsA("StringValue") or keyVal.Value == "" then return end
	local kv = keyVal
	local keyValue = kv.Value
	local actionName = "Shoot_" .. kv.Name
	if boundActions[actionName] then ContextAction:UnbindAction(actionName) boundActions[actionName] = nil end
	local enumArg
	if keyValue == "MouseButton1" or keyValue == "MouseButton2" then enumArg = Enum.UserInputType[keyValue] else enumArg = Enum.KeyCode[keyValue] end

	local function actionCallback(name, inputState, inputObject)
		if not tool or not tool.Parent or tool.Parent ~= char then return Enum.ContextActionResult.Pass end
		if inputState == Enum.UserInputState.Begin and globalCdActive then return Enum.ContextActionResult.Sink end
		if inputState == Enum.UserInputState.Begin then
			if State.GetState(player, "Using") and isHolding then return Enum.ContextActionResult.Sink end
			local id = getInputId(inputObject)
			if id then table.insert(inputHistory, id) end
			local modScript = script:FindFirstChild(kv.Name)
			if not modScript then return Enum.ContextActionResult.Pass end
			local mod = require(modScript)
			if mod.HoldAble then startHold(kv, mod) else pressAction(mod, kv) end
			return Enum.ContextActionResult.Sink
		elseif inputState == Enum.UserInputState.End or inputState == Enum.UserInputState.Cancel then
			local modScript = script:FindFirstChild(kv.Name)
			if not modScript then return Enum.ContextActionResult.Pass end
			local mod = require(modScript)
			if mod.HoldAble then releaseAction(mod, kv) return Enum.ContextActionResult.Sink end
		end
		return Enum.ContextActionResult.Pass
	end

	if enumArg then ContextAction:BindAction(actionName, actionCallback, false, enumArg) else ContextAction:BindAction(actionName, actionCallback, false) end
	boundActions[actionName] = true
end

local shootKeybinds = pdata.Keybinds:FindFirstChild("Shoot")
if shootKeybinds then
	for _, keyVal in ipairs(shootKeybinds:GetChildren()) do bindKey(keyVal) end
else
	warn("[Startup] pdata.Keybinds.Shoot not found")
end

pdata.Keybinds.Shoot.ChildAdded:Connect(function(child) bindKey(child) end)
pdata.Keybinds.Shoot.ChildRemoved:Connect(function(child)
	local actionName = "Shoot_" .. tostring(child.Name)
	if boundActions[actionName] then ContextAction:UnbindAction(actionName) boundActions[actionName] = nil end
end)

1 Like

It looks like your issue is rooted in lines 39 and 193 of your code-I’ve tried to look for those parts of your script but since the lines aren’t numbered, I can’t really tell where they are. Could you just write out only lines 193 and 39 in a reply ?

1 Like

I think these are the lines (yes, with line by line counting):
Line 39 script: Information.ReactFunction(Ball, Limb)
Line 193 script: local keyVal = pdata.Keybinds.Shoot:FindFirstChild(mod.Name) (unsure, but I ain’t double checking line 1 to 193 bruh)

2 Likes

It is yes. I tried to find some fixes but couldn’t so if u guys do lmk

2 Likes

Probably Ball in Parts is nil, which is the factor of bug. You should check if workspace:GetPartsInPart(Limb, ParametersModule:GetBallParameters())
exist.

2 Likes

I’ll try & tell you, but this is weird as hell because i use a script VERY VERY similar for my dribble tools & it Work correctly..

1 Like

Okay, I saw documents about GetPartsInPart since I didn’t know it. This function detects parts touching a particular part, isn’t it?(Please tell me if this interpretation is wrong)
I guess the ball is not touching limbs when the script runs, or ball parameter module is empty.
Please insert this code before index loop and test again.:if not Parts:GetChildren then end

Also, I see the new method replacing Runservice.Stepped. Please check the documentations.

Make sure all your mods have “Name” property. I see mods are ModuleScripts that contain some sort of information (lines 244 - 245)

local mod = require(modScript)
if mod.HoldAble then startHold(kv, mod) else pressAction(mod, kv) end

so when you’re doing

local keyVal = pdata.Keybinds.Shoot:FindFirstChild(mod.Name)

if the property Name does not exist in mod, then FindFirstChild errors with that error that its giving you. The argument passed to FindFirstChild cannot be nil.

1 Like