Best way to control UI with only 1 LocalScript

I’ve seen a lot people talk about this whole 1 script structure, and while I’ve done it with ServerSide scripts, the client side is a different story.

Long ago I used to just have 1 long local script that would basically handle everything in the UI. That became really cluttered and a nightmare to navigate, so I tried just using 1 local script and then have a module inside each ‘menu’ of the UI (shop, other menus, etc.) and then use the 1 local script to just require all those modules.

So my question is, is having a module control each menu the best practice? Or should I just use 1 script to control everything? Or is this simply just up to personal preference.

Not sure if this actually belongs in Scripting Support

1 Like

Server-side one-script structures are the same as client-side one-script structures, simply the organisation of them differs due to the scope of the actions they’re responsible for handling.

I personally use a single LocalScript per Gui that I’ve made for some years now and it’s worked perfectly for me. That single LocalScript directly descends a LayerCollector (ScreenGui, SurfaceGui or BillboardGui) and accesses all the Gui’s children as necessary.

As far as organisation goes, I split repeat responsibilities by ModuleScript and handle the rest through an organised main script and do-end blocks. They help for collapsing specific chunks of code. I add a comment to the side to briefly explain what a block does, typically under a few characters.

-- Small test chunk
do
    print("FOO BAR")
end

Truthfully, it’s all personal preference. It’s often suggested to work with ModuleScripts to keep that transferrable skill for other languages where you don’t get the same leeway as programming on Roblox, but we’re in Roblox and it’s your choice.

I can hardly think of a way in which using one or the other may change the effectiveness of your Gui, unless you have functions to expose to external scripts (which can easily be done via bindables and remotes).

4 Likes

Im sure people will disagree with me… but I am going to say it anyway…

Its personal preference… Using 1 script has its benefit such as updating so you don’t have to go through every single script but if you have to scroll through several thousand lines it has the same effect.

One way I personally use often… is to go a more a simple way and have values inside of each button and let them tell me what it needs to do… (Not to mention I don’t care for module scripts at all)

A easy example of this that I done was with a dev product/gamepass gui. With this I have 1 script inside and 2 values inside of each button that tells me what I need to do… The 2 values are labeled Product(Bool) and ID(For the product/gamepassID) of course…

This makes this very easy and simple to either add more or edit the current one… Instead of having to go through 10 or so gamepasses, I can go through a 60 line script.

https://gyazo.com/ab7a7879bfe61c7aeeab6f48eb1e1eb1

With just a little bit of simple code through a loop, you can easily go through all of the items and control them simultaneously

	for i,v in pairs(script.Parent.Money:GetChildren()) do
		v.Activated:Connect(function()
			if v:FindFirstChild("Product") then
				MPS:PromptProductPurchase(game.Players.LocalPlayer, v.ID.Value)
			elseif not v:FindFirstChild("Product") then
				if not MPS:UserOwnsGamePassAsync(game.Players.LocalPlayer.UserId, v.ID.Value) then
					MPS:PromptGamePassPurchase(game.Players.LocalPlayer, v.ID.Value)
				end
			end
		end)
		v.MouseEnter:Connect(function()
			for b,o in pairs(v:GetChildren()) do
				if not o:IsA("NumberValue") and not o:IsA("BoolValue") then
					local position = UDim2.new(-3.5,0,o.Position.Y.Scale, 0)
					o:TweenPosition(position, "In", "Quad", .2)
					spawn(function()
						wait(2)
						local position2 = UDim2.new(5,0,o.Position.Y.Scale, 0)
						o:TweenPosition(position2, "In", "Quad", .2)
					end)
				end
			end
		end)
		v.MouseLeave:Connect(function()
			for b,o in pairs(v:GetChildren()) do
				if  not o:IsA("NumberValue") and not o:IsA("BoolValue") then
					local position = UDim2.new(5,0,o.Position.Y.Scale, 0)
					o:TweenPosition(position, "Out", "Quad", .2)
				end
			end
		end)
	end

https://gyazo.com/8650319eea01a4bb9295cbf37fbc12f2

I have gotten bad about using this method just because of the fact that is quick. My friends that program go to look at this wondering what I done… This method is a bit more complicated then the conventional method but works better by far!

Hope this has helped you!

2 Likes

I do this as well, don’t see anything wrong with it. However, I’d normally do this through a modulescript that would handle say (in your case) all the stuff on that side bar

1 Like