My practices on RemoteEvent / RemoteFunction

My modern projects only have four instances for events/functions.

1 RemoteEvent, 1 RemoteFunction, 1 BindableEvent, 1 BindableFunction.

I’ve made this common practice because I can filter out any malformed fires a hacker may send without having to secure tons and tons of remotes.

Here’s how it usually works:

Client:

RemoteEvent:FireServer("SomeEventType", "abc", 123, Instance.new("Part"))

Server:

RemoteEvent.OnServerEvent:Connect(function (ClientThatFired, EventType, ...) local Args = {...} if EventType == "SomeEventType" then if #Args == 3 and typeof(Args[1]) == "string" and typeof(Args[2]) == "number" and typeof(Args[3]) == "Instance" then print("ya noob") end end end)

So there you have it. I suggest you do this as it can really rid of the clutter caused by having too many events. The only issue is remembering your EventType

It’s a compelling reason to advice against this, because you’re really killing the readability of your code/game if you also don’t have an overview of all your events listed elsewhere.

You could also just write a small wrapper function that first performs these checks and then calls some given function with the parameters, then you can do the same with multiple instances which improves readability.

Really it’s just a matter of what you prefer. I usually try to do what you explain here, but I can imagine why someone wouldn’t use just one instance.

I do this, but keep all the callbacks in a module. The script will check if there is an index in the modules’ returned table with the name listed, then call it with the Player & Other arguments.

This means it’s far more readable and you don’t have to use a giant messy case system. Only complication is making all your other modules accessible in in that Module without making it look messy.

I also have a really basic framework which uses a network module, so you can do stuff like

Network:Listen("RuntimeTeamChange",function(Player,TeamName)
	if not game.Teams[TeamName] then return end --Make sure the team exists!
	if (TeamName ~= "Malicious Roblox Bloxxors") or Player:IsInGroup(123) then --Either the team name isn't 'Malicious Roblox Bloxxors' or the Player is in the Malicious Roblox Bloxxors group
		Player.Team = game.Teams[TeamName]
		Player:LoadCharacter()
	end
end)

Not really protection, it just prevents your server code from erroring… which doesn’t really matter as the error shouldn’t expand beyond the listener anyway. I don’t think it’s worth making the server do more things? Side note: I’m pretty sure an Instance created on the client with FE will just come up as nil on the server.

Yeah good point lol

Might be worth mentioning that ROBLOX already sends over the “EventType” data through which remote you use. By adding an “EventType” argument, you’re kinda being redundant for the sake of syntactic sugar.

1 Like

It does? I’m not seeing anything on the OnServerEvent wiki page for instance – only sending player and developer-passed arguments.

I might’ve worded that weirdly. I did not mean it in the literal sense of an argument.

If you have several remotes (each for processing different types of events), then based on which one you fire your code can execute those events.

ROBLOX automatically networks the instance which was fired, and the arguments you supplied.
Because of this, there’s already an element that says what kind of event you’re networking.

1 Like

Oh, yeah. Some people like to use a single RemoteEvent for whatever reason though, and that’s why they need to manually specify what type of event it is.

I do the concept of what OP mentioned. I like it because it keeps remotes to a minimum and how centralized I can make things especially if I intend on adding security and other debugging processes.

How mine is formatted:

function MainInvoke.OnServerInvoke(Player,Data)
	local result,entity = pcall(function()
		local ChosenEvent = Data.Event
		local Args = Data
		
		if ChosenEvent == "Event" then
			return ExampleFunc(Player,Args.Param1,Args.Param2)
		end
	end)
end

One drawback is the huge decision structure you may end up with depending on how many remotes used.

God remotes make me cry. :sob:

As someone who originally did this, then decided to move to using separate remotes because I found out the hard way the problems this brings - I suggest not to do this.

Doing what OP does leads to huge amounts of spaghetti code with a huge control structure that ends up calling separate functions anyway - and also becomes a real nightmare to work with.

It’s like having a function called “doThings” which you just call from the rest of your code that does 100s of things. Sure it works, but doesn’t mean it’s good a good practice. Definitely not if you want to be able to work on it a couple of years later, or allow other people to work on your game as well.

A function, even a remote function or a remote event - should do what it describes, and only what it describes. “RemoteEvent” just makes it hard to even understand what the purpose of the event is. “Everything” you might say, well - how do I know there’s an argument for solving world hunger wihtout looking through a clusterfuck of control structures?

Security is a silly excuse, you can still secure remotes completely fine if they’re separate, in fact it (IMO) makes it easier because you can be very strict with what the remote itself accepts… especially since there’s this wonderful thing called assert you can use to ensure stuff complies with what the remote actually wants to recieve. :slight_smile:

You should already be modularizing everything. Clutter only happens if you’re keeping everything in a single script (which is another topic in itself that I could rant on about, but I’ll save you guys the read)


ModRemote is good if you want to be able to reference remotes by name (basically what you’re doing here), and not worry about remotes - I use it for Heroes’ Legacy and it works :ok_hand:

Please anyone who considers doing what OP does, don’t do it. It’ll help with your sanity later on as well as any other people who you might end up getting to help you with your game.

6 Likes