Server VS. Client VS. Module Scripts; What's the Difference?

As I was starting out scripting, I was extremely confused with all of the different types of scripts, but they actually have very important differences! This tutorial goes in-depth about all the different types of scripts & other info that may be very useful! Whether you are new, experienced, or looking to re-sharpen up your skills, this tutorial is for you! :bulb:

Client Scripts

Client Scripts

To understand client scripts, you must understand a few key things first!

  • Client Scripts run on the player’s device;
  • Client Scripts do not change items for other players;
  • & Finally, Client Scripts are prone to exploiters.

Table of Contents:

  1. Functionality
  2. Location
  3. Safety

I would highly recommend reading them in order.

ptsa: I will be referring to them as “LocalScripts” for the rest of this tutorial :dizzy:
Chapter 1: Functionality

Due to LocalScripts running on the Client, they do not change data for other players / the server, here is a comprehensive table explaining the functionality.


Action Changing Data Deleting Data Creating Data
Result Data changes for the client, other clients (or players) & server scripts cannot access the change. Data deletes only for the client once again-if you delete a part only the local player can see it deleted. Data creates only for the client, only LocalScripts running on the same client can access the data created.

Next up: Location.

Chapter 2: Location

LocalScripts cannot just be put anywhere - they must be in a location where they are able to run! Here is every single location you can put a LocalScript in Roblox Studio!

  • StarterPlayerScripts - Will automatically be placed in every player object under a folder.
  • StarterCharacterScripts - Will automatically be placed in every player character object.
  • StarterPlayer - Will automatically be placed in every player object - *not in a folder.
  • StarterGui - Will automatically be placed in every single player GUI.
  • StarterPack - Will automatically be placed in every player object under their Backpack.
  • Directly into the Backpack Object from a script
  • Directly in the Character Object from a Script
  • Directly in the Player Object from a Script
fyi - they can be placed anywhere, but these are the places that they will run :large_orange_diamond:

Next up: Safety.

Chapter 3: Safety

LocalScripts run locally - I think that’s been defined at this point. However, due to them running locally, this means that they are prone to exploiters as exploiters use, change, read, delete, and create data *locally. Here are my personal tips for safety when using local scripts:

  1. Always check / change critical data through a server script.

Exploiters can exploit many vulnerabilities if data is checked locally! If you check someone’s money from a local script, an exploiter could have already set that to an extremely high number, meaning that they could abuse your code.

Solution: Use a RemoteEvent to send a signal to a server script to check and send back the true data.


  1. Limit / Remove any Client Managed Values.

Try to limit / remove data that is created and/or managed solely by the client; it’s not safe.

Scenario: A Player has an in-game currency that is only managed by the Client and cannot be managed by the Server. It seems like a great approach if you don’t want other people to have access to your in-game currency data. However, now exploiters can easily change any values and/or data with ease, as you cannot implement an anti-cheat against it due to it being local.

Solution: Just make it accessible to all, and apply the previous knowledge.

I hope that you learned some about LocalScripts!


Server Scripts

Server Scripts

In order to understand ServerScripts, a few key details must be pointed out first.

  • Unlike LocalScripts, ServerScripts are managed by Roblox servers.
  • ServerScripts change data for everyone, not just the client.
  • & Finally, ServerScripts are not prone to exploiters!

Table of Contents:

  1. Functionality
  2. Location

I would highly recommend reading them in order

Chapter 1: Functionality

Server Scripts are managed by Roblox Servers, so data changed, deleted, or created happens for all clients. Data changed through LocalScripts will not be changed on the server. :sunny:

Server Scripts should be used to check / change values (such as money, xp, and basically all values) and to edit data you want to be changed throughout the entire server (CFrame, Color, and many other values) :compass:

Next Up: Location.

Chapter 2: Location

Similar to LocalScripts, ServerScripts will only run in certain locations, so here is a list of all of the locations I recommend they should be put.

  • ServerScriptService
  • Any Tools inside of the backpack / player
  • Inside the character if needed
  • Under certain object types in workspace
  • Workspace - Although I highly don’t recommend putting all your scripts in Workspace, it will run, but the code can be stolen by exploiters

ModuleScripts

ModuleScripts

ModuleScripts work differently than Client and Server scripts–they are used for storing data / tables and can be accessed by both Client and Server scripts.

Table of Contents:

  1. Functionality
  2. Access

I would highly recommend reading them in order

Chapter 1: Functionality

Module Scripts are not used to change data generally, they are used to store it inside of tables. They work very differently than other Script types.

Chapter 1a. - ModuleScript Basics

To start off your ModuleScript, you need to have a table with a return + your table name at the end.

MyTable = {
--PlaceHolder
}

return MyTable

To add data, you just add variables but do not type local.

Good Example:

MyTable = {
  PlaceHolder = "Hello! This is a PlaceHolder!"
}

return MyTable

Bad Example:

MyTable = {
  local PlaceHolder = "Hello! This is a PlaceHolder!"
}

return MyTable

Unlike Local/Server Scripts, ModuleScripts are not meant to run code / functions. Do not try to change, create, or remove any data from these scripts.

Next Up: Access.

Chapter 2: Access

To interpret stored data in ModuleScripts, we must use the require() attribute to send a request for the data.

Chapter 2a. - Accessing Data & Use Cases

So we use the require() attribute to request the data, but how do we do it? It’s actually very simple. Just put your ModuleScript object into the parenthesis and call it a day. Here is a code snippet:

local MyModule = game:GetService("ServerStorage"):WaitForChild("MyModuleScript")
local MyModuleData = require(MyModule)

Chapter 2b. - Finding variables inside the module.

Once you have the ModuleScript required, you can access any of the variables inside of it by using the good ol’ . Here is a code snippet:

ModuleScript:

MyTable = {
   PlaceHolder = "Hello! This is a PlaceHolder!"
}

return MyTable

ServerScript:

local MyModule = game:GetService("ServerStorage"):WaitForChild("MyModuleScript")
local MyModuleData = require(MyModule)

local PlaceHolder = MyModuleData.PlaceHolder

It’s that simple! Nothing else needed unless you are going very deep.


Thanks for reading! If you’ve got any issues, complaints, or feedback I’d love to hear your opinion down below, and if I’m missing and/or have any formatting issues, false information then please let me know!

By the way, this post took me several hours to make, so if you would like to support me, drop a follow, it’s easy and motivates me to make more posts like this!

if there is any tutorials you would like me to focus on, I would love to hear them, bye now :wave:
2 Likes
MyTable = {
  local PlaceHolder = "Hello! This is a PlaceHolder!"
}

insane

MyTable = {
  local PlaceHolder = "Hello! This is a PlaceHolder!"
}

Im cry

i copied the wrong code whoops :sob::sob:

fixed now thank you for the notice :clipboard:

I mean, using modulescripts purely to store data is good practice yeah, but why the “do not try to change, create or remove any data”? Using ModuleScripts to share information/communicate across scripts is very commonplace and actually recommended over the usage of e.g ValueObjects or BindableEvents or _G or shared.

This is only if you return a table in the ModuleScript, keep in mind ModuleScripts can return literally anything. Userdata proxies, instances, functions, strings, numbers, etc. And these values are also what will be returned by require()

Other than that tho the rest of the info is pretty sound from a quick read, nice post!

That was just the module script basics. I was explaining that inside of the table provided do not try to edit data. They can also return many values, you are correct! I was trying to explain just a few basics. Thanks for the tips, I’ll try to add that in my module script, and thanks for the complement!

1 Like
local MyTable = {}
MyTable.PlaceHolder = "Hello! This is a PlaceHolder!"