Looking to Improve Efficiency on this Fireball Spell Tool

Provide an overview of:

  • What does the code do and what are you not satisfied with?
    This is a tool that spawns a energy fireball sort of spell in front of you that heads towards where the mouse clicked, and upon hitting another humanoid explodes and the hitbox becomes larger.
  • What potential improvements have you considered?
    I’d like it to not pass through objects such as terrain and parts if you click behind them, although this won’t be a problem in my game as players are locked in first person.
  • How (specifically) do you want to improve the code?
    Improve efficiency, mainly. This is the first time I’ve made something without really using any tutorials or resources and just played around with it until it worked.

LocalScript

local RS = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local player = Players.LocalPlayer

local bars = player.PlayerGui:WaitForChild("Bars")
local focusF = bars.FocusF
local CastCost = 15

local spellRemote = RS.EnergySender
local mouse = player:GetMouse()
local spell = script.Parent

local debounce = false

spell.Activated:Connect(function(player)
	local target = mouse.Hit
	if debounce == false and focusF:GetAttribute("Focus") >= CastCost then
		debounce = true
		focusF:SetAttribute("Focus", (focusF:GetAttribute("Focus")-CastCost))
		spellRemote:FireServer(target, player)
		task.wait(1)
		debounce = false
	end	
end)

Focus variables have to do with another script controlling GUI elements.

Server Script

local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TweenService")

local spell = script.Parent
local spellRemote = RS.EnergySender

local Speed = 80
local function GetTime(Distance, Speed)
	--time = distance / speed
	local Time = Distance / Speed
	return Time
end

local debounce = true

spellRemote.OnServerEvent:Connect(function(player, target)
	local character = player.Character
	local humanoid = character.Humanoid
	local animator = humanoid.Animator

	local castAnim = Instance.new("Animation")
	castAnim.AnimationId = "rbxassetid://14320972213"

	local castAnimTrack = animator:LoadAnimation(castAnim)

	local projectile = workspace.Particles.EnergyParticle
	local projectileClone = projectile:Clone() --need to add overlapparams
	local hitbox = Instance.new("Part")
	hitbox.Parent = projectileClone
	hitbox.Transparency = 1
	hitbox.Size = projectileClone.Size
	hitbox.CanCollide = false
	local weld = Instance.new("Weld")
	weld.Parent = hitbox
	weld.Part0 = hitbox
	weld.Part1 = projectileClone
	
	--hitbox.BrickColor = BrickColor.new("Really red") -- debug
	--hitbox.Material = "Neon" -- debug
	
	castAnimTrack:Play()

	task.wait(0.5)

	projectileClone.Parent = character
	projectileClone.CFrame = character.Torso.CFrame * CFrame.new(0,0,-10)

	local Distance = (projectileClone.Position - target.Position).magnitude
	local Time = GetTime(Distance, Speed)

	local spellTween = TS:Create(projectileClone, TweenInfo.new(Time, Enum.EasingStyle.Linear), {CFrame = CFrame.new(target.Position)})
	spellTween:Play()

	hitbox.Touched:Connect(function(hit)
		if hit.Parent.Name ~= player.Name and hit.Parent.ClassName == "Model" and debounce == true then
			debounce = false
			hit.Parent.Humanoid.Health -= math.random(15,35)
			hitbox.Size = Vector3.new(8,8,8)
			projectileClone.ParticleEmitter:Emit(200)
			spellTween:Cancel()
			wait(0.4)
			hitbox:Destroy()
			projectileClone:Destroy()
			debounce=true	
		end
	end)

	if projectileClone and hitbox then
		spellTween.Completed:Wait()
		projectileClone.ParticleEmitter:Emit(200)
		task.wait(0.4)
		hitbox:Destroy()
		projectileClone:Destroy()
	end
end)
1 Like

Pretty decent code, well first of all I think the optimization on this code is fine and shouldn’t cause mostly any lag, but there are improvements that could be made.

You could for example replace spellTween with bodymovers and calculate the direction of the mouseHit from player. This could mitigate the issue with fireball passing throught objects.

You could then instead of using Hitbox.Touched use GetPartsInPart BUT I’m not sure if its more performant or not, you would probably have to test this.

The code is otherwise fine as far as I can see.

1 Like