Is using a module script top share table data wrong?

I have been using module scripts to store in game data about which parts are “connected”. These are in ReplicatedStorage. However, Im not sure Im using them correctly.

I have a client script that fires server events. A serverScript then adds “connections” to the table that has been required

local connectionsTable = require(game.ReplicatedStorage.ConnectionsTable).

This is the only script that writes to the table. Other serverScripts also require the this table and loop through the connections and set values of parts based on their connection status.

Does this seem sensible? I have read that required module scripts are cached? Does this mean need to re-fetch the table somehow?

You can use module scripts to share information between scripts on the same side, but they will not send information from client to server or the other way.

A module script has its data created the first time it is require()'d, but there’s not a great way to “reset” a module to its fresh state, except by cloning it. So you should consider using it for things which have the same lifetime as the ModuleScript instance itself, or things that last the whole life of the server.

It’s also hard to control the order of operations done to the module, so be careful about that.

1 Like

Thanks @azqjanna

You can use module scripts to share information between scripts on the same side, but they will not send information from client to server or the other way.

I think that is ok with how I am working :+1:

A module script has its data created the first time it is require()'d

Does this mean a table is not good in my instance (to keep track of connections)? As I need to add or remove data from it. Say a function in a serverScript that has required the table needs to read it - will it be up to date with changes made to the table since it creation?

It’s also hard to control the order of operations done to the module, so be careful about that.

Could you explain this more?

1 Like

When you call require() for the first time, the text of the script is loaded and any statements inside it run, so any default values like jeff = 2 will be set. The second or later time it is called, it will just return the the same table that was returned to the first caller. This means that you cannot rely on calling require to assure that jeff = 2, because you will not know if you are the first caller when multiple scripts can use it. If you only need the functions in the module, or are using it to share values, this is fine, and callers will not be able to tell the difference between first or second require().

Scripts run one at a time, but you cannot control in what order. Any time you wait() or return from an event function, a different script is switched to. You should make sure not to write anything the requires two scripts to run in an exact order. Assume you have 3 functions:

A: writes 1 to the variable ‘jeff’ in a module
B: reads 1 from the variable ‘jeff’ in a module, which must have been written by A
C: writes 2 to the variable ‘jeff’ in a module, but should not be seen by B

This situation will not work, theres no way to know that C has not run between when A stops and B starts.

On the other hand, if you have many scripts with some code like this:

myModule.points = myModule.points + 1

where myModule is shared by all the scripts, this is fine, because there is no requirement for a specific order of operations. But this would not be ok:

local points = myModule.points
wait(1)
myModule.points = points + 1

Because another script could run during the wait and change myModule.points. points would then have the old value and a number would be “missed”. The difference is the example without the wait is atomic