Should we use server scripts instead of local scripts for GUI buttons?

Before you crucify me, or perhaps just assume this post is asking “which script do I use for gui!!!11!!” consider this which you might not have known:


Server scripts can detect client side GUI button presses on the server. Obviously that’s ridiculous because GUI is exclusively on the client, so Roblox must do some weird background data transfer to allow this to happen.

Screenshot 2021-11-05 233700

Using this set up, with this script:

script.Parent.MouseButton1Click:Connect(function()
	print("This button was detected ON THE SERVER!")
end)

I was able to pull off what you see in the video. Before you tell me this is just a studio thing, you’re wrong I tested this in the real playable game and it works.

So now, on to my real question!
For security purposes, when a GUI button does some task that requires server authentication, should I use a server script for that? It’s extremely taboo to use a server script in PlayerGui, but this saves the vulnerability of using RemoteEvents and is literally unhackable.

Let me know what you think, or if like me you didn’t know about this nifty trick until now.

Guess I never knew that. I use them all the time :man_shrugging:

1 Like

It works but if you modify the StarterGui from a server script then whatever is performed on the UI will reflect to every client in the server. Modifying a player’s PlayerGui from the server, while considered taboo, can be done to modify a player’s UI exclusively.

In days of yore, Roblox had almost everything set up to run in either type of script. The exception being security critical stuff like badges and data persistence. It is certainly taboo, and just because it currently works does not mean it always will. I, and many others, feel that server stuff should be kept separate even if just for organizing. If you can enter your game knowing that all the server stuff is in ServerScriptService and all the GUI stuff was LocalScripts in the GUIs or player, it can be a lot easier to find what you want to find.

The taboo bit is because you’re managing input on the server. That is always taboo, though technically it won’t cause issues in your case assuming nothing changes.

2 Likes

You should not be using a ServerScript from anywhere inside of your client, it’s a bad practice to get into.

Yes, you can detect UI events from the server. Should you be doing it? Probably not. There’s no real reason to put that extra load directly on the server when you could just use Remote listeners. It’s not commonplace and you won’t really see other people doing it.

There is nothing weird about it working. Finding it weird stems from a misunderstanding of the Client-Server model that Roblox exists under. Every object in your game is being replicated from the server. PlayerGui is nothing more than the server cloning StarterGui objects into it when a player joins / respawns (depending on what properties are enabled). This is to say that your PlayerGui is effectively no different from any other instance the server clones. It can and will register events that occur to it, because it is being replicated from the server ← (afaik).

Instances that interact individually with the client should be handled by the client. You want them to have active feedback in the event that they are (/experiencing high latency / disconnecting entirely/). There are very few circumstances that you should stray away from that concept.

There is also no guarantee that this will work forever. Aim for code longevity.

2 Likes

Yeah, pre-filtering enabled client-server replication was nearly everything.
So is this just a remnant of that still in the engine? If so I can see why you’re sceptical to use this as that does sound like something that would be removed.

As for organization, you’re right completely but my thoughts here are exclusively on security.

I actually find it weird because this behavior can be seen nowhere else within the engine post-filtering enabled.

If you want data to transfer from the client to the server now normally you would need to either send an event or have network ownership of a property to change.

I think this answers my question flawlessly though, the benefit of this behavior being extremely secure is highly outweighed by the fact that it relies on latency and you’re unable to filter the data transfer.
Also I agree that this is terrible practice and should not be taught to beginners.

1 Like

Jarod is probably more on track than I am with that, he’s been around for longer.

There are exceptions listed to the model listed at the link above, which shows this:
image

It may be that it just isn’t directly documented, or that they group it with ClickDetectors.

2 Likes

He’s not wrong on this actually. BasePart.Touched will detect touches independently on both the client and the server, but MouseButton1Click can only be detected natively on the client for obvious reasons. So even though it’s not much more work to add to the Roblox backend, it does still behave differently that most events under the surface. It’s pretty much irrelevant knowledge, but it does happen of course.

Even before FE, Roblox started to crack down on bad practices in this category. They added things like GetMouse/KeyDown/MouseMove/etc, which were LocalScript-specific.

So if you’re looking at this from a security standpoint, I can make the server do a ton of extra work with a spamclicker. If this were LocalScript based, you could add a debounce before you add overhead to a shared system and network. Obviously anyone malicious could just DDoS the server if they really cared, but as far as arbitrary security goes, it is more secure against certain types of attacks.

I’m actually more worried about new scripters learning bad practices without realising. This is a bad practice especially outside of Roblox, and client/server boundaries are something that new scripters struggle with even without muddying it up with weird, unexpected behaviors like this.

'cepting you’ve done more on Roblox as a whole and beat me into the dev forum. Thanks again for the help with that btw. <3

2 Likes

I think this is good for 2d gui games, i have a 2d game with a player scoring system, and using a remote event to save these changes is very risky as exploiters could falsify this information