[hitsquad] FilteringEnabled: A primer (being revised)

Originally from this topic.

[quote] First, what is FilteringEnabled? FilteringEnabled is a division between the client and server. The client is no longer allowed to change server things, and the server is no longer allowed to change client things.

What the server and client can see. Note that even though the client can see other client’s PlayerGui, any changes made are not sent to other clients.

With FilteringEnabled turned off, the client can freely access and alter server things (aside from ServerScriptService and ServerStorage), and the server can freely access the PlayerGui and StarterGear. Turning FilteringEnabled on is like constructing a wall between client and server, tall but surmountable for the developer, but tall and impossible for an exploiter.

“That sounds really cool, but how do I turn FilteringEnabled on?”

When in Roblox Studio, open the Properties window and Explorer window and select “Workspace” in the explorer. On the properties window will be something called “FilteringEnabled”. Make sure that has a tick mark and FilteringEnabled is turned on.

ΓÇ£You mentioned that FilteringEnabled was like an impassable wall for exploiters, but not for developers. How do I get past that wall?ΓÇ¥

Like with telecommunications, you need three things: a sender, a medium, and a receiver.

The sender and the receiver can be both Scripts and LocalScripts, and the medium can be either a RemoteEvent or a RemoteFunction. You can even have the same Scripts and LocalScripts act as the sender and receiver at the same time, using the same medium. You can add RemoteThings anywhere and any Script and any LocalScript can access them and send data through each.

Both RemoteEvent and RemoteFunction are Roblox Instances and can be inserted in the game like any other Instance.

“So what can I do with these objects?”

The methods and events that are unique to the two objects are listed below with what they do.
RemoteEvent:
[ul]
[li]Functions:
[li]:FireClient(Player,Data) [i]Transfer from server to a specific client[i]
[li]:FireAllClients(Data) [i]Transfer from server to every client[i]
[li]:FireServer(Data) [i]Transfer from client to server[i]
[li]Events
[li].OnServerEvent(Client,Data) [i]A client has sent the server data[i]
[li].OnClientEvent(Data) [i]The server has sent a client data[i]
[/ul]
RemoteFunction:
[ul]
[li]Functions:
[li]:InvokeClient(Player,Data) [i]Transfer from server to a specific client[i]
[li]:InvokeServer(Data) [i]Transfer from server to every client[i]
[li].OnServerInvoke(Player,Data) [i]A client has sent the server data[i]
[li].OnClientInvoke(Data) [i]The server has sent the client data[i]
[/ul]

“There is only one Data argument! Does that mean I can only send one thing at a time?”

Not at all! The tehnical name for what the “Data” is happens to be something called. “Tuple” which means it can be any number of any type of thing. There is no real known limit to how many arguments you can have, but there are practical limits of how much information you should pass to any one function.
The below codes are examples of how Tuples can be used:

RemoteFunction:FireCliet(game.Players.Player1,"Heya!ΓÇ¥,BrickColor.new(ΓÇ£MauveΓÇ¥))
RemoteFunction:FireAllClients("Hi", true, workspace.Part1)

this applies to every time “Data” appears above.

“Aren’t we talking about clients, not Players?”

Since players are unique to each client, the client is specified by the player object. For example:

RemoteFunction:FireClient(game.Players.Player1,"Get to the choppa!")

“How do these RemoteEvent and RemoteFunction things work?”

RemoteEvent is simple. You tell it to fire with this info, and it will broadcast to a client, all clients, or the server, and the script will keep on going regardless.

RemoteFunction is a little more difficult, but still somewhat simple. Instead of being able to push stuff to the server or client instantly and not caring if it is received, RemoteFunction does care, and will yield until something is returned. For those who are not familiar with the term, yielding is what the wait() function calls. Basically, the script will wait() until the client/server returns some value using the [FONT=Courier New]return[/FONT] statement. Also, you can only invoke one client at a time instead of all at once, which makes sense because then the server would get a bunch of returns instead of only one.

“Can you use them in a [strike]sentence[/strike] script?”

Sure! I’ll even use them in two scripts for good measure.

To use a RemoteEvent, you will want to use something like this in your scripts:

Script

function DetermineSuccess(player, wasSuccessful)
    if wasSuccessful then
        print(player.." has successfully gotten the message")
    else
        print(player.." did not get the message :(")
    end
end

RemoteEvent:FireAllClients("Hey guys!")
RemoteEvent.OnServerEvent:connect(DetermineSuccess)

LocalScript

function PrintMessage(message)
    success = pcall(function() print(message) end)
    RemoteEvent:FireServer(success)
end

RemoteEvent.OnClientEvent:connect(PrintMessage)

This code sends a message to the client, which tries to print the message. The client tells the server whether or not it actually printed the message.
The RemoteEvent used above is any RemoteEvent that both client and server can see, such as one in Workspace or ReplicatedStorage. The [FONT=Courier New].OnServerEvent[/font] and [FONT=Courier New].OnClientEvent[/font] events are listened to just like any other event such as [FONT=Courier New].Changed[/font].

An example of a RemoteFunction in your code:

Script

error_code = ΓÇ¥It didnΓÇÖt work!ΓÇ¥
success = RemoteFunction:InvokeClient(game.Players.Player1,ΓÇ¥Print plzΓÇ¥,error_code)
if success then
    print(ΓÇ£yay it printed on the clientΓÇ¥)
else
    print(error_code)
end

LocalScript

function RemoteFunction.OnClientInvoke(print_message_1,error_code)
    success = pcall(function() print(print_message_1) end)
    if not success then
        print(error_code)
    end
        return success
end

This code sends a message to the client, which tries to print the message. The client tells the server whether or not it actually printed the message.
The RemoteFunction used above is any RemoteFunction that both client and server can see, such as one in Workspace or ReplicatedStorage. The [FONT=Courier New]OnClientInvoke[/font] and [FONT=Courier New]OnServerInvoke[/font] methods are called as if they were in a table with the function following the object and a period like so:

function RemoteFunction.OnServerInvoke(data)
end

There are advantages to both, of course, but using either one depends on what you are trying to do. If you want the client or server to wait for the other to do something, use a RemoteFunction. If you donΓÇÖt care if anyone receives something, use RemoteEvent.

“Where should I use RemoteFunction and where should I use RemoteEvent?”

RemoteFunctions are best when retrieving data or making the script stop until the other says to go. With that, here are some example uses of RemoteFunctions:
[ul]
[li]The client asks the server for data that was stored in DataStore[/li]
[li]The server asks for data stored on the client so that it can save it to DataStore[/li]
[li]The client wants to know who is controlling a particular model train[/li]
[/ul]

RemoteEvents don’t care (similar to the honey badger) whether the receiver actually receives something, which makes things a lot easier, especially if someone disconnects. Here are some examples of places RemoteEvents are useful:
[ul]
[li]The server is broadcasting how many seconds left of a match[/li]
[li]The client is telling the server what buttons it pressed[/li]
[li]The client tells the server that the character died[/li]
[/ul]

ΓÇ£So, what is the best way to pass lots of data through one RemoteThing?ΓÇ¥

The best way to pass data depends primarily on the situation. As a rule of thumb that I like to use, dictionaries are the best as an all-purpose data transfer protocol. Dictionaries are like tables but cooler. With dictionaries, you can use strings instead of numbers for the keys, like so:

Data_Table = {[ΓÇ£TextToPrintΓÇ¥] = ΓÇ£HiΓÇ¥,[ΓÇ£ErrorMessageΓÇ¥] = ΓÇ£Sorry, I didnΓÇÖt quite catch thatΓÇ¥}

Note: due to limitations of RemoteThings, you cannot construct dictionaries without the square brackets and quotes because if you do not use them the key will be lost and you have no way to know what data is which.

The code on the receiving end is really simple, and can be expanded indefinitely for any type of information on either end of the connection, and can be condensed into a single table in ΓÇÿpacketsΓÇÖ for easy handling. The example below comes from a car that I made to use FilteringEnabled:

seat.DataPasser.OnServerEvent:connect(function(player,tbl)
if tbl["honk"]~=nil then honk() end
if tbl["goodbye"]~=nil then exit() end
if tbl["throttle"]~=nil then throttle = tbl["throttle"] control() end
if tbl["steer"]~=nil then steer = tbl["steer"] control() end
if tbl["gear"]~=nil then gear = tbl["gear"] control() end
end)

Note: since some values may be Boolean, using truthy as a detector for the table is a poor idea, which is why I use [FONT=Courier New]~=nil[/font] in these instances.

“Do I have to turn FilteringEnabled on to use RemoteEvents and RemoteFunctions?”

Nope! You can use them as much as you like at games with or without FilteringEnabled.

“What are the advantages of FilteringEnabled?”

First of all, those pesky exploiters are a lot rarer to non-existent with FilteringEnabled on. There is also some debate on whether or not it forces proper client/server communication like reel vidja games, but the outcome so far has not been clear on that topic.

“What are the disadvantages of FilteringEnabled?”

As it is right now, FilteringEnabled is rather incomplete. Not every core feature of roblox has been added to the FilteringEnabled whitelist: for example, one cannot sit down while FilteringEnabled is on. Also, there is no customizable whitelist, which means that for some things that are better left to the client are not able to be controlled by the client, such as vehicles. Also, if you rely on FilteringEnabled to control vehicles or other fast-paced thing, lag will be an issue and the vehicle will not respond well or at all with a spotty connection, leaving the vehicle going in circles or jumping off cliffs until the packets come full circle.

Hopefully this clears up a little confusion over how RemoteEvents and RemoteFunctions work and how to implement them in your place with FilteringEnabled.

Cheers!

[/quote]

Problem with FilteringEnable is the fact that it slows down the server.

Problem with FilteringDisable is everything else in the world.

Problem with FilteringEnabled is that I feel like killing myself while working with it.

I don’t really like FilteringEnabled because there are so many core functions of roblox that FilteringEnabled filters, such as seat welds and click detectors. I wrote this guide mainly as an explanation of RemoteThings since there was some confusion that someone mentioned on the forum, so I decided to write the guide. As far as actually making something that is able to twist and bend itself into an uncomfortable shape that the FilteringEnabled hole is shaped in, I don’t enjoy that much either.

There are a few things that need to be whitelisted with FilteringEnabled in order for it to be more usable. It hasn’t helped that only a handful of developers have used the system until now. That’s why some of these bugs have remained undiscovered.

This is a good explanation of RemoteFunctions vs RemoteEvents but I do not feel that it addresses the real point of FilteringEnabled and the proper separation between server and client.

You’re doing it wrong. I was coding as if I was using FilteringEnabled before it came out [size=1](this is called ‘properly’)[/size]. It’s just coding a game The Right WayΓäó.

You’re doing it wrong. I was coding as if I was using FilteringEnabled before it came out [size=1](this is called ‘properly’)[/size]. It’s just coding a game The Right WayΓäó.[/quote]

not always, which I have mentioned in the article.