Is it fine to have nested functions in my script?

I have a function that includes multiple functions inside the same, called nested functions. Is it fine to do so? Follow the function:

local Click = function() -- função quando clicar no botão roll
	if dbs.db then return end -- se db for verdadeiro, retorne nada
	dbs.db2 = false -- seta db2 como false
	dbs.db = true -- seta db como true

	local Numero = tonumber(Texto.Text)

	local roletado = Rolled:InvokeServer()
	local Estrela_Clone = clone(Estrela, RollGui)

	local determination_tween = Module_Tween(Heart, infos.info3(Numero), properties.property3)
	local pos_estrela = Module_Tween(Estrela_Clone, infos.info4(Numero), properties.property4)
	local tamanho_estrela = Module_Tween(Estrela_Clone, infos.info5(Numero), properties.property5)
	local rotacao_estrela = Module_Tween(Estrela_Clone, infos.info6(Numero), properties.property6)

	local Estrela_tamanho = Module_Tween(Estrela_Clone, infos.info7(Numero), properties.property7)
	local Estrela_aumentar = Module_Tween(Estrela_Clone, infos.info8(Numero), properties.property8)
	local Estrela_rotacionar = Module_Tween(Estrela_Clone, infos.info9(Numero), properties.property9)
	local Estrela_transparente = Module_Tween(Estrela_Clone, infos.info10(Numero), properties.property10)

	local RollFrame_Time = function()
		local rollframe_clone = clone(RollFrame, RollGui)

		local aumentar_x = Module_Tween(rollframe_clone, infos.info11(Numero), properties.property11)
		local aumentar_y = Module_Tween(rollframe_clone, infos.info11(Numero), properties.property12)
		local diminuir_x = Module_Tween(rollframe_clone, infos.info11(Numero), properties.property13)

		local LoopFor = function()
			for _,v in pairs(rollframe_clone:GetChildren()) do
				if Isa(v, "TextButton") then

					local Evento_Chamada = function()
						local bindable = bindablefunction:Invoke(v.Name, roletado) -- Invokar bindablefunction, com parâmetro nome e roll
						local escolhido = rollframe_clone[t[not bindable]] -- armazenar escolhido, pegando o index notbindable(boolean) de t(boolean) de rollframeclone(frame). Uma forma de checar se o jogador apertou equip ou leave

						local Loop_Cor = function() -- uma coroutine que tem como argumento uma função que é automaticamente tocada
							while Taskwait(.15/Numero) do -- loop que espera 0.3 segundos até o próximo
								v.TextColor3 = Color3New(1, 1, .412) -- mudar cor para amerelo claro
								Taskwait(.15/Numero) -- esperar 0.3 segundos
								v.TextColor3 = Color3New(255,255,255) -- mudar cor para branco
							end
						end

						local LoopTransparencia = function() -- função que muda a transparência do objeto
							v.Active = false -- setar v.Active como falso

							for numero = 0, 1, .025 do -- loop que itera até 1, com o ínicio de 0 e incremento de 0.05
								escolhido.TextTransparency = numero -- atualizar transparência para o número
								Heartebeat:Wait() -- esperar até o próximo frame Heartbeat
							end
						end

						local LoopTransparencia2 = function() -- função que muda a transparência do objeto
							for i = 0, 1, .025 do
								rollframe_clone.UIStroke.Transparency = i
								Heartebeat:Wait()
							end
						end

						local Reset_DT_Value = function() -- função que reseta a posição do DT
							local T = Module_Tween(Heart, infos.info3(Numero), properties.property14(OldPosHeart))
							Tween_Audio_Play(T)

							dbs.db = false
						end

						local Corotina = Coroutinewrap(Loop_Cor) -- encapsular LoopCor em uma corotina

						TocarFuncoes({
							[1] = {LoopTransparencia},
							[2] = {Destroy_Instance, escolhido},
							[3] = {Corotina},
							[4] = {Taskwait, .5/Numero},
							[5] = {Tween_Audio_Play, aumentar_x},
							[6] = {Event, "Completed", aumentar_x, TocarFuncoes, "Once", 
								{
									[1] = {Tween_Audio_Play, diminuir_x},
									[2] = {Reset_DT_Value},
									[3] = {LoopTransparencia2},
									[4] = {Destroy_Instance, rollframe_clone}
								}
							}
						})
					end

					Event("Activated", v, Evento_Chamada, "Once")
				end
			end
		end

		TocarFuncoes({
			[1] = {Atualizar_Info, roletado, rollframe_clone, RollGui},
			[2] = {Tween_Audio_Play, aumentar_x},
			[3] = {Event, "Completed", aumentar_x, Tween_Audio_Play, "Once", aumentar_y},
			[4] = {LoopFor}
		})
	end

	local Efeitos = function()

		local Blur = InstanceNew("BlurEffect", CurrentCamera, {
			Name = "Momentary Blur",
			Size = 0
		})

		local Iluminacao = clone(Ilum, RollGui)

		local UIG = Iluminacao.UIGradient
		local NV, NV2 = UIG.NV, UIG.NV2

		local Diminuir_FieldOfView, AumentarSize = Module_Tween(CurrentCamera, infos.info11(Numero), properties.property16), Module_Tween(Blur, infos.info12(Numero), properties.property15)
		local Aumentar_FieldOfView, DiminuirSize = Module_Tween(CurrentCamera, infos.info12(Numero), properties.property17), Module_Tween(Blur, infos.info12(Numero), properties.property18)
		local NV_T, NV2_T = Module_Tween(NV, infos.info13(Numero), properties.property19), Module_Tween(NV2, infos.info13(Numero), properties.property20)
		local NV2_T_Reset = Module_Tween(NV2, infos.info14(Numero), properties.property21)

		local InputBeganWait = function()

			local function LoopWhile()
				while true do
					local input = InputBegan:Wait()

					local UserInputType = input.UserInputType

					local Mapeamento = {
						[Enums.Outros.Mouses.MouseButton1] = true,
						[Enums.Outros.Mouses.MouseButton2] = true,
						[Enums.Outros.Mouses.MouseButton3] = true,
					}

					if Mapeamento[UserInputType] then break end
				end
			end

			TocarFuncoes({
				[1] = {Taskwait, .5/Numero},
				[2] = {LoopWhile},
				[3] = {Event, "Cancel", NV2_T},
				[4] = {function() NV_T = nil end},
				[5] = {Tween_Audio_Play, NV2_T_Reset},
			})

		end

		local NV_Mains = function(Objeto)

			if Objeto == NV and (not NV_T) then return end

			local function Sequencia_Handler(value)
				local NumberSequenceMapeamento = {
					["NV"] = {
						NumberKeypointNew(0, 1),
						NumberKeypointNew(value, 1),
						NumberKeypointNew(1, NV2.Value)
					},

					["NV2"] = {
						NumberKeypointNew(0, 1),
						NumberKeypointNew(NV.Value, 1),
						NumberKeypointNew(1, value)
					}
				}

				local Sequencia = NumberSequenceMapeamento[Objeto.Name]

				UIG.Transparency = NumberSequenceNew(Sequencia)
			end

			Event("Changed", Objeto, Sequencia_Handler, "Connect")

		end

		TocarFuncoes({ 
			[1] = {TocarVarios, "Play", Diminuir_FieldOfView, AumentarSize},
			[2] = {TocarVarios, "Play", NV2_T, NV_T},
			[3] = {NV_Mains, NV},
			[4] = {NV_Mains, NV2},
			[5] = {InputBeganWait},
			[6] = {TocarVarios, "Play", Aumentar_FieldOfView, DiminuirSize},
			[7] = {Event, "Completed", DiminuirSize, Destroy_Instance, "Once", Blur},
		})
	end

	TocarFuncoes({
		[1] = {Increment, Increment_Stats, Rolls, Jackpots},

		[2] = {TocarVarios, "Play", determination_tween, pos_estrela, tamanho_estrela, rotacao_estrela},

		[3] = {Event, "Completed", tamanho_estrela, TocarFuncoes, "Connect", {
			[1] = {Efeitos},
			[2] = {Tween_Audio_Play, Estrela_tamanho},
			[3] = {Event, "Completed", Estrela_tamanho, TocarFuncoes, "Connect", 
				{
					[1] = {TocarVarios, "Play", Estrela_aumentar, Estrela_rotacionar, Estrela_transparente},
					[2] = {Event, "Completed", Estrela_aumentar, Destroy_Instance, "Connect", Estrela_Clone},
					[3] = {Taskwait, .15/Numero},
					[4] = {RollFrame_Time},
				}
			}
		}}
	})
end

The variables name don’t matter, but the main question is here.

It shouldn’t affect the performance of the script, but it can get cluttered easily. Depends on whether you want to be organised or not. :woman_shrugging:

I mean, for me it looks really Organized. I mainly did it because it was really ugly outside the function

Depends on the context and reusability. If you think you will only use these functions only within that function and you think that is readable to you. Then go ahead.

However in my preference I would generally rearrange it so the functions are out of that function in case for later reuse.

2 Likes

Yea sure! I’ll mark your response as the solution, as it gave me some answers to my inner questions. Thank you, @GoodUsername777 and @Deb0rahAliWilliams

It does affect the performance, because you are creating functionB every time functionA is called instead of it being in memory. Depending on what functionB is doing, it may cause a noticeable effect, but most of the time you won’t notice it, but it does have a performance degradation effect, for sure.

So in my case, is it better to prefer not to use nested functions?

I don’t think it will matter unless you need maximized efficiency for your game (which you probably don’t). I have a game that generates terrain infinitely, so in a case like that, and depending on the functionality usage, id opt for having them outside of the function.

You should be fine in your case.

1 Like

Thank you! I’m actually doing a table with functions inside now, to maintain optimization:

local EC = {

	LOOPS = {

		Cores = {

			[1] = function(Numero, v)

				local Tempo = NovoTempo(.15, Numero)

				while esperar(Tempo) do
					v.TextColor3 = Color3New(1, 1, .412)
					esperar(Tempo)
					v.TextColor3 = Color3New(255,255,255)
				end

			end,

		},

		Transparencias = {

			[1] = function(v, escolhido)

				local Inicio = 0
				local Goal = 1
				local Incremento = .025

				v.Active = false

				for numero = Inicio, Goal, Incremento do

					escolhido.TextTransparency = numero
					Heartebeat:Wait()

				end

			end,

			[2] = function(Stroke)

				local Inicio = 0
				local Goal = 1
				local Incremento = .025

				for i = Inicio, Goal, Incremento do

					Stroke.Transparency = i
					Heartebeat:Wait()

				end

			end,

		}

	},

	OUTROS = {

		ResetDT = function(Numero)

			local T = Module_Tween(Heart, infos.info3(Numero), properties.property14(OldPosHeart))

			Tween_Audio_Play(T)

			dbs.db = false

		end,

	}

}
1 Like

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