Transcript for:
Roblox Script Security & Remote Functions

Hey, thanks for stopping by. We're going to be adding more security to our Roblox scripts using a feature that further expands what we learned upon in the last episode about remote events. This one is going to be about remote functions, which have its own use cases that make it different from remote events. And in this episode, I'm going to be showing you what these are and how to use them. And this example that I have here uses remote functions.

So I have a leader set with 50 coins, and I have a prompt here that says... would you like to buy this button for 50 coins? If I click on it, then the server should have deducted 50 coins from my leader stats.

And that message should have been sent back to the client to then update this GUI to say purchase has been successful. So this had a two-way communication system that was happening rather than one-way communication. And that is essentially the difference between the two.

And that's what we're going to be discussing about inside of this episode. But before we start implementing, let me go back to our diagram that I've showed you in previous episodes. Alright, let's think about this for a minute.

So we're back on this diagram that shows us the server and client model yet again. I think you've seen this before. That's located in the Roblox Developer Hub.

Link is in the description for that. In the last episode, we covered remote events, which act as one-way communication between the server and the client. And like I mentioned, remote events act as one-way communication. And there's three ways of communicating with remote events. So the first one is from one client to the server.

The other way is from the server to one of the clients. And then there was the server to all of the clients. But what if we wanted to do a communication that sends information to one party? And then with that, it will send results back to the caller. What I mean is, what if we had...

this player communicate to the server and then with that communication to the server, the server then communicates back to the player with results to give us more information or to let us know that the call was successful. This is essentially what remote functions do that remote events can't do. The very important thing to know here is that what we're going to be talking about in this episode will act as two-way communication rather than one-way communication.

So hopefully you were able to understand this from my explanation. Now that we understand it, let's implement these remote functions. So I went ahead and created a leader stats script inside of server script service with our player added event and we're given 50 coins whenever we join into the game. So and then for the setup what we're going to do is we're going to make a prompt purchase with the coins that we have when we load into the game.

So in starter GUI we're going to create a screen GUI And then inside of the screen GUI, we're going to create a text label. And we're going to rename this to prompt. And let's move this over here.

Let's drag it a little bit. Let's center it. Let's go down here, text scale it. And then let's change the text to, would you like to buy this button? Next, what we'll do is we're going to add a text button to the screen GUI.

So it's going to look like this. And then we're going to rename this. to buy button.

Let's move this down here. Let's scale it up just a little bit. Center it.

Go down here. Text scale it. And then change the text to buy button.

And then in parentheses, we're going to say 50 coins to let the player know that this is going to cost 50 coins. Let's just scale this a little bit here so that it looks nicer. And then center it back again.

Okay. And now what we'll do is we'll create a local script inside of our screen GUI. So let's just create a local script here, go back into our game. And now that we have our setup, let's create our remote function. And so because this requires server and client communication, we want to be able to access this remote function from the server and the client, much like remote events.

And one of the best places that the server and client can access is replicated storage. So we're going to add this remote function inside of here in replicated storage. So hit the plus sign and let's add a remote function. Remember, it's remote function. And let's rename this to by button.

That's what we're going to call this remote function. And now what we'll do is we're going to open up our local script. And let's delete this and first make reference to our.

remote function. So we'll say local by button. And just to make this easier, we're going to call this by button remote so that we know that this is a remote function equals game.replicatedstorage.by button. And then what we'll do is make reference to our GUI, make reference to our prompt, and also make reference to our buy button. So first we're going to make reference to the GUI, which is located in the script's parent, and then we will locate the prompt, which will be in the GUI itself.

So GUI.prompt and then finally the buy button. So buy button equals GUI.buyButton. And now what we'll do is we will make this button active when we press it so that we can send the message to the server using our remote function.

So in here, let's create a mouse click event. So we'll say by button dot mouse button one click colon connect function open parentheses, close parentheses, enter. So here's the really interesting thing about remote functions that makes them unique compared to remote events. So in order to fire the remote function, much like remote events, all we need to do is use the function provided to call whatever side of the game we want to fire to.

So in this case, since we're in the client, we want to fire to the server. So you might say, buy button remote colon fire server. But fire server is surprisingly not a function you can use for remote functions because fire server is very specifically a function for remote events. So in this case, what we're going to say instead of fire server is we're actually going to replace fire with invoke. So this is the function we need to use in order to make a call to the server.

And in terms of parameters, it's basically the same thing with invoke server. And in this case, the other one is invoke client, where we don't need to pass in a player. if we're calling from the client to the server, but if we're going to pass in arguments, then we're going to need to do that for here. So it's basically structured the same way as a remote event.

And the way we're going to catch this function call is by doing it from the server. So let's copy this reference up here with Control-C, and then we're going to go to our leader stats script. Let's drop two lines down here, paste that, and then down here, The syntax here is going to be a little weird.

Like with invoke server not being fire server, there's a special syntax for catching this invoke server call, and it's not on server event, but instead it's going to be on server invoke. So this is what it's going to look like. It's going to be by button remote dot on server invoke. Now you might be tempted to say colon Connect function open parentheses close parentheses and enter this is actually incorrect This is not the right way to write the syntax for on server invoke Even though this pretty much is what it is like for on server event So you might ask why is it not like on server event? Why is the syntax incorrect here?

It's important to understand the difference between a callback and an event I will explain what the difference is once we finish writing our code as of right now what you need to know is that this is not the right way to write the onServerInvoke syntax because this is not an event. This is a callback. And the way you structure a callback is that it's basically a function that is structured like this.

So after onServerInvoke, we say equals function because we create a new function when we call this onServerInvoke with the open parentheses, close parentheses. And the parameters are basically the same way as... on server event call so you know how over here we have an on server event call for remote events where the first parameter implicitly gives you the player and then you have whatever other arguments you have over here it basically works the same way here where we are given the player when we call on server invoke and then let's hit enter now you might notice is that this end has no end parentheses while onServerEvent does have an end parentheses. So this is something you have to keep aware of, is that there are tiny syntax differences when it comes to using remote events and remote functions. And when you're calling onServerInvoke, you have to set this equal to a new function that implicitly passes in the player, much like onServerEvent, and then it returns, and then it stops this block of code using an end statement without the end parentheses.

So that's something important to know about here. So now what we'll do is we will make reference to the player's coins and check if the player has enough coins to be able to buy this button. And then we will subtract 50 currency from the player's inventory. So we're going to first make reference to their leader stats by saying local leader stats equals player dot leader stats. And then we will make reference to the coins by saying leader stats dot coins.

And then we will check if... Coins.value is greater than or equal to 50. Then we're going to subtract the coins value by 50. We've now provided one-way communication from the client to the server to then tell the server whether the player can buy this button and if they can then we will subtract the currency. So right now this is functioning pretty much the same as a remote event. But now let's get to the interesting part that makes this stand out from remote events.

And that is the two-way communication part. So I mentioned that we're able to invoke the server by calling invoke server and then telling the server to do what it needs to do here. But now let's actually send information back to the client to let us know that the purchase has been successful so that we can let the client do something special when we know that the player was able to buy the button.

So let's go over here and let's make a... boolean by dropping two lines at the very beginning. So we'll say local purchase successful equals false. And then let's drop a line down here after subtracting 50 coins by saying purchase successful equals true.

So this basically lets us know that if the player was able to successfully buy the button, then we set this. purchase successful boolean to true. And now what we'll do is we're going to go down here and use the return keyword to return the purchase successful boolean.

So not only are we invoking the server to buy this button and make computations to be able to get rid of 50 coins from the coins value, we're also passing back information to the client to let us know that the purchase has been successful. And the way we will get the information back... is by declaring a Boolean and setting it equal to this function call right here.

So behind our call, let's create a variable. We will call this one local purchase successful equals buy button remote invoke server. So what's going to happen is that this is going to be essentially a Boolean that is set to whatever this function call returns.

So when we call invoke server to buy button remote, it's going to go to the server and it's going to first create a Boolean called purchase successful and then it'll check whether the player can buy the button if they can then we're going to set purchase successful equal to true and then we're going to return whatever the value of purchase successful is back to the client which is going to be set here so now this will tell the client whether we know that the purchase has been successful and let's do that check down here by dropping two lines and saying if purchase successful then and when we just put in the boolean variable here this is implicitly saying if this is true or not if this is true then what we will do is we're going to change the prompt text label so this text label right here we're going to change the prompts text to purchase successful so that we can really let the client know that the purchase has been successful and let's even change the background color of it too by saying prompt.backgroundcolor3 equals color3.fromRGB. Let's click this color wheel and let's pick light green. And so this will let us know whether the purchase has been successful or not. But we can also make a check to see if it wasn't successful.

And we will do this by dropping a line down here and saying else. And now down here, let's just copy this code over here and paste it down here. So then we will say purchase. failed instead of success instead of it being successful and let's also change this color to red. So now we've successfully made a remote function that basically allows the player to press a button to buy that button by calling the server and telling us whether the player can buy this button or not and if they can then we will send information back to the client to tell us that the purchase was successful so that we can do whatever we want to do.

After we get this information, so let's go into the game and see our results. Alright, so I've loaded into the game Let's see if we can buy this button. So I have 50 coins up here and this says would you like to buy this button? Let's click it And as you can see, the server has successfully decremented 50 coins from my leader stats, and the text label has updated to say purchase has been successful.

Now let's see what happens if I press it again. It'll then tell the server to check whether the player can buy the button or not, which in this case we can't because we have zero coins, not 50. So then we told the server that this is not possible, and we sent... the information back to the client by saying it was not possible to so then we could update this text label to say the purchase has failed and so we have successfully used a remote function to make two-way communication with the server and client so that we can pass information around and do what it is we need to do with that two-way communication from the server and client now there is another method for this two-way communication because what we did was go from the client to the server and then back to the client. The second method we can do is from the server to the client and then back to the server. However, what I can say to that is I would actually advise not to do this method from communicating from the server to the client and then back to the server because the server basically has access to all the information that a client already has.

So there's no need for a server to communicate to the client to get information. to be able to send it back to the server. There's just no need for that. What you could do instead is just use a remote event that communicates from the server and then to the client so that the server can tell the client what to do rather than having to fetch information from the client because we don't need information from the client because the server already knows everything that a client knows.

So the only use case I can say to remote functions is by communicating from the client to the server and then back to the client. That's the only use case I can see with remote functions. At least in my opinion from my time developing Roblox games, that's the only use I've seen with remote functions.

Now you might ask, why does the syntax for onServerInvoke look like this, where we need to create a new function and not have an end parentheses by the end here, rather than doing it like this with remote events with the colon connect function and end. It's important to understand the difference between events and callbacks. So... Events are basically a signal that gets fired when something happens, when we call the function of the remote event to then catch that event using colon connect. This is specifically for events when they have to catch the event calls.

But in the way that a callback is different for on-server invoke is that a callback is basically a function that is passed as an argument to another function, and then it is called to execute code after a task is completed. because the whole point of a two-way communication is that when we communicate from one side which is the client to the server and we rely on information from the server to be sent back to the client the code does not continue until we get the results from this callback to then continue executing whatever else it is we need to execute down here but an event call can happen multiple times and execute without having to wait for results to happen. I hope that makes sense. Imagine if you had two parts here that have a touch event where if a player constantly stepped on this part, then it'll keep on firing events to then to execute whatever it is that we need to execute here. But a callback relies on the information to be received back to whatever party called that function.

In this case, we cannot have so many of these info calls at the same time as we do with events. I don't know if that made sense to you. I really hope you kind of get the feel of what I'm trying to say here. But that is essentially why the syntax difference matters between a callback versus an event.

Other than that, everything else is still pretty much the same. It's just the little syntax difference that you need to be able to understand why it is the way it is. So for this last part of the video, I'm actually going to make this into a challenge. And I'm not going to lie to you, this challenge is actually going to be very fun.

At least I think so anyways. Because essentially what we're going to do is we're going to create a tools shop system using everything we learned up until this point. And there's three requirements I have for you to do while you try doing this challenge on your own first and then coming back to see what I do once we go through this challenge together. So the first requirement I have for you is to use a remote.

function, obviously because that's the title of this episode. The next requirement is to make at least three buttons or tools for this shop system. You can either go to the toolbox to look at some tools for you to use inside of your game, or you can try creating your own tools for your shop, but either way works for you. The third requirement is I want you to use the clone function to take the bot tool and put it inside of the player's backpack.

After the player has bought. whichever tool that they purchased in the shop. And if you don't remember how to do this, I highly encourage you to refer back to my tools episode where I went through a bunch of properties that will definitely help you with this challenge.

So just putting that out there before you start this challenge. So with that being said, pause the video, try this challenge out on your own first, and then come back and we'll go through this together. All right, so first thing we're gonna do, for the sake of time, we're just going to find three random tools in the toolbox. and just use that and just use those as our tools. So I think first thing down here, I can actually see that there's the linked sword uploaded by Roblox.

So let's add that in. Let's hit okay, put tool in the starter pack. Yes, let's do that. Okay, and let's look for two more.

So I'm just gonna search up tool and let's look for two more things. So there's a flashlight tool. Let's just take this. And it looks like there's also a knife. So we might as well take that as well.

Alright, and they all should now be inside of our starter pack. Let's also rename these tools to make it more simple. So we'll call classic sword, sword. We will call flashlight, flashlight. And then we'll keep knife as it is.

Now we need a place to store these tools so that we can fetch them by the server. And probably one of the most ideal places is server storage. So let's actually take all of these tools and let's put them inside of server storage. Now what we'll do is create a shop.

So let's create another screen GUI here. Let's rename this to shop. Let's just open up our previous screen GUI and let's copy everything that's into here by hitting control Z and then just pasting it all into here so that we don't so that we can just reuse what we currently have.

So for our prompt, let's change the text to welcome to my shop. And let's just center this a little bit. And let's also make this buy button one of the tools. So let's say sword for instance. Let's rename this to sword and let's change this text to buy sword.

And ideally we should make all these tools different prices. So let's make this sword 10 coins. Let's just move this over here to the left and then let's duplicate it and move this to the center. And let's call this one flashlight.

And let's change the text to flashlight. And let's even change the amount to, let's say, 15. All right. And let's duplicate that again.

Put it over here. This one is going to be the knife. And we will make this knife 20 coins. So let's rename it to knife, 20 coins. So this is now what our shop should look like on the GUI side.

But now let's open up our script. inside of our shop. And first thing we will do is instead of make reference to one buy button, we need to make references to all three buttons so that we can make all of them functional.

So what we're going to do is rename buy button to sword button and change the reference to sword. And let's copy and paste this two more times so that we can get reference so we can get references to the other buttons. So this one will be Flashlight so this one's going to say flashlight and this one is going to say knife and this one's going to be a knife and so let's just change this variable here from by button to Sword button and in order to make all these buttons functional We need to copy what we have with our code and just paste it in like two different times so that we can make all Of them functional now this already does look pretty messy. I would not recommend doing it like this what I would recommend is putting all of these buttons inside of a table and looping through that table so that you can just write this code section only one time. You don't need to write it like three different times like I'm doing here.

And so now we need to figure out how we can pass in this information to the server to know which button is being pressed. What we can do inside of the server is create additional parameters to let us know which tool we're trying to look for when we are making this purchase. So let's actually create two parameters here. So the first one is going to be the tool name.

And then the second parameter is going to be the tool price. When we implicitly call player, we want to pass in these two parameters as well so that we know which tool we're trying to look at. So let's go back into our local script and let's add in our additional arguments.

Now remember, player is already implicitly being thrown into here. So we can skip throwing in player. What we do need to put in is the tool name and the tool price.

So in quotations, we're going to say. Sword and then we'll space it out with a comma and we will put in the price which is going to be Ten coins and then we will do the same thing down here with the flashlight. Oh, and I meant to change these to flashlight button and then down here to Knife button so that we're not doing this like three different times And so now inside of our invoke function inside of our invoke server function here. Let's call this one flashlight and this one is going to be 15 coins. So now down here we're going to say knife and this one's going to be 20 coins.

So now we are effectively passing in arguments into this into this callback so that we know which tool we're talking about. And so first thing we can do is replace our coins value condition instead of it being 50 all the time let's replace this with the tool price and we will do the same thing down here when we remove values from the coins. So now we have that done, but now what we will do is we're going to get the tool from server storage, use the tool colon clone function, and then put it inside of the player's backpack.

The way we're going to do that is by dropping two lines down here, or actually three lines, after we know that the player has enough to be able to buy this tool. We're going to first check in server storage to see if we're able to find the tool that we're looking for. So what we're going to say is local tool equals game dot server storage. And we need to check if it's here.

So we're going to say colon find first child, open parentheses, close parentheses. And inside of here, we're going to pass in our tool name, tool name, because our tool name could be sword or flashlight. or knife.

So we're trying to look for this inside of our server storage. And now let's check to see if it actually does exist. So we'll say if tool then, we're going to create a clone of that tool and put it inside of the player's backpack.

So we'll say local cloned tool equals tool colon clone, open parentheses, close parentheses. And then we're going to set the parent of this clone tool. So cloned tool dot parent.

equals the player's backpack, which is going to be player.backpack. So now we have successfully allowed the server to check whether this tool exists inside of server storage. And if it does, like let's say it's a sword, then we're going to clone this tool and we're going to place this inside of the player backpack while also decrementing the coin's value, while also telling the client that this purchase has been successful. And we're going to send this information back to the client. So we're pretty much done here.

This was basically our whole script. Now, again, there are definitely better ways of handling this code, especially this right here, when we're duplicating a lot of stuff by using a table and then looping through all those buttons inside of a loop rather than creating three different mouse button, one click events. But other than that, I'd say our system we have is pretty good. So let's test it out inside of our game.

All right. So we've loaded into the game. I have 50 coins and let's see what happens if I... try buying the sword. So as you can see, first thing that happened was that it checked if we had enough coins for 10 and it did.

So we decremented 10 coins after buying the sword. The second thing that happened was that the server checked server storage to see if it had the sword we were looking for. And it did.

So the server created a clone of this tool and put it inside of our backpack. So if we open up players, our player, and then go to backpack, we can see. that our sword has successfully been placed inside of our backpack.

So that was successful. And the last thing that happened was that the server sent the message back to the client to tell us that the purchase has been successful. Therefore, we updated this text label to say the purchase has been successful. And we did all of those things using remote functions. Now let's see what happens if we try buying a flashlight.

We can see that we now have the flashlight inside of our backpack and we also decremented 15 coins from buying this one. Now let's try buying the knife and we have also successfully bought the knife so it works as intended. Now let's try buying something else. We can't afford anything now so let's try buying something and as you can see the purchase has failed because now we only have five coins and not at least 10 to buy any of these. So we're basically done here and what we got out of this was a pretty nice shop system that allows us to be able to buy these tools.

So I hope you found this challenge to be very interesting. I definitely had fun explaining how this shop system worked and I think we're starting to be able to apply our skills to be able to create actual systems inside of our games. So I think this was definitely a fun challenge to to do.

So that's going to be it for this episode on remote functions. I hope you learned a lot from this episode. We were able to create a shop system using everything we've learned up until this point. And I think we're starting to make more and more progress into creating bigger and better systems for our Roblox games. And I hope you'll be sticking around for more episodes to come in the future.

But other than that, that's pretty much it for this episode. Be sure to join my Discord server. The link is in the description.

And I will see you in the next episode. Take care.