What is the best way to make a Skill? (For example FireBall)

I want to make for example Fireball with Tool, how should I do it?

Right now I’m using Server to Animate the Fireball and Detect the enemy.

image

Client:

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local Mouse = player:GetMouse()

local Tool = script.Parent
local ActivateSkill = Tool:WaitForChild("ActivateSkill")

Tool.Activated:Connect(function()
	ActivateSkill:FireServer(Mouse.Hit)
end)

Server:

local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")

local Tool = script.Parent
local ThrowAnimation = Tool:WaitForChild("ThrowAnimation")
local ActivateSkill = Tool:WaitForChild("ActivateSkill")
local cdtime = Tool:WaitForChild("Cooldown").Value
local cooldown = os.time()-cdtime

ActivateSkill.OnServerEvent:Connect(function(player,mousehit)
	if os.time() - cooldown >= cdtime then
		cooldown = os.time()
		
		local character = script.Parent.Parent
		local animation = character.Humanoid:LoadAnimation(ThrowAnimation)
		animation:Play()
		animation:GetMarkerReachedSignal("Throw"):Wait()
		
		local fireball = game.ServerStorage.Fireball:Clone()
		
		local hrp = character:WaitForChild("HumanoidRootPart")

		local cf = CFrame.new(hrp.Position, mousehit.Position)

		local newPos = cf.LookVector * 10000

		fireball.CFrame = cf


		local tweenTime = (hrp.Position - newPos).Magnitude / script.Parent.Speed.Value

		local ti = TweenInfo.new(tweenTime, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)


		local tween = TweenService:Create(fireball, ti, {Position = newPos})
		tween:Play()

		tween.Completed:Connect(function()
			fireball:Destroy()
		end)
		
		task.spawn(function()
			local conn = fireball.Touched:Connect(function() end)
			while task.wait() do
				for _,hit in pairs(fireball:GetTouchingParts()) do
					if hit.Parent:IsA("Accessory") == false and hit.Parent ~= character then
						if hit.Parent:FindFirstChild("Humanoid") then
							hit.Parent.Humanoid:TakeDamage(script.Parent.Damage.Value)
						end

						fireball:Destroy()
					end
				end	
			end
		end)


		fireball.Parent = workspace
	end
end)

I believe there is a much better way to recreate this such as using Client to animate instead. But I’m still confused on how to make the hit detection if I’m gonna use Client to animate.

So is there any better way to recreate this?