Spaghetti code or not?

Good day dear devs and programmers. I wanted to ask something related to a project I’ve been working on. “Is it smart to have one local script handle multiple visuals?” What I mean by this is: To have one script that handles for example: A loading screen, Main Menu, Crosshair and etc. The reason I’m asking this is because I have a local script that is 105 lines long which is quite a record for me since I’ve never written 100 lines of code :smiling_face_with_tear:

I just don’t wanna end up doing a yandere dev by having a code file that is littered with code to the point of the code being absolute spaghetti :disappointed:

--Services:
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local SoundService = game:GetService("SoundService")
local Lighting = game:GetService("Lighting")

--Variables:
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

--Player_Values:
--local PlayerValues = Character:WaitForChild("PlayerValues")
--local NumberValues = PlayerValues:WaitForChild("NumberValues")
--local Sanity = NumberValues:WaitForChild("Sanity")

--Extras:
local Camera = game.Workspace.CurrentCamera
local Music = SoundService:WaitForChild("Music")
local SFX = SoundService:WaitForChild("SFX")

--UI:
local PlayerGUI = Player:WaitForChild("PlayerGui")

local InjuredUI = PlayerGUI:WaitForChild("InjuredUI")
local InjuredFrame = InjuredUI:WaitForChild("Background")

local IntroUI = PlayerGUI:WaitForChild("IntroUI")
local Background = IntroUI:WaitForChild("Background")
local Image1 = Background:WaitForChild("Image1")
local Image2 = Background:WaitForChild("Image2")
local Text1 = Background:WaitForChild("Text1")
local Text2 = Background:WaitForChild("Text2")

--Functions:
local function CreateInjury()
	--Objects:
	local Blur = Lighting.Blur
	Blur.Size = 0
	local Heartbeat = SFX:WaitForChild("Heartbeat")
	local Music = Music:WaitForChild("Injured")
	Music:Play()
	
	--Tweens:
	TweenService:Create(Blur, TweenInfo.new(0.25, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, -1, true), {Size = 10}):Play()
	Heartbeat:Play()
	TweenService:Create(Camera, TweenInfo.new(0.35, Enum.EasingStyle.Linear, Enum.EasingDirection.In, -1, true), {FieldOfView = 80} ):Play()
	TweenService:Create(InjuredFrame, TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {BackgroundTransparency = 0.2}):Play()
end

local function RemoveInjury()
	local Blur = Lighting:WaitForChild("Blur")
	local Heartbeat = SFX:WaitForChild("Heartbeat")
	local Music = Music:WaitForChild("Injured")
	
	
	--Tweens:
	TweenService:Create(Heartbeat, TweenInfo.new(0.5), {Volume = 0}):Play()
	TweenService:Create(Music, TweenInfo.new(0.5), {Volume = 0}):Play()
	
	TweenService:Create(Blur, TweenInfo.new(0.25, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {Size = 0}):Play()
	TweenService:Create(Camera, TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.In), {FieldOfView = 70} ):Play()
	TweenService:Create(InjuredFrame, TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {BackgroundTransparency = 1}):Play()
end

Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	if Humanoid.Health <= 50 then
		CreateInjury()
	else
		RemoveInjury()
	end
	
	Humanoid.Died:Connect(function()
		RemoveInjury()
	end)
end)

if game:IsLoaded() == false then game.Loaded:Wait()
	local Notification = SFX:WaitForChild("Notification")
	--Tweens:
	HumanoidRootPart.Anchored = true
	Background.BackgroundTransparency = 0

	task.wait(1)
	local Tween1 = TweenService:Create(Image1, TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, true), {ImageTransparency = 0})
	Tween1:Play()
	Tween1.Completed:Wait()
	local Tween2 = TweenService:Create(Image2, TweenInfo.new(2, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, true), {ImageTransparency = 0})
	Tween2:Play()
	Tween2.Completed:Wait()
	task.wait(3)

	Notification:Play()
	Text1.TextTransparency = 0
	task.wait(4)
	Notification:Play()
	Text2.TextTransparency = 0

	task.wait(2.5)
	local Tween3 = TweenService:Create(Text1, TweenInfo.new(1), {TextTransparency = 1})
	local Tween4 = 	TweenService:Create(Text2, TweenInfo.new(1), {TextTransparency = 1})
	Tween3:Play()
	Tween4:Play()

	Tween4.Completed:Wait()
	TweenService:Create(Background, TweenInfo.new(1), {BackgroundTransparency = 1}):Play()
	task.wait(1)
	HumanoidRootPart.Anchored = false
end

Here’s the code by the way so you can get a feeling of how it looks like

4 Likes

Too many WaitForChilds. They should only be used when you are trying to get an object that is to spawned or hasn’t loaded in the game. You don’t need it if you’re getting preloaded stuff.

You can use FindFirstChild or just reference them directly if you’re confident that they will load before the script can do the checking.

Use game:GetService("Player") for referencing Players.
Other than that I don’t see anything that is spaghetti in your code.

1 Like

Alright thanks, I just use WaitForChild to ensure that the object is fully loaded since whenever I do reference an object directly:

local Example = script.Example

Then I receive an error so I just use WaitForChild or FindFirstChild to ensure that an instance has loaded without any errors :slight_smile:

1 Like

But what I was asking about is: If it would be considered normal to have multiple Visuals being handled by one script like a Crosshair, Menu, Loading Screen etc :sweat_smile:

Use FindFirstChild but not WaitForChild unless you are waiting for an instance that hasn’t loaded yet. Referencing every single instance with WaitForChild is bad practice.

There’s no problem. You can also use a modulescript to handle multiple functions and have them usable by separate scripts.

Ohh…I thought FindFirstChild and WaitForChild did the same thing just one for the clientside and one for the serverside

Alright thanks pal, appreciate the help

So basically have the Visuals follow a modular structure right?

Both are usable for both scripts. FindFirstChild finds the first thing it can see with the given name of the first parameter.

1 Like

If you want, ModuleScripts are built for organization and for the functions/contents in it to be used by other scripts

Yeah, that’s true but I’ll stick to the functional structure for now this is jut for testing purposes :slight_smile:

1 Like

Well then, thanks for the help, goodbye :slight_smile:

To add, FindFirstChild takes 20% longer that using the dot operator.

These docs explain a bit more.
FindFirstChild

WaitForChild

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.