Adding Axe makes the RunService goes 2x, 3x times faster the more Axe we add

Hey G’s so basically I have a problem with my Axe so when I add another Axe the second axe rotate 2x faster than the first axe and when I add a 3rd axe it rotates 3x faster than the other axes not normal it’s not following the flow correctly it’s getting too faster so here’s the code to update axe position G

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local Remotes = ReplicatedStorage:WaitForChild("Remotes")

local axeModel = nil

local rotationAngle = {}
local orbitAngle = {}
--local rotationAngle = 0
--local orbitAngle = 90 

local player = Players.LocalPlayer
local Character = player.Character
local axeName = "AxeModelOnPlayer"

local debounceMonsters = {}

local healthUpdateEvent = ReplicatedStorage:WaitForChild("HealthUpdateEvent")

local AttributeAbility = Remotes:WaitForChild("AttributeAbility")

local axes = {}

local function getAllAxes()
	for _, item in pairs(Character:GetChildren()) do
		if item.Name:match("^Axe") then
			table.insert(axes, item)
		end
	end
	return axes
end

axes = getAllAxes()


-------------------- HAMMER ABILITY -----------------------------

local HammerAttackSpeed = script:GetAttribute("HammerAttackSpeed")
local HammerAttackSpeedLevel = script:GetAttribute("HammerAttackSpeedLevel")
local HammerAttack = script:GetAttribute("HammerAttack")
local HammerAttackLevel = script:GetAttribute("HammerAttackLevel")
local HammerAttackcritical = script:GetAttribute("HammerAttackcritical")
local HammerAttackcriticalLevel = script:GetAttribute("HammerAttackcriticalLevel")
local HammerAttackcooldown = script:GetAttribute("HammerAttackCooldown")
local HammerAttackcooldownLevel = script:GetAttribute("HammerAttackCooldownLevel")
local HammerAttackpoisonLevel = script:GetAttribute("HammerAttackpoisonLevel")
local HammerAttackpoison = script:GetAttribute("HammerAttackpoison")
local HammerAttackAdd = script:GetAttribute("HammerAttackAdd")
local HammerAttackAddLevel = script:GetAttribute("HammerAttackAddLevel")
local HammerAttackScale = script:GetAttribute("HammerAttackscale")
local HammerAttackScaleLevel = script:GetAttribute("HammerAttackscaleLevel")

-------------------- AXE ABILITY -----------------------------

local AxeAttackSpeed = script:GetAttribute("AxeAttackSpeed")
local AxeAttackSpeedLevel = script:GetAttribute("AxeAttackSpeedLevel")
local AxeAttack = script:GetAttribute("AxeAttack")
local AxeAttackLevel = script:GetAttribute("AxeAttackLevel")
local AxeAttackcritical = script:GetAttribute("AxeAttackcritical")
local AxeAttackcriticalLevel = script:GetAttribute("AxeAttackcriticalLevel")
local AxeAttackcooldown = script:GetAttribute("AxeAttackCooldown")
local AxeAttackcooldownLevel = script:GetAttribute("AxeAttackCooldownLevel")
local AxeAttackpoisonLevel = script:GetAttribute("AxeAttackpoisonLevel")
local AxeAttackpoison = script:GetAttribute("AxeAttackpoison")
local AxeAttackAdd = script:GetAttribute("AxeAttackAdd")
local AxeAttackAddLevel = script:GetAttribute("AxeAttackAddLevel")
local AxeAttackScale = script:GetAttribute("AxeAttackscale")
local AxeAttackScaleLevel = script:GetAttribute("AxeAttackscaleLevel")

-------------------- ANY ABILITY -----------------------------

local WalkSpeed = script:GetAttribute("WalkSpeed")
local WalkSpeedLevel = script:GetAttribute("WalkSpeedLevel")
local Health = script:GetAttribute("Health")
local HealthLevel = script:GetAttribute("HealthLevel")
local Expboost = script:GetAttribute("Expboost")
local ExpboostLevel = script:GetAttribute("ExpboostLevel")
local Fortuneboost = script:GetAttribute("Fortuneboost")
local FortuneboostLevel = script:GetAttribute("FortuneboostLevel")

local isOnCooldown = {}  
--local cooldownTimer = 0

local cooldownTimer = {}

local orbitCenterPosition = nil
local lastPlayerPosition = nil


local function SmoothCurve(t)
	return 1 - math.pow(1 - t, 3)
end

local function UpdateAxePosition(deltaTime, axeModel)
	print("DELTA TIME IS : ", deltaTime)
	print("AXE MODEL IS : ", axeModel)
	
	
	if not player:FindFirstChild("IsPlaying") or not player.IsPlaying.Value then return end
	if not Character or not Character.PrimaryPart then return end
	
	if not rotationAngle[axeModel.Name] then
		rotationAngle[axeModel.Name] = 0
	end
	
	if not orbitAngle[axeModel.Name] then
		orbitAngle[axeModel.Name] = 90
	end
	
	if not cooldownTimer[axeModel.Name] then
		cooldownTimer[axeModel.Name] = 0
	end
	
	if isOnCooldown[axeModel.Name] then
		cooldownTimer[axeModel.Name] -= deltaTime
		if cooldownTimer[axeModel.Name] <= 0 then
			isOnCooldown[axeModel.Name] = false 			
			orbitAngle[axeModel.Name] = 90			
			rotationAngle[axeModel.Name] = 0
		end
		return
	end

	local rootPos = Character.PrimaryPart.Position
	local head = Character:FindFirstChild("Head")
	if not head then return end

	local invisibleFillingPart = axeModel:FindFirstChild("invisible filling part")
	if not invisibleFillingPart then
		warn("invisible filling part is missing in the axe model!")
		return
	end
	
	
	
	rotationAngle[axeModel.Name] -= AxeAttackSpeed
	orbitAngle[axeModel.Name] += (90 + AxeAttackSpeed) * deltaTime
	
	if orbitAngle[axeModel.Name] >= 450 then
		orbitAngle[axeModel.Name] = 450
	end

	local radius = 10
	local height = 2
	local orbitCenter = Vector3.new(rootPos.X, rootPos.Y + height, rootPos.Z)

	local offsetX = math.cos(math.rad(orbitAngle[axeModel.Name])) * radius
	local offsetZ = math.sin(math.rad(orbitAngle[axeModel.Name])) * radius
	local offset = Vector3.new(offsetX, 0, offsetZ)

	local axePos = orbitCenter + offset
	local rotation = CFrame.Angles(0, math.rad(rotationAngle[axeModel.Name]), 0)
	axeModel:SetPrimaryPartCFrame(CFrame.new(axePos) * rotation)

	local fadeStart = 360
	local fadeEnd = 450
	local alpha = 0
	if orbitAngle[axeModel.Name] >= fadeStart then
		alpha = (orbitAngle[axeModel.Name] - fadeStart) / (fadeEnd - fadeStart)
	end

	for _, part in axeModel:GetChildren() do
		if part:IsA("BasePart") and part.Name ~= "invisible filling part" then
			part.Transparency = math.clamp(alpha, 0, 1)
		end
	end

	if invisibleFillingPart then
		for _, part in ipairs(invisibleFillingPart:GetTouchingParts()) do
			if part.Name ~= "OtherGrip" then
				if not debounceMonsters[part.Parent] then
					debounceMonsters[part.Parent] = true
					healthUpdateEvent:FireServer(AxeAttack, part.Parent, script:GetAttribute("ContainPoison"))
					task.delay(1, function()
						debounceMonsters[part.Parent] = false
					end)
				end
			end
		end
	end

	if orbitAngle[axeModel.Name] >= 450 then
		isOnCooldown[axeModel.Name] = true
		cooldownTimer[axeModel.Name] = 5
	end
end

AttributeAbility.Event:Connect(function(abilityName, weapon)
	if weapon == "Axe" or weapon == "Hammer" then
		if abilityName == "AxeAttackSpeed" then
			AxeAttackSpeed += (AxeAttackSpeed * 0.1)
			AxeAttackSpeedLevel += 1

			script:SetAttribute("AxeAttackSpeed", AxeAttackSpeed)
			script:SetAttribute("AxeAttackSpeedLevel", AxeAttackSpeedLevel)

		elseif abilityName == "AxeAttack" then
			AxeAttack += 1
			AxeAttackLevel += 1

			script:SetAttribute("AxeAttack", AxeAttack)
			script:SetAttribute("AxeAttackLevel", AxeAttackLevel)
		elseif abilityName == "AxeAttackcritical" then

			AxeAttackcritical += 0.1
			AxeAttackcriticalLevel += 1

			AxeAttack += AxeAttackcritical


			script:SetAttribute("AxeAttack", AxeAttack)

			script:SetAttribute("AxeAttackcritical", AxeAttackcritical)
			script:SetAttribute("AxeAttackcriticalLevel", AxeAttackcriticalLevel)

		elseif abilityName == "AxeAttackCooldown" then
			AxeAttackcooldown -= 0.1
			AxeAttackcooldownLevel += 1

			script:SetAttribute("AxeAttackCooldown", AxeAttackcooldown)
			script:SetAttribute("AxeAttackCooldownLevel", AxeAttackcooldownLevel)
		elseif abilityName == "AxeAttackpoison" then
			AxeAttackpoison += 1
			AxeAttackpoisonLevel += 1
			
			
			script:SetAttribute("AxeAttackpoison", AxeAttackpoison)
			script:SetAttribute("AxeAttackpoisonLevel", AxeAttackpoisonLevel)

			script:SetAttribute("ContainPoison", true)
		elseif abilityName == "AxeAttackAdd" then
			AxeAttackAdd += 1
			AxeAttackAddLevel += 1
			
			axes = getAllAxes()

			local newAxe = axes[AxeAttackAdd - 1]:Clone()
			newAxe.Name = "Axe " .. AxeAttackAdd
			newAxe.Parent = player.Character
			
			table.insert(axes, newAxe)


			script:SetAttribute("AxeAttackAdd", AxeAttackAdd)
			script:SetAttribute("AxeAttackAddLevel", AxeAttackAddLevel)
		elseif abilityName == "AxeAttackscale" then
			local scale = axeModel:GetScale() 
			local newScale = scale + (scale * 0.1)
			axeModel:ScaleTo(newScale)

			AxeAttackScale += (scale * 0.1)
			AxeAttackScaleLevel += 1

			script:SetAttribute("AxeAttackscale", AxeAttackScale)
			script:SetAttribute("AxeAttackscaleLevel", AxeAttackScaleLevel)
		end
	elseif weapon == "Hammer" then
		if abilityName == "HammerAttackSpeed" then
			if HammerAttackSpeed > 0.1 then
				HammerAttackSpeed -= (HammerAttackSpeed * 0.1)
			end

			HammerAttackSpeedLevel += 1

			script:SetAttribute("HammerAttackSpeed", HammerAttackSpeed)
			script:SetAttribute("HammerAttackSpeedLevel", HammerAttackSpeedLevel)
		elseif abilityName == "HammerAttack" then
			HammerAttack += 1
			HammerAttackLevel += 1

			script:SetAttribute("HammerAttack", HammerAttack)
			script:SetAttribute("HammerAttackLevel", HammerAttackLevel)
		elseif abilityName == "HammerAttackcritical" then
			HammerAttackcritical += 0.1
			HammerAttackcriticalLevel += 1

			HammerAttack += HammerAttackcritical

			script:SetAttribute("HammerAttack", HammerAttack)

			script:SetAttribute("HammerAttackcritical", HammerAttackcritical)
			script:SetAttribute("HammerAttackcriticalLevel", HammerAttackcriticalLevel)
		elseif abilityName == "HammerAttackCooldown" then
			if HammerAttackcooldown > 0.1 then
				HammerAttackcooldown -= 0.1
			end

			HammerAttackcooldownLevel += 1

			script:SetAttribute("HammerAttackCooldown", HammerAttackcooldown)
			script:SetAttribute("HammerAttackCooldownLevel", HammerAttackcooldownLevel)
		elseif abilityName == "HammerAttackpoison" then
			HammerAttackpoison += 1
			HammerAttackpoisonLevel += 1

			script:SetAttribute("HammerAttackpoison", HammerAttackpoison)
			script:SetAttribute("HammerAttackpoisonLevel", HammerAttackpoisonLevel)

			script:SetAttribute("ContainPoison", true)
		elseif abilityName == "HammerAttackAdd" then
			HammerAttackAdd += 1
			HammerAttackAddLevel += 1

			script:SetAttribute("HammerAttackAdd", HammerAttackAdd)
			script:SetAttribute("HammerAttackAddLevel", HammerAttackAddLevel)

		elseif abilityName == "HammerAttackscale" then
			HammerAttackScale += (HammerAttackScale * 0.1)
			HammerAttackScaleLevel += 1

			script:SetAttribute("HammerAttackscale", HammerAttackScale)
			script:SetAttribute("HammerAttackscaleLevel", HammerAttackScaleLevel)
		end
	elseif weapon == "AnyWeapon" then

		if abilityName == "WalkSpeed" then
			Character.Humanoid.WalkSpeed += (Character.Humanoid.WalkSpeed * 0.1)

			WalkSpeed += (Character.Humanoid.WalkSpeed * 0.1)
			WalkSpeedLevel += 1

			script:SetAttribute("WalkSpeed", WalkSpeed)
			script:SetAttribute("WalkSpeedLevel", WalkSpeedLevel)
		elseif abilityName == "Health" then
			Health += 5
			HealthLevel += 1

			script:SetAttribute("Health", Health)
			script:SetAttribute("HealthLevel", HealthLevel)

			Remotes:WaitForChild("ChangeHealth"):FireServer(Health)
		elseif abilityName == "Expboost" then
			Expboost += (Expboost * 0.1) 
			ExpboostLevel += 1

			script:SetAttribute("Expboost", Expboost)
			script:SetAttribute("ExpboostLevel", ExpboostLevel)

			Remotes:WaitForChild("BoostExp"):InvokeServer(Expboost)
		elseif abilityName == "Fortuneboost" then
			Fortuneboost += (Fortuneboost * 0.1) 
			FortuneboostLevel += 1


			script:SetAttribute("Fortuneboost", Fortuneboost)
			script:SetAttribute("FortuneboostLevel", FortuneboostLevel)
		end
	end
end)

RunService.RenderStepped:Connect(function(deltaTime)
	for _, axe in ipairs(axes) do
		task.spawn(UpdateAxePosition, deltaTime, axe)
	end
end)

The issue lies in your getAllAxes function.

The functions doesn’t wipe the axes table before filling it with all axes inside the player’s character. So every time you call this function, which you do whenever you create a new axe, all axes are added to the table again, resulting in older axes being in the table multiple times.

You can fix this by adding this at the top of your getAllAxes function.

table.clear(axes)

You will add it here ?

elseif abilityName == "AxeAttackAdd" then
	        AxeAttackAdd += 1
	        AxeAttackAddLevel += 1
			
			axes = getAllAxes()

			local newAxe = axes[AxeAttackAdd - 1]:Clone()
			newAxe.Name = "Axe " .. AxeAttackAdd
			
			orbitAngle[newAxe.Name] = 90
			rotationAngle[newAxe.Name] = 0
			cooldownTimer[newAxe.Name] = 0
			isOnCooldown[newAxe.Name] = false
			
			table.insert(axes, newAxe)


			script:SetAttribute("AxeAttackAdd", AxeAttackAdd)
			script:SetAttribute("AxeAttackAddLevel", AxeAttackAddLevel)

No, add it inside the getAllAxes function.

Got it G that’s what I just realized

I just hope we are on the same page when there’s 2 axes the first run run at a normal speed and the second one run 2 times faster orbiting around the player hope you understand my problem G

Please mark my reply as the solution if it fixed your problem.

Alright we are getting close to perfection G now we just have to make sure that when we have 3 swords it runs the 3 swords at the same time for the moment it run the 1st sword then after that it run at the same time 2 swords but it should run 3 at the same time the 3 swords when there’s 3 swords

2 at the same time when there’s 2 swords

4 at the same time when there’s 4 swords

Hey G always available we are close to perfection man

You’re too incoherent for me to understand what you are saying.
The problem you described in the post has already been solved.

1 Like

Sorry I’m just trying my best to explain it I solved it on my own G