What can I do to improve this script?

Hi everyone, hope all is well.

I have a power-up script that semi-works.

It works whenever it wants to. It has always been unstable and it was always over-complicated for me to fix, and this is one of my last resorts.

Can anyone review the script and see what I can do to improve and fix, please? Thanks.

(If you guys want to test out the feature, I’ll try to create another place and use the same files associated with the power-ups so you can test them for yourselves.)

pcall(function()
	local player = game.Players.LocalPlayer
	local countdown = player.PlayerGui:WaitForChild("InGame").Assets.Countdown
	local icon = countdown.Icon
	local ui = player.PlayerGui:WaitForChild("Notification")
	local ts = game:GetService("TweenService")
	local text = ui:WaitForChild("Notification")
	local runservice = game:GetService("RunService")
	local context = game:GetService("ContextActionService")
	local sound = workspace.Sound.SFX.BoxSound
	local ticksound = workspace.Sound.UI.TickSound
	local EndDebounce = false
	local debounce = false
    local GlobalUISpring = require(game:GetService("ReplicatedFirst").Modules.EzUISpring.GlobalPreset)
	text.BackgroundTransparency = 1
	text.TextTransparency = 1
	local Subject
	-- Tweens

	local tweenInfo = TweenInfo.new(
		0.2, 
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.In)

	local tweenInfo2 = TweenInfo.new(
		0.5, 
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.In)

	local opennotif1 = {}
	opennotif1.BackgroundTransparency = 0
	opennotif1.Position = UDim2.new(0.373, 0,0.892, 0)

	local textnotif1 = {}
	textnotif1.TextTransparency = 0

	local closenotif1 = {}
	closenotif1.BackgroundTransparency = 1
	closenotif1.Position = UDim2.new(0.373, 0,1, 0)

	local textnotif2 = {}
	textnotif2.TextTransparency = 1

	local framein = {}
	framein.Position = UDim2.new(0.015, 0,0.18, 0)

	local frameout = {}
	frameout.Position = UDim2.new(-1, 0,0.18, 0)

	local vignetteblack = {}
	vignetteblack.ImageColor3 = Color3.fromRGB(0, 0, 0)

	local vignetteblue = {}
	vignetteblue.ImageColor3 = Color3.fromRGB(82, 134, 255)

	local vignettegreen = {}
	vignettegreen.ImageColor3 = Color3.fromRGB(154, 255, 111)

	--Open Tweens
	local opentweens = ts:Create(text, tweenInfo, opennotif1)
	local opentweent = ts:Create(text, tweenInfo, textnotif1)
	local fin = ts:Create(countdown, tweenInfo2, framein)

	--Close Tweens
	local closetweens = ts:Create(text, tweenInfo, closenotif1)
	local closetweent = ts:Create(text, tweenInfo, textnotif2)
	local fout = ts:Create(countdown, tweenInfo2, frameout)
	local vignettereturn = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblack)
	local vignetteblue = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblue)
	local vignettegreen = ts:Create(player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignettegreen)

	--Person In Box
	local function SetUpTouched(Object)
		local handleAction, runConn

		local Hitbox =  Object:WaitForChild("hitbox")

		local EXIT_RADIUS = Hitbox:GetAttribute("ExitRadius") or 12 -- how far away player needs to be for

		Hitbox.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") and Subject == nil then
				--print("Touched")
				Subject = hit
				ui.Enabled = true
				if script:GetAttribute("enableNotification", true) then
					opentweens:Play()
					opentweent:Play()
				end
				context:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
				context:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
				context:SetImage("OpenBox", "rbxassetid://12768386698")

				runConn = runservice.Heartbeat:Connect(function()
					local inRadius = true
					if Subject.Parent == nil then
						inRadius = false
					else
						local Distance = (Hitbox.Position - Subject.Position).Magnitude
						if Distance >= EXIT_RADIUS then
							inRadius = false
						end
					end

					if inRadius == false then
						runConn:Disconnect()
						--print("TouchEnded")
						EndDebounce = true
						if opentweens.PlaybackState == Enum.PlaybackState.Playing then
							opentweens.Completed:Wait()
						end
						if script:GetAttribute("enableNotification", true) then
							closetweens:Play()
							closetweent:Play()
						end
						context:UnbindAction("OpenBox")
						task.wait(0.5)
						ui.Enabled = false
						EndDebounce = false
						Subject = nil
					end
				end)
			end
		end)


		local PowerUp = Hitbox:GetAttribute("PowerUp")
		if PowerUp == "JumpBoost" then
			handleAction = function(actionName, inputState, _inputObject)
				if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
					context:UnbindAction("OpenBox")
					local cvalue = Hitbox:GetAttribute("Countdown")
					player.Character:WaitForChild("Humanoid").Died:Connect(function()
						cvalue = 0
						closetweens:Play()
						closetweent:Play()
						fout:Play()
						countdown.Visible = false
						countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
					end)
					sound:Play()
					countdown.Visible = true
					player:SetAttribute("PowerUp", PowerUp)
                    fin:Play()
					vignettegreen:Play()
                    icon.Image = "rbxassetid://14495774882"
                    local highlight = Instance.new("Highlight")
                    highlight.Parent = player.Character
                    highlight.OutlineTransparency = 0.1
                    highlight.FillTransparency = 1
                    highlight.OutlineColor = Color3.fromRGB(179, 255, 107)
                    highlight.OutlineTransparency = 1
                    local tween1 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                    local tween0 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                    tween1:Play()
					player.Character:WaitForChild("Humanoid").UseJumpPower = true
					player.Character:FindFirstChild("Humanoid").JumpPower = 95
					Object:FindFirstChild("box").Transparency = 1
					Object:FindFirstChild("box"):FindFirstChild("PointLight").Enabled = false
					Object:FindFirstChild("box"):FindFirstChild("ParticleEmitter").Enabled = false
					Hitbox.CanTouch = false -- maybe remove this?
					closetweens:Play()
					closetweent:Play()
					ui.Enabled = false		
					repeat
						if Object:FindFirstChild("hitbox") == nil then
							return
						end
						countdown.TextLabel.Text = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
						cvalue = cvalue - 1
						if cvalue <= 4 then
							countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
							ticksound:Play()
						end
						Object:FindFirstChild("hitbox"):SetAttribute("Countdown", cvalue)
						task.wait(1)
					until
					cvalue == 0
                    if cvalue == 0 then
                        tween0:Play()
						fout:Play()
						fout.Completed:Wait()
						player:SetAttribute("PowerUp", "")
						countdown.Visible = false
						vignettereturn:Play()
						countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                        player.Character:FindFirstChild("Humanoid").JumpPower = 50
                        tween0.Completed:Wait()
                        highlight:Destroy()
					end
				end
			end

		elseif PowerUp == "SpeedBoost" then
			handleAction = function(actionName, inputState, _inputObject)
				if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
					workspace.Gravity = 150
					context:UnbindAction("OpenBox")
					local cvalue = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
					sound:Play()
					countdown.Visible = true
					player:SetAttribute("PowerUp", PowerUp)
					fin:Play()
                    icon.Image = "rbxassetid://14495573983"
                    local highlight = Instance.new("Highlight")
                    highlight.Parent = player.Character
                    highlight.OutlineColor = Color3.fromRGB(115, 164, 255)
                    highlight.FillTransparency = 1
                    highlight.OutlineTransparency = 1
                    local tween1 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                    local tween0 = ts:Create(highlight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                    tween1:Play()
					vignetteblue:Play()
					script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
					player.Character:FindFirstChild("Humanoid").WalkSpeed = 40
					Object:FindFirstChild("box").Transparency = 1
					Object:FindFirstChild("box"):FindFirstChild("PointLight").Enabled = false
					Object:FindFirstChild("box"):FindFirstChild("ParticleEmitter").Enabled = false
					Hitbox.CanTouch = false
					closetweens:Play()
					closetweent:Play()
					ui.Enabled = false
					repeat
						if Object:FindFirstChild("hitbox") == nil then
							return
						end
						countdown.TextLabel.Text = Hitbox:GetAttribute("Countdown")
						if cvalue <= 4 then
							ticksound:Play()
							countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
						end
						cvalue = cvalue - 1
						Hitbox:SetAttribute("Countdown", cvalue)
						task.wait(1)
					until
					cvalue == 0
                    if cvalue == 0 then
                        tween0:Play()
						workspace.Gravity = 196.2
						script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
						fout:Play()
						fout.Completed:Wait()
                        player:SetAttribute("PowerUp", "")
						countdown.Visible = false
						vignettereturn:Play()
						countdown.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                        player.Character:FindFirstChild("Humanoid").WalkSpeed = 20
                        tween0.Completed:Wait()
                        highlight:Destroy()                        
					end
				end
			end

			player.Character:WaitForChild("Humanoid").Died:Connect(function()
				workspace.Gravity = 196.2
				local cvalue = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
				fout:Play()
				fout.Completed:Wait()
				countdown.Visible = false
				cvalue = 0
				return
			end)

		end
	end

	local function FindBoxesRecurring(Object)
		if Object.Name == "Box" and Object:isA("Model") then
			SetUpTouched(Object)
		end
		for _, child in pairs(Object:GetChildren()) do
			FindBoxesRecurring(child)
		end
	end

	workspace.DescendantAdded:Connect(function(Object)
		if Object.Name == "Box" and Object:isA("Model") then
			SetUpTouched(Object)
		end
	end)

	FindBoxesRecurring(workspace)
end)
1 Like

Remove the outside pcall(), with it there, it will eat any errors and you will not know what is going on unless you manually print the error result.

1 Like

I have and there’s no errors. It just doesn’t work when it wants to. Don’t get me wrong, it usually works, but it’s not stable.

What does it do when it doesn’t work?

I don’t wanna sound rude but I think you should really focus on formatting your code in a readable way, It’s all mushed together into a block, you shouldn’t use pcall() like that, it’s mostly for error handling and you aren’t using it like that. The reason you don’t encounter errors running your code is because of the pcall() outside.

1 Like

It doesn’t give the power up at all. The notification ‘Press E to Activate’ does not pop-up either. You have to go out of it’s hitbox and go back in for it to MAYBE work.

You’re not rude at all! I agree, I’ve been planning to reformat the whole thing. My friend suggested using pcall though I’m not sure. The entire script was a little rushed. I really need some help reconstructing it. :sweat:

If you break the script into separate pieces that each only have one way they can work or not work, it will be easier.

1 Like

I’ll try my best to do so, hopefully I won’t break anything in the process.

I’d say just redo it all and try to format it nicely, I’d recommend reading this Lua Style Guide.

I would redo it all, though it may sound like a stretch but I actually don’t know how I’m going to redo it. It took me and my friend (mostly my friend in fact) hours to construct this script because I was having multiple issues. I prefer reformatting the current code as much as I can and then asking what I can do about it to improve it here, heh.

Unless you mean slowly building a new script with the same script concept.

Hello!

I’ve updated the script by reformatting it from top to bottom, including Variable names, etc for better readability.

-- General Variables
local Player = game.Players.LocalPlayer
local EndDebounce = false
local debounce = false
local Subject
local GlobalUISpring = require(game:GetService("ReplicatedFirst").Modules.EzUISpring.GlobalPreset)

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

-- UI Instances
local NotificationUI = Player.PlayerGui:WaitForChild("Notification")
local NotificationText = NotificationUI:WaitForChild("Notification")
local CountDownFrame = Player.PlayerGui:WaitForChild("InGame").Assets.Countdown
local PowerUp_Icon = CountDownFrame.Icon

-- Sounds
local PowerUp_ActivatedSound = workspace.Sound.SFX.BoxSound
local TickSound = workspace.Sound.UI.TickSound

-- Properties
local PowerUp_Properties = {
    SpeedBoost = {
        Icon = "rbxassetid://14495573983",
        HighLightColor = Color3.fromRGB(115, 164, 255)
    },
    JumpBoost = {
        Icon = "rbxassetid://14495774882",
        HighLightColor = Color3.fromRGB(179, 255, 107)
    }
}

-- Tweens
local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
local tweenInfo2 = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.In)

local textnotif1 = {}
textnotif1.TextTransparency = 0
textnotif1.BackgroundTransparency = 0
textnotif1.Position = UDim2.new(0.373, 0,0.892, 0)

local textnotif2 = {}
textnotif2.TextTransparency = 1
textnotif2.BackgroundTransparency = 1
textnotif2.Position = UDim2.new(0.373, 0,1, 0)

local framein = {}
framein.Position = UDim2.new(0.015, 0,0.18, 0)

local frameout = {}
frameout.Position = UDim2.new(-1, 0,0.18, 0)

local vignetteblack = {}
vignetteblack.ImageColor3 = Color3.fromRGB(0, 0, 0)

local vignetteblue = {}
vignetteblue.ImageColor3 = Color3.fromRGB(82, 134, 255)

local vignettegreen = {}
vignettegreen.ImageColor3 = Color3.fromRGB(154, 255, 111)

--Open Tweens
local NotificationText_In = TweenService:Create(NotificationText, tweenInfo, textnotif1)
local CountDownFrame_In = TweenService:Create(CountDownFrame, tweenInfo2, framein)

--Close Tweens
local NotificationText_Out = TweenService:Create(NotificationText, tweenInfo, textnotif2)
local CountDownFrame_Out = TweenService:Create(CountDownFrame, tweenInfo2, frameout)
local Vignette_Black = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblack)
local Vignette_Blue = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblue)
local Vignette_Green = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignettegreen)

--Person Inside the HitBox
local function SetUpTouched(Object)
    local handleAction, RunConnection

    local Hitbox = Object:WaitForChild("hitbox")

    local EXIT_RADIUS = Hitbox:GetAttribute("ExitRadius") or 12 -- how far away player needs to be for

    Hitbox.Touched:Connect(function(Human)
        if Human.Parent:FindFirstChild("Humanoid") and Subject == nil then
            --print("Touched")
            Subject = Human
            NotificationUI.Enabled = true
            if script:GetAttribute("enableNotification", true) then
                NotificationText_In:Play()
            end
            ContextActionService:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
            ContextActionService:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
            ContextActionService:SetImage("OpenBox", "rbxassetid://12768386698")

            RunConnection = RunService.Heartbeat:Connect(function()
                local inRadius = true
                if Subject.Parent == nil then
                    inRadius = false
                else
                    local Distance = (Hitbox.Position - Subject.Position).Magnitude
                    if Distance >= EXIT_RADIUS then
                        inRadius = false
                    end
                end

                if inRadius == false then
                    RunConnection:Disconnect()
                    --print("TouchEnded")
                    EndDebounce = true
                    if NotificationText_In.PlaybackState == Enum.PlaybackState.Playing then
                        NotificationText_In.Completed:Wait()
                    end
                    if script:GetAttribute("enableNotification", true) then
                        NotificationText_Out:Play()
                    end
                    ContextActionService:UnbindAction("OpenBox")
                    task.wait(0.5)
                    NotificationUI.Enabled = false
                    EndDebounce = false
                    Subject = nil
                end
            end)
        end
    end)

    local function EffectFunction(TypeOfPower, Enabled)
        if Enabled == "Activate" then -- Effect Activated
            if TypeOfPower == "JumpBoost" then -- Grant Jump Effects
                Vignette_Green:Play()
                Player.Character:WaitForChild("Humanoid").UseJumpPower = true
                Player.Character:FindFirstChild("Humanoid").JumpPower = 95
            elseif TypeOfPower == "SpeedBoost" then -- Grant Speed Effects
                Vignette_Blue:Play()
                workspace.Gravity = 150
                script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
                Player.Character:FindFirstChild("Humanoid").WalkSpeed = 40
            end
        elseif Enabled == "Deactivate" then -- Effect Deactivated
            if TypeOfPower == "JumpBoost" then -- Revoke Jump effects
                Player.Character:FindFirstChild("Humanoid").JumpPower = 50
            elseif TypeOfPower == "SpeedBoost" then -- Revoke Speed effects
                workspace.Gravity = 196.2
                script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
                Player.Character:FindFirstChild("Humanoid").WalkSpeed = 20
            end
        end
    end

    local function PowerUpFunction(Icon, PowerUp_Box, HighlightColor)
        handleAction = function(actionName, inputState, _inputObject)
            if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
                ContextActionService:UnbindAction("OpenBox")
                local CountDownValue = Hitbox:GetAttribute("Countdown")

                -- If player dies
                Player.Character:WaitForChild("Humanoid").Died:Connect(function()
                    CountDownValue = 0
                    NotificationText_Out:Play()
                    CountDownFrame_Out:Play()
                    CountDownFrame.Visible = false
                    CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                end)

                -- Initializes
                PowerUp_ActivatedSound:Play()
                CountDownFrame.Visible = true
                Player:SetAttribute("PowerUp", PowerUp_Box)
                CountDownFrame_In:Play()
                PowerUp_Icon.Image = Icon

                -- Highlight Instance and it's properties
                local HighLight = Instance.new("Highlight")
                HighLight.Parent = Player.Character
                HighLight.OutlineTransparency = 0.1
                HighLight.FillTransparency = 1
                HighLight.OutlineColor = HighlightColor
                HighLight.OutlineTransparency = 1

                -- Tweens
                local ShowOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                local HideOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                ShowOutline:Play()

                EffectFunction(PowerUp_Box, "Activate") -- Gives the effects to the player

                -- Making the PowerUp Box invisible and uninteractable
                Object:FindFirstChild("box").Transparency = 1
                Object:FindFirstChild("box"):FindFirstChild("PointLight").Enabled = false
                Object:FindFirstChild("box"):FindFirstChild("ParticleEmitter").Enabled = false
                Hitbox.CanTouch = false

                -- Returns Tweens to their original state
                NotificationText_Out:Play()
                NotificationUI.Enabled = false		

                --Counts down the amount of time the effect will last till.
                repeat
                    if Object:FindFirstChild("hitbox") == nil then
                        return
                    end
                    CountDownFrame.TextLabel.Text = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
                    CountDownValue = CountDownValue - 1
                    if CountDownValue <= 4 then
                        CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
                        TickSound:Play()
                    end
                    Object:FindFirstChild("hitbox"):SetAttribute("Countdown", CountDownValue)
                    task.wait(1)
                until
                CountDownValue == 0

                -- When the effect is finished
                if CountDownValue == 0 then
                    HideOutline:Play()
                    CountDownFrame_Out:Play()
                    CountDownFrame_Out.Completed:Wait()
                    Player:SetAttribute("PowerUp", "")
                    CountDownFrame.Visible = false
                    Vignette_Black:Play()
                    CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                    EffectFunction(PowerUp_Box, "Deactivate")
                    HideOutline.Completed:Wait()
                    HighLight:Destroy()
                end
            end
        end
    end

    local PowerUp = Hitbox:GetAttribute("PowerUp")
    if PowerUp == "JumpBoost" then
        PowerUpFunction(PowerUp_Properties.JumpBoost.Icon, PowerUp, PowerUp_Properties.JumpBoost.HighLightColor)
    elseif PowerUp == "SpeedBoost" then
        PowerUpFunction(PowerUp_Properties.SpeedBoost.Icon, PowerUp, PowerUp_Properties.SpeedBoost.HighLightColor)
    end
    
    -- If player dies
    Player.Character:WaitForChild("Humanoid").Died:Connect(function()
        workspace.Gravity = 196.2
        local CountDownValue = Object:FindFirstChild("hitbox"):GetAttribute("Countdown")
        CountDownFrame_Out:Play()
        CountDownFrame_Out.Completed:Wait()
        CountDownFrame.Visible = false
        CountDownValue = 0
        return
    end)
    
end

-- Finds boxes inside Workspace
local function FindBoxesRecurring(Object)
    if Object.Name == "Box" and Object:isA("Model") then
        SetUpTouched(Object)
    end
    for _, child in pairs(Object:GetChildren()) do
        FindBoxesRecurring(child)
    end
end

workspace.DescendantAdded:Connect(function(Object)
    if Object.Name == "Box" and Object:isA("Model") then
        SetUpTouched(Object)
    end
end)

FindBoxesRecurring(workspace)

@HeartIeech , @azqjanna

I hope this is much more pleasant to the eye and legible rather then before.

(Sorry for taking a while, it took me a bit to reconstruct it.)

This is way better than what you posted before! you can put most functions in a module so it’s easier to reuse, try to minimize using variables for everything.

1 Like

I’m glad it’s much better! I’ll consider modulizing the functions tomorrow then. Though the problem still persists (though it’s not as prominent as it was before i heavily reorganized it)

Video (streamable.com)

Hopefully this shows what I mean exactly.
It’s not necessarily a game breaking bug, though I’d love if I could make it work perfectly.

Few things.

Using :FindFirstChild() a lot of times like right here is not good for performance:

A way to improve this is to use :WaitForChild instead.

Code:

--Counts down the amount of time the effect will last till.
repeat
	local hitbox = Object:WaitForChild("hitbox", math.huge)

	CountDownFrame.TextLabel.Text = hitbox:GetAttribute("Countdown")
	CountDownValue -= 1
	
	if CountDownValue <= 4 then
		CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
		TickSound:Play()
	end
	
	hitbox:SetAttribute("Countdown", CountDownValue)
	
	task.wait(1)
until CountDownValue == 0

This line is also unnecessary because you had a loop repeat until that value is 0, so there’s no need to check again.

Code:

-- When the effect is finished
HideOutline:Play()
CountDownFrame_Out:Play()
CountDownFrame_Out.Completed:Wait()
Player:SetAttribute("PowerUp", "")
CountDownFrame.Visible = false
Vignette_Black:Play()
CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
EffectFunction(PowerUp_Box, "Deactivate")
HideOutline.Completed:Wait()
HighLight:Destroy()

I’ve also noticed you have done this a lot:

UDim2.new(0.373, 0, 1, 0)

You can replace it with this:

UDim2.fromScale(0.373, 1)

I’ll keep looking for more improvements and keep you updated.

1 Like

Hi! Thanks for your awesome suggestions! I’ll work on it tomorrow, at the moment it’s 1AM. I’ll make sure to keep you updated when I commit these new changes!

Thank you for helping me improve the game :slight_smile:
(This goes for the others involved aswell)

Made a small edit on my other reply to add a variable called hitbox so you don’t have to keep referencing it.

I’ve noticed you have been using:

:isA("Model")

The above is deprecated and is replaced by:

:IsA("Model")

You also should not be using :FindFirstChild if you aren’t going to check if it actually found the child, because that will waste performance.

Examples:

You don’t check if :FindFirstChild(“hitbox”) returns anything so there’s no need to use :FindFirstChild.

Code:

local CountDownValue = Object.hitbox:GetAttribute("Countdown")

You also have an unnecessary return in the above function.

You don’t check if :FindFirstChild() returns anything here too, so it’s unnecessary.

Code:

local box = Object.box
box.Transparency = 1
box.PointLight.Enabled = false
box.ParticleEmitter.Enabled = false

No checks on the return value here either, so it’s an unnecessary :FindFirstChild.

Code:

local Humanoid = Player.Character and Player.Character:FindFirstChildWhichIsA("Humanoid")
	
if not Humanoid then
	return
end
	
if Enabled == "Activate" then -- Effect Activated
	if TypeOfPower == "JumpBoost" then -- Grant Jump Effects
		Vignette_Green:Play()
		Humanoid.UseJumpPower = true
		Humanoid.JumpPower = 95
	elseif TypeOfPower == "SpeedBoost" then -- Grant Speed Effects
		Vignette_Blue:Play()
		workspace.Gravity = 150
		script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
		Humanoid.WalkSpeed = 40
	end
elseif Enabled == "Deactivate" then -- Effect Deactivated
	if TypeOfPower == "JumpBoost" then -- Revoke Jump effects
		Humanoid.JumpPower = 50
	elseif TypeOfPower == "SpeedBoost" then -- Revoke Speed effects
		workspace.Gravity = 196.2
		script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
		Humanoid.WalkSpeed = 20
	end
end

Another small issue is that you’re not referencing every service at the top, so you use game.Players when you should be using game:GetService(“Players”).

Code:

-- Services
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")

-- Modules
local GlobalUISpring = require(ReplicatedFirst.Modules.EzUISpring.GlobalPreset)

-- General Variables
local Player = Players.LocalPlayer
local EndDebounce = false
local debounce = false
local Subject = nil

This also is not necessary because :GetAttribute does not have a second argument.

Code:

if script:GetAttribute("enableNotification") then

Completely revised code:

-- Services
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")

-- Modules
local GlobalUISpring = require(ReplicatedFirst.Modules.EzUISpring.GlobalPreset)

-- General Variables
local Player = Players.LocalPlayer
local PlayerGui = Player:WaitForChild("PlayerGui")
local EndDebounce = false
local debounce = false
local Subject = nil

-- UI Instances
local NotificationUI = PlayerGui:WaitForChild("Notification")
local NotificationText = NotificationUI:WaitForChild("Notification")
local InGame = PlayerGui:WaitForChild("InGame")
local CountDownFrame = InGame.Assets.Countdown
local PowerUp_Icon = CountDownFrame.Icon

-- Sounds
local PowerUp_ActivatedSound = workspace.Sound.SFX.BoxSound
local TickSound = workspace.Sound.UI.TickSound

-- Properties
local PowerUp_Properties = {
	SpeedBoost = {
		Icon = "rbxassetid://14495573983",
		HighLightColor = Color3.fromRGB(115, 164, 255)
	},
	JumpBoost = {
		Icon = "rbxassetid://14495774882",
		HighLightColor = Color3.fromRGB(179, 255, 107)
	}
}

-- Tweens
local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
local tweenInfo2 = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.In)

local textnotif1 = {}
textnotif1.TextTransparency = 0
textnotif1.BackgroundTransparency = 0
textnotif1.Position = UDim2.fromScale(0.373, 0.892)

local textnotif2 = {}
textnotif2.TextTransparency = 1
textnotif2.BackgroundTransparency = 1
textnotif2.Position = UDim2.fromScale(0.373, 1)

local framein = {}
framein.Position = UDim2.fromScale(0.015, 0.18)

local frameout = {}
frameout.Position = UDim2.fromScale(-1, 0.18)

local vignetteblack = {}
vignetteblack.ImageColor3 = Color3.fromRGB(0, 0, 0)

local vignetteblue = {}
vignetteblue.ImageColor3 = Color3.fromRGB(82, 134, 255)

local vignettegreen = {}
vignettegreen.ImageColor3 = Color3.fromRGB(154, 255, 111)

--Open Tweens
local NotificationText_In = TweenService:Create(NotificationText, tweenInfo, textnotif1)
local CountDownFrame_In = TweenService:Create(CountDownFrame, tweenInfo2, framein)

--Close Tweens
local NotificationText_Out = TweenService:Create(NotificationText, tweenInfo, textnotif2)
local CountDownFrame_Out = TweenService:Create(CountDownFrame, tweenInfo2, frameout)
local Vignette_Black = TweenService:Create(InGame.Vignette, tweenInfo, vignetteblack)
local Vignette_Blue = TweenService:Create(InGame.Vignette, tweenInfo, vignetteblue)
local Vignette_Green = TweenService:Create(InGame.Vignette, tweenInfo, vignettegreen)

--Person Inside the HitBox
local function SetUpTouched(Object)
	local handleAction, RunConnection

	local Hitbox = Object:WaitForChild("hitbox")

	local EXIT_RADIUS = Hitbox:GetAttribute("ExitRadius") or 12 -- how far away player needs to be for

	Hitbox.Touched:Connect(function(Human)
		if Human.Parent:FindFirstChild("Humanoid") and Subject == nil then
			--print("Touched")
			Subject = Human
			NotificationUI.Enabled = true
			if script:GetAttribute("enableNotification") then
				NotificationText_In:Play()
			end
			ContextActionService:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
			ContextActionService:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
			ContextActionService:SetImage("OpenBox", "rbxassetid://12768386698")

			RunConnection = RunService.Heartbeat:Connect(function()
				local inRadius = true
				if Subject.Parent == nil then
					inRadius = false
				else
					local Distance = (Hitbox.Position - Subject.Position).Magnitude
					if Distance >= EXIT_RADIUS then
						inRadius = false
					end
				end

				if inRadius == false then
					RunConnection:Disconnect()
					--print("TouchEnded")
					EndDebounce = true
					if NotificationText_In.PlaybackState == Enum.PlaybackState.Playing then
						NotificationText_In.Completed:Wait()
					end
					if script:GetAttribute("enableNotification", true) then
						NotificationText_Out:Play()
					end
					ContextActionService:UnbindAction("OpenBox")
					task.wait(0.5)
					NotificationUI.Enabled = false
					EndDebounce = false
					Subject = nil
				end
			end)
		end
	end)

	local function EffectFunction(TypeOfPower, Enabled)
		local Humanoid = Player.Character and Player.Character:FindFirstChildWhichIsA("Humanoid")
		
		if not Humanoid then
			return
		end
		
		if Enabled == "Activate" then -- Effect Activated
			if TypeOfPower == "JumpBoost" then -- Grant Jump Effects
				Vignette_Green:Play()
				Humanoid.UseJumpPower = true
				Humanoid.JumpPower = 95
			elseif TypeOfPower == "SpeedBoost" then -- Grant Speed Effects
				Vignette_Blue:Play()
				workspace.Gravity = 150
				script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
				Humanoid.WalkSpeed = 40
			end
		elseif Enabled == "Deactivate" then -- Effect Deactivated
			if TypeOfPower == "JumpBoost" then -- Revoke Jump effects
				Humanoid.JumpPower = 50
			elseif TypeOfPower == "SpeedBoost" then -- Revoke Speed effects
				workspace.Gravity = 196.2
				script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
				Humanoid.WalkSpeed = 20
			end
		end
	end

	local function PowerUpFunction(Icon, PowerUp_Box, HighlightColor)
		handleAction = function(actionName, inputState, _inputObject)
			if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
				ContextActionService:UnbindAction("OpenBox")
				local CountDownValue = Hitbox:GetAttribute("Countdown")

				-- If player dies
				Player.Character:WaitForChild("Humanoid").Died:Connect(function()
					CountDownValue = 0
					NotificationText_Out:Play()
					CountDownFrame_Out:Play()
					CountDownFrame.Visible = false
					CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
				end)

				-- Initializes
				PowerUp_ActivatedSound:Play()
				CountDownFrame.Visible = true
				Player:SetAttribute("PowerUp", PowerUp_Box)
				CountDownFrame_In:Play()
				PowerUp_Icon.Image = Icon

				-- Highlight Instance and it's properties
				local HighLight = Instance.new("Highlight")
				HighLight.Parent = Player.Character
				HighLight.OutlineTransparency = 0.1
				HighLight.FillTransparency = 1
				HighLight.OutlineColor = HighlightColor
				HighLight.OutlineTransparency = 1

				-- Tweens
				local ShowOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
				local HideOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
				ShowOutline:Play()

				EffectFunction(PowerUp_Box, "Activate") -- Gives the effects to the player

				-- Making the PowerUp Box invisible and uninteractable
				local box = Object.box
				box.Transparency = 1
				box.PointLight.Enabled = false
				box.ParticleEmitter.Enabled = false
				Hitbox.CanTouch = false

				-- Returns Tweens to their original state
				NotificationText_Out:Play()
				NotificationUI.Enabled = false		

				--Counts down the amount of time the effect will last till.
				repeat
					local hitbox = Object:WaitForChild("hitbox", math.huge)
					CountDownFrame.TextLabel.Text = hitbox:GetAttribute("Countdown")
					CountDownValue -= 1
					
					if CountDownValue <= 4 then
						CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
						TickSound:Play()
					end
					
					hitbox:SetAttribute("Countdown", CountDownValue)
					task.wait(1)
				until CountDownValue == 0

				-- When the effect is finished
				HideOutline:Play()
				CountDownFrame_Out:Play()
				CountDownFrame_Out.Completed:Wait()
				Player:SetAttribute("PowerUp", "")
				CountDownFrame.Visible = false
				Vignette_Black:Play()
				CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
				EffectFunction(PowerUp_Box, "Deactivate")
				HideOutline.Completed:Wait()
				HighLight:Destroy()
			end
		end
	end

	local PowerUp = Hitbox:GetAttribute("PowerUp")
	if PowerUp == "JumpBoost" then
		PowerUpFunction(PowerUp_Properties.JumpBoost.Icon, PowerUp, PowerUp_Properties.JumpBoost.HighLightColor)
	elseif PowerUp == "SpeedBoost" then
		PowerUpFunction(PowerUp_Properties.SpeedBoost.Icon, PowerUp, PowerUp_Properties.SpeedBoost.HighLightColor)
	end

	-- If player dies
	Player.Character:WaitForChild("Humanoid").Died:Connect(function()
		workspace.Gravity = 196.2
		
		local CountDownValue = Object.hitbox:GetAttribute("Countdown")
		CountDownFrame_Out:Play()
		CountDownFrame_Out.Completed:Wait()
		CountDownFrame.Visible = false
		CountDownValue = 0
	end)
end

-- Finds boxes inside Workspace
local function FindBoxesRecurring(Object)
	if Object.Name == "Box" and Object:IsA("Model") then
		SetUpTouched(Object)
	end
	for _, child in pairs(Object:GetChildren()) do
		FindBoxesRecurring(child)
	end
end

workspace.DescendantAdded:Connect(function(Object)
	if Object.Name == "Box" and Object:IsA("Model") then
		SetUpTouched(Object)
	end
end)

FindBoxesRecurring(workspace)
1 Like

I’ve tried applying all of your advice:

-- Services
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")

-- General Variables
local Player = Players.LocalPlayer
local EndDebounce = false
local debounce = false
local Subject

-- UI Instances
local NotificationUI = Player.PlayerGui:WaitForChild("Notification")
local NotificationText = NotificationUI:WaitForChild("Notification")
local CountDownFrame = Player.PlayerGui:WaitForChild("InGame").Assets.Countdown
local PowerUp_Icon = CountDownFrame.Icon

-- Sounds
local PowerUp_ActivatedSound = workspace.Sound.SFX.BoxSound
local TickSound = workspace.Sound.UI.TickSound

-- Properties
local PowerUp_Properties = {
    SpeedBoost = {
        Icon = "rbxassetid://14495573983",
        HighLightColor = Color3.fromRGB(115, 164, 255)
    },
    JumpBoost = {
        Icon = "rbxassetid://14495774882",
        HighLightColor = Color3.fromRGB(179, 255, 107)
    }
}

-- Tweens
local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
local tweenInfo2 = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.In)

local textnotif1 = {}
textnotif1.TextTransparency = 0
textnotif1.BackgroundTransparency = 0
textnotif1.Position = UDim2.fromScale(0.373, 0.892)

local textnotif2 = {}
textnotif2.TextTransparency = 1
textnotif2.BackgroundTransparency = 1
textnotif2.Position = UDim2.fromScale(0.373, 1)

local framein = {}
framein.Position = UDim2.fromScale(0.015, 0.18)

local frameout = {}
frameout.Position = UDim2.fromScale(-1, 0.18)

local vignetteblack = {}
vignetteblack.ImageColor3 = Color3.fromRGB(0, 0, 0)

local vignetteblue = {}
vignetteblue.ImageColor3 = Color3.fromRGB(82, 134, 255)

local vignettegreen = {}
vignettegreen.ImageColor3 = Color3.fromRGB(154, 255, 111)

--Open Tweens
local NotificationText_In = TweenService:Create(NotificationText, tweenInfo, textnotif1)
local CountDownFrame_In = TweenService:Create(CountDownFrame, tweenInfo2, framein)

--Close Tweens
local NotificationText_Out = TweenService:Create(NotificationText, tweenInfo, textnotif2)
local CountDownFrame_Out = TweenService:Create(CountDownFrame, tweenInfo2, frameout)
local Vignette_Black = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblack)
local Vignette_Blue = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignetteblue)
local Vignette_Green = TweenService:Create(Player.PlayerGui:WaitForChild("InGame").Vignette, tweenInfo, vignettegreen)

--Person Inside the HitBox
local function SetUpTouched(Object)
    local handleAction, RunConnection

    local Hitbox = Object:WaitForChild("hitbox")

    local EXIT_RADIUS = Hitbox:GetAttribute("ExitRadius") or 12 -- how far away player needs to be for

    Hitbox.Touched:Connect(function(Human)
        if Human.Parent:FindFirstChild("Humanoid") and Subject == nil then
            --print("Touched")
            Subject = Human
            NotificationUI.Enabled = true
            if script:GetAttribute("enableNotification", true) then
                NotificationText_In:Play()
            end
            ContextActionService:BindAction("OpenBox", handleAction, true, Enum.KeyCode.E, Enum.KeyCode.ButtonR1)
            ContextActionService:SetPosition("OpenBox", UDim2.new(1, -70, 0, 10))
            ContextActionService:SetImage("OpenBox", "rbxassetid://12768386698")

            RunConnection = RunService.Heartbeat:Connect(function()
                local inRadius = true
                if Subject.Parent == nil then
                    inRadius = false
                else
                    local Distance = (Hitbox.Position - Subject.Position).Magnitude
                    if Distance >= EXIT_RADIUS then
                        inRadius = false
                    end
                end

                if inRadius == false then
                    RunConnection:Disconnect()
                    --print("TouchEnded")
                    EndDebounce = true
                    if NotificationText_In.PlaybackState == Enum.PlaybackState.Playing then
                        NotificationText_In.Completed:Wait()
                    end
                    if script:GetAttribute("enableNotification", true) then
                        NotificationText_Out:Play()
                    end
                    ContextActionService:UnbindAction("OpenBox")
                    task.wait(0.5)
                    NotificationUI.Enabled = false
                    EndDebounce = false
                    Subject = nil
                end
            end)
        end
    end)

    local function EffectFunction(TypeOfPower, Enabled)
        local Humanoid = Player.Character and Player.Character:FindFirstChildWhichIsA("Humanoid")

        if not Humanoid then
            return
        end
        
        if Enabled == "Activate" then -- Effect Activated
            if TypeOfPower == "JumpBoost" then -- Grant Jump Effects
                Vignette_Green:Play()
                Humanoid.UseJumpPower = true
                Humanoid.JumpPower = 95
            elseif TypeOfPower == "SpeedBoost" then -- Grant Speed Effects
                Vignette_Blue:Play()
                workspace.Gravity = 150
                script.Parent.FOV.FOV.Value = script.Parent.FOV.FOV.Value + 10
                Humanoid.WalkSpeed = 40
            end
        elseif Enabled == "Deactivate" then -- Effect Deactivated
            if TypeOfPower == "JumpBoost" then -- Revoke Jump effects
                Humanoid.JumpPower = 50
            elseif TypeOfPower == "SpeedBoost" then -- Revoke Speed effects
                workspace.Gravity = 196.2
                script.Parent.FOV.FOV.Value = script.Parent.FOV.InitialFOV.Value
                Humanoid.WalkSpeed = 20
            end
        end
    end

    local function PowerUpFunction(Icon, PowerUp_Box, HighlightColor)
        handleAction = function(actionName, inputState, _inputObject)
            if actionName == "OpenBox" and inputState == Enum.UserInputState.Begin then
                ContextActionService:UnbindAction("OpenBox")
                local CountDownValue = Hitbox:GetAttribute("Countdown")

                -- If player dies
                Player.Character:WaitForChild("Humanoid").Died:Connect(function()
                    CountDownValue = 0
                    NotificationText_Out:Play()
                    CountDownFrame_Out:Play()
                    CountDownFrame.Visible = false
                    CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                end)

                -- Initializes
                PowerUp_ActivatedSound:Play()
                CountDownFrame.Visible = true
                Player:SetAttribute("PowerUp", PowerUp_Box)
                CountDownFrame_In:Play()
                PowerUp_Icon.Image = Icon

                -- Highlight Instance and it's properties
                local HighLight = Instance.new("Highlight")
                HighLight.Parent = Player.Character
                HighLight.OutlineTransparency = 0.1
                HighLight.FillTransparency = 1
                HighLight.OutlineColor = HighlightColor
                HighLight.OutlineTransparency = 1

                -- Tweens
                local ShowOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 0})
                local HideOutline = TweenService:Create(HighLight, TweenInfo.new(0.5, Enum.EasingStyle.Quint), {OutlineTransparency = 1})
                ShowOutline:Play()

                EffectFunction(PowerUp_Box, "Activate") -- Gives the effects to the player

                -- Making the PowerUp Box invisible and uninteractable
                local Box = Object.box
                Box.Transparency = 1
                Box.PointLight.Enabled = false
                Box.ParticleEmitter.Enabled = false
                Hitbox.CanTouch = false

                -- Returns Tweens to their original state
                NotificationText_Out:Play()
                NotificationUI.Enabled = false		

                --Counts down the amount of time the effect will last till.
                repeat
                    CountDownFrame.TextLabel.Text = Hitbox:GetAttribute("Countdown")
                    CountDownValue -= 1

                    if CountDownValue <= 4 then
                        CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 52, 55)
                        TickSound:Play()
                    end

                    Hitbox:SetAttribute("Countdown", CountDownValue)

                    task.wait(1)
                until CountDownValue == 0

                -- When the effect is finished
                HideOutline:Play()
                CountDownFrame_Out:Play()
                CountDownFrame_Out.Completed:Wait()
                Player:SetAttribute("PowerUp", "")
                CountDownFrame.Visible = false
                Vignette_Black:Play()
                CountDownFrame.TextLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
                EffectFunction(PowerUp_Box, "Deactivate")
                HideOutline.Completed:Wait()
                HighLight:Destroy()
            end
        end
    end

    local PowerUp = Hitbox:GetAttribute("PowerUp")
    if PowerUp == "JumpBoost" then
        PowerUpFunction(PowerUp_Properties.JumpBoost.Icon, PowerUp, PowerUp_Properties.JumpBoost.HighLightColor)
    elseif PowerUp == "SpeedBoost" then
        PowerUpFunction(PowerUp_Properties.SpeedBoost.Icon, PowerUp, PowerUp_Properties.SpeedBoost.HighLightColor)
    end

    -- If player dies
    Player.Character:WaitForChild("Humanoid").Died:Connect(function()
        workspace.Gravity = 196.2
        local CountDownValue = Object:WaitForChild("hitbox"):GetAttribute("Countdown")
        CountDownFrame_Out:Play()
        CountDownFrame_Out.Completed:Wait()
        CountDownFrame.Visible = false
        CountDownValue = 0
    end)

end

-- Finds boxes inside Workspace
local function FindBoxesRecurring(Object)
    if Object.Name == "Box" and Object:IsA("Model") then
        SetUpTouched(Object)
    end
    for _, child in pairs(Object:GetChildren()) do
        FindBoxesRecurring(child)
    end
end

workspace.DescendantAdded:Connect(function(Object)
    if Object.Name == "Box" and Object:IsA("Model") then
        SetUpTouched(Object)
    end
end)

FindBoxesRecurring(workspace)

What do you think?

1 Like

Looks good, you should use guard clauses for some of your functions though:

Okay, I’ll try to do that then. Though, how do I fix the actual issue that’s being bothersome, please?

I’ve attached a video in one of my posts:

Demonstrating the problem.

I’d really appreciate some help on that while I continue improving my code’s structure. :slight_smile: