The client and server run in separate Lua contexts - similar to how contexts are different across Actor
s. This means that on the client, when you require
a module, if you require the same module on the server, you will get a new table, not the one the client has.
FWIW it’s not even technically possible to sync two tables properly, as they reside in memory and can hold functions (functions cannot be transferred between Lua contexts; this is why you can’t send a function over a remote event).
The network acts as a barrier between the server and the client and creates some limitations. Everything you send over to the server (or the server sends to the client) is first serialized (i.e. converted into a format that is good for transmission), then sent, then received, and deserialized. This means that you aren’t really working with the original sent data, but with a copy of it, on the machine that received the data. This is true of everything sent between two computers.
This is why modifying a part on the client won’t (after 2016*) modify it on the server - only the client sees the change. The usual returned table from a ModuleScript will only be accessible in the context that required it; and if it’s passed to another context (e.g. via a RemoteEvent), it will always, 100%, undoubtedly be copied and then transferred.
Edit for clarification
Since most changes are dictated by the server, and because of the separation of contexts, this also means that a client cannot access the memory of other clients. This is quite obvious, but some people think that Client → Client modifications are still possible. They never were: if one client manipulated a property, that got synced to the server, which then sent the change to other clients. The server has always been authoritative in the Roblox model, but it used to be also quite lenient.
* - In order to have this behaviour, you (read: Roblox) deliberately have to write code to support the synchronisation. This already exists for Server → Client changes, so if a server modifies an Instance, all clients see it, but having the reverse is somewhat unusual in modern day game networking. There are a couple of exceptions - player characters are usually synched from the client to the server, because the client should be able to move its own player - otherwise, it’d be necessary to send the command to move the player to the server, then wait for the server to move the character, and then find out what the new position is. Since this costs time (a 500 ms ping means you have to wait 1 second for each movement), this clearly doesn’t work. Roblox’ FilteringEnabled prevented servers from receiving updates on Instances which players shouldn’t be controlling - e.g. recolouring half of the map 