Could this code be more optimised than it currently is?

I’m currently on making my game more optimised and cutting down on memory usage.
This is the most major optimisation of code I’ve made so far and I’d just like to know if I’m going in the right direction when it comes to optimisation.

local BP = script.Parent.Parent
local MM = BP:WaitForChild("Module_Management")

local Animation = MM:WaitForChild("Animations")
local SAnim = Animation:WaitForChild("Shoot")

local TM = require(BP:WaitForChild("ToolManagment"))
local Tween = require(MM:WaitForChild("Tweening"))
local animm = require(Animation)

local anim = require(SAnim).Q_Down
local anim2 = require(SAnim).Q_Up

local Kick = false
local Equipped = false
local Tool = script.Parent
local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()

local power = 0
local Angle = 0
local percent = 0
local enabled = false

local Direction = Enum.EasingDirection.Out
local Style = Enum.EasingStyle.Back

local Direction2 = Enum.EasingDirection.InOut
local Style2 = Enum.EasingStyle.Sine

local Duration1 = 0.15
local Duration2 = 0.2
local Duration3 = 0.3

Tool.Equipped:Connect(function()
	Equipped = true
end)

Tool.Unequipped:Connect(function()
	Equipped = false
end)

local Character = Player.Character

if not Character or Character.Parent then
	Character = Player.CharacterAdded:Wait()
end

local HRP = Character:WaitForChild("HumanoidRootPart")
local Head = Character:WaitForChild("Head")

local CC = workspace.CurrentCamera

local RA = "Right Arm"
local LA = "Left Arm"

local Key = "q"

local function Force(Ball)
	
	Kick = false
	
	local Angle = Vector3.new(math.huge, math.huge, math.huge)
	local AngleBar = HRP.CFrame.LookVector * power * 1.15
	local force
	
	if Angle >= 2 then
		force = AngleBar + Vector3.new(0, Angle + 10, 0)
	else
		force = AngleBar + Vector3.new(0, Angle, 0)
	end
	TM.ApplyForce(Ball, Angle, force, "HRP")
end

local function alreadytouched(Limb)
	for Table, Ball in pairs(Limb:GetTouchingParts()) do
		if Ball ~= nil and Ball.Name == "TPS" and Kick then
			Force(Ball)
		end
	end

	Limb.Touched:Connect(function(Hit)
		if Hit ~= nil and Hit.Name == "TPS" and Kick then
			Force(Hit)
		end
	end)

	Limb.TouchEnded:Connect(function(Hit)
		if Hit ~= nil and Hit.Name == "TPS" and Kick then
			Force(Hit)
		end
	end)
end


local function Calculate()
	local Value
	local Calc = math.asin((Head.Position.Y - CC.CFrame.Position.Y) / (Head.Position - CC.CFrame.Position).Magnitude)
	
	if Calc < math.rad(0) then
		return 0
	end
	
	if math.rad(0) < Calc then
		if not (math.rad(25) < Calc) then
			if Calc < math.rad(-55) then
				Calc = math.rad(-22)
			end
			Value = Calc
			return Value
		end
		
	else
		Value = Calc
		return Value
	end
	
	return math.rad(25)
end

Mouse.KeyDown:Connect(function(key)
	if Equipped == false then return end
	if TM.GetUsing() then return end
	if key ~= Key then return end
	TM.SetUsing(true)
	TM.showPowerBar()
	TM.setWindUp(true)
	
	Tween.TweenWeld(RA, CFrame.new(1.5, 0, 0), CFrame.new(1.2, 0.5, -0.5) * CFrame.fromEulerAnglesXYZ(-math.pi / 1, -5, 5), Direction2, Style2, Duration2)
	Tween.TweenWeld(LA, CFrame.new(-1.5, 0, 0), CFrame.new(-1.2, 0.5, -0.5) * CFrame.fromEulerAnglesXYZ(-math.pi / 1, 5, -5), Direction2, Style2, Duration2)

	for i, v in pairs(anim) do
		Tween.TweenWeld(i, animm[i], CFrame.new(0, 1.5, 0.2) * CFrame.fromEulerAnglesXYZ(Calculate(), 0, 0), Direction, Style, Duration1)
	end
	
	power = 35
	Angle = 0
	percent = 0
	enabled = true
	for i = 1, 20 do
		if TM.getWindUp() then
			power = power + 3.2
			Angle = Angle + 0.05
			TM.powerUp(i / 20)
			TM.AdjustPowerBarColour(255/20)
			local calculation = 100 / 20

			percent = percent + calculation
			Player.PlayerGui.Start.Bar.PowerBar.Percent.Text = "<i>"..percent.."%</i>"
			task.wait(0.03)
		end
	end
end)

Mouse.KeyUp:Connect(function(key)
	if TM.getWindUp() and TM.GetUsing() and Equipped == true and key == Key and enabled then
		enabled = false
		TM.setWindUp(false)
		Kick = true
			for i, v in pairs(anim) do
				for i2, v2 in pairs(anim2) do
					if i == i2 then	
					Tween.TweenWeld(i, v, CFrame.new(0, 1.5, -0.4) * CFrame.fromEulerAnglesXYZ(Calculate(), 0, 0), Direction, Style, Duration1)
				end
			end
		end	
		
		alreadytouched(Head)
		
		task.wait(0.5)
		TM.resetPowerBar()
		for i2, v2 in pairs(anim2) do
			Tween.TweenWeld(i2, CFrame.new(0, 1.5, -0.4) * CFrame.fromEulerAnglesXYZ(Calculate(), 0, 0), animm[i2], Direction, Duration3)
		end
		
		Tween.TweenWeld(RA, CFrame.new(1.2, 0.5, -0.5) * CFrame.fromEulerAnglesXYZ(-math.pi / 1, -5, 5), CFrame.new(1.5, 0, 0), Direction, Style2, Duration3)
		Tween.TweenWeld(LA, CFrame.new(-1.2, 0.5, -0.5) * CFrame.fromEulerAnglesXYZ(-math.pi / 1, 5, -5), CFrame.new(-1.5, 0, 0), Direction, Style2, Duration3)

		
		task.wait(0.25)
		Kick = false
		TM.ResetWelds()
		TM.SetUsing(false)
	end
end)

I can’t say for certain just due to the large amount of code and the module dependencies, but it looks alright.

Technically there’s always stuff you can use for optimization, you could define global variables locally for a few nano seconds of extra speed. I wouldn’t recommend this though as it makes writing code down the line much much harder and painful.


Some minor things

local Character = Player.Character

if not Character or Character.Parent then
	Character = Player.CharacterAdded:Wait()
end

-- Instead of that, just make this one line
local Character = Player.Character or Player.CharacterAdded:Wait()
math.rad(0) -- is 0, replace with 0

My main recommendation for your code would be to make your code more consistent, use a naming convention and clean up your variables.

By sticking to a certain naming convention as it will help you read your code and make edits down the line. In your code you have

local BP = script.Parent.Parent -- Abbreviated 
local MM = BP:WaitForChild("Module_Management")

local Animation = MM:WaitForChild("Animations") -- Not Abbreviated + PascalCase
local SAnim = Animation:WaitForChild("Shoot") -- Partially Abbreviated 

local TM = require(BP:WaitForChild("ToolManagment"))
local Tween = require(MM:WaitForChild("Tweening"))
local animm = require(Animation) -- camelCase

local anim = require(SAnim).Q_Down -- More camelCase 
local anim2 = require(SAnim).Q_Up -- (Not sure why you didn't just require(SAnim) above)

...

local power = 0 -- camelCase
local Angle = 0 -- AHHHH (imposter moment)
local percent = 0
local enabled = false

Personally, I define my variables using the following naming convention
Feel free to mess around and do whatever though, I know a lot of scripters who love to use camelCase for everything and some who just use PascalCase for everything

-- Services (PascalCase, full name)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Modules (PascalCase)
local ModuleFolder = ReplicatedStorage:WaitForChild("Modules")
local SomeModule = require(ModuleFolder:WaitForChild("Something")

-- Constants (UPPER_CASE. If I don't have any, I just remove this section)
local MAX_PLAYERS = 123

-- Variables (Pascal for paths, camelCase for otherwise)
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local RemoteThing = Remotes:WaitForChild("Thing")

local player = Players.LocalPlayer
local debounce = true

-- Functions (camelCase)
local function foo(argument)

end

-- Core (Connections, loops, etc etc)
player.CharacterAdded:Connect(foo)

Outside of that, In terms of consistency in your code

-- Guard Clauses here
Mouse.KeyDown:Connect(function(key)
	if Equipped == false then return end
	if TM.GetUsing() then return end
	if key ~= Key then return end
    ...

-- Giant if and statement there
Mouse.KeyUp:Connect(function(key)
	if TM.getWindUp() and TM.GetUsing() and Equipped == true and key == Key and enabled then	

That’s all I got to say, gl coding :slight_smile:

3 Likes

Thanks for the advice!

On the term of consistency, the code has been coded months apart (the first time I wrote the script was in December of last year and i didn’t really think that changing the stuff to be more consistent would be that necessary lol

Instead of Vector3.new(0,1,0) you can write Vector3.new(0,1).
Vector3.new() will return 0,0,0.
Instead of math.rad(0),math.rad(55) just write result of function.
These are the basics of optimizing.
If you want to learn more about optimizing your code you can write to me.
Edit:
So about Vector3.new() and Vector3.new(1,1,1)
using Vector3.zero will give the same result but it will be %70 cheaper and faster same for Vector3.one.

1 Like