I decided to simplify my current scripts to figure out why they weren’t working as intended. Turns out the table values were different for both the client/server.
What I want is basically to store string values in a dictionary (main goal is to store a player name to another player name) and to be able to access it through a local and server script.
Questions:
• Why is the table different in server and client?
• Is there a way to make the table the same for both (or copy data one to another)?
• Are string dictionaries stable (or is there a better option)?
Local Script
local mod = require(game.ReplicatedStorage.ModuleScript)
wait(1)
print(mod.getTable())
Server Script
local mod = require(game.ReplicatedStorage.ModuleScript)
game.Players.PlayerAdded:Connect(function(player)
mod.changeTable("hello", "hi")
end)
Module Script
local module = {}
local testTable = {}
function module.changeTable(index, value)
-- Trying to edit/add table values to testTable here
print(index, value)
--testTable[index] = value
testTable = {
index = value
}
print(testTable)
return testTable
end
function module.getTable()
return testTable
end
return module
The table is different between the Server and Client due to the ModuleScript not storing data correctly. When you require the module on Server & Client recursively, they get their own “instance” of the module, similar to Javascript. Meaning any changes you handle on the server, won’t affect data in the local script module, does that make sense? For Example;
local moduleInServerModules
if runService:IsServer() then
moduleInServerModules = findModuleScript(serverScriptService.ServerModules, moduleName)
else
moduleInServerModules = findModuleScript(replicatedStorage.ClientModules, moduleName)
end
In my Module Loader function, I retrieve the module script accordingly based on the Server or Client. Yes you can make the table the same for both. Utilizing my method, or DataStoreService. And yes, string dictionaries are one of the most reliable data structure(s).
It’s my module loader system, optimized with my Network. I’ll send the full code to the loader here in a second.
local loadedModulesCache = {}
local replicatedStorage = game:GetService("ReplicatedStorage")
local function findModuleScript(parent, moduleName)
for _, descendant in ipairs(parent:GetDescendants()) do
if not descendant:IsDescendantOf(replicatedStorage.SharedModules.OldData) then
if descendant.Name == moduleName and descendant:IsA("ModuleScript") then
return descendant
end
end
end
return nil
end
local runService = game:GetService("RunService")
local serverScriptService = game:GetService("ServerScriptService")
return function(moduleName)
if loadedModulesCache[moduleName] then
return loadedModulesCache[moduleName]
end
local moduleInSharedModules = findModuleScript(replicatedStorage.SharedModules, moduleName)
if moduleInSharedModules then
local module = require(moduleInSharedModules)
loadedModulesCache[moduleName] = module
return module
end
local moduleInServerModules
if runService:IsServer() then
moduleInServerModules = findModuleScript(serverScriptService.ServerModules, moduleName)
else
moduleInServerModules = findModuleScript(replicatedStorage.ClientModules, moduleName)
end
if not moduleInServerModules then
error(string.format("Failed to load module %q", moduleName))
return
end
local module = require(moduleInServerModules)
loadedModulesCache[moduleName] = module
return module
end
Usage
local loadModule = require(game:GetService("ReplicatedStorage").Loader) local YourModule = loadModule("Name of your module")
I think I know the answer but, im curious; is your module loader allowing real time replication of a module script from the server to the client or are you just loading modules and caching them for performance? @corehimself
It does indeed load the module, and cache them for performance. User-dependent on setting up remotes, client requesting the module script, having server respond with data, etc.
My implementation is not for real-time, but makes it easier to be utilized as so.