is there a way to use a module script for the clients and server to access the same data. because ive been searching for an answer and simply cant find one.
im setting data in the module script on the server side and then attempting to access that data from the client side.
You would still need to send and retrieve data from the server through a remote event. But you can still use a module script for this and have events set up to listen for client requests to read and set data.
this was my back up plan i just wanted to be able to do it mostly through client for sake of efficiency but if this is the only way then thank you for taking time to reply
Module script gets cached once per environment. Meaning once you have called require, the module script will get cache, any other place that tries to use it will be using the same copy.
You can store something inside of it like a variable and that variable can be access using multiple Local Script or Server Script.
You can also edit them provided that you have the right function to change them.
I use module script to maintain and keep track of player data.
This way I avoid doing anything on the client side or keeping any data on them.
if (game:GetService("RunService"):IsServer()) then
local serverModule = {}
local data = {} -- data is kept on the server
-- serverside getter/setter is simple
serverModule.Get = function(index)
return data[index]
end
serverModule.Set = function(index, value)
data[index] = value
script.ChangedServer:Fire(index, value)
script.ChangedClient:FireAllClients(index, value)
end
serverModule.Changed = script.ChangedServer.Event
-- client requests call the server getter/setters
script.Get.OnServerInvoke = function(user, index)
return serverModule.Get(index)
end
script.Set.OnServerEvent:Connect(function(user, index, value)
serverModule.Set(index, value)
end)
return serverModule
else
local clientModule = {}
-- instead of changing the table the client methods send requests for the server to change
clientModule.Get = function(index)
return script.Get:InvokeServer(index)
end
clientModule.Set = function(index, value)
script.Set:FireServer(index, value)
end
clientModule.Changed = script.ChangedClient.OnClientEvent
return clientModule
end
It wraps a remote event and function on the client side so clients can “ask” the server to change values on the server-sided table. I also threw in the ability to listen for events that fire when a value is changed from either side.
Clients that require a shared module don’t get the same table that is returned when the server calls it. So instead each client gets a table of helper functions that looks identical to the server table, except their functions just invoke the server table’s functions.
And to state the obvious, while this is an interesting implementation of module scripts, it is not a safe place to store important information like leaderboard stats since any client can change values in this global table. (Unless you add sanity checks to the server’s listener for the Set event, or disable the client’s Set ability altogether.)
well why doesnt this work then when thats what im doing (this is just a simplified version of my code but the main bits)
server script:
local PlayerDataModule = require(game.ReplicatedStorage.Events.Time.PlayerModule)
game.Players.PlayerAdded:Connect(function(Player)
--make sure names matches what we have stored
local UserID = tostring("Player"..Player.UserId)
local Name = Player.Name
local StoredName = IDsToNameDataStore:GetAsync(UserID)
if Name ~= StoredName then
IDsToNameDataStore:SetAsync(UserID, Name)
end
--retrieve data
local HighestTimeData = HighestTimeDataStore:GetAsync(UserID)
local OverallTimeData = OverallTimeDataStore:GetAsync(UserID)
PlayerDataModule:SetData(Player.Name, HighestTimeData, OverallTimeData)
end)
module script:
local Data = {}
local PlayersNData = {testperson = {11, 5959 , 111}}
function Data:SetData(Player, HighestTime, TotalTime)
if HighestTime == nil or HighestTime == 0 then
PlayersNData[Player] = {0, 0, 0}
else
PlayersNData[Player] = {0, HighestTime, TotalTime}
end
end
function Data:RemoveData(Player)
PlayersNData[Player] = nil
end
function Data:IncrementData()
for I,V in pairs(PlayersNData)do
print("i =", I,"v =", V)
if V[1] >= V[2]then
V[2]=V[2]+1
end
V[1]=V[1]+1
V[3]=V[3]+1
end
end
function Data:GetData(Player)
print(PlayersNData[Player])
print(PlayersNData.testperson[1])
return PlayersNData[Player]
end
return Data
local script:
local PlayerDataModule = require(game.ReplicatedStorage.Events.Time.PlayerModule)
TimePulse.OnClientEvent:Connect(function()
print(LocalPlayer.Name)
local Data = PlayerDataModule:GetData(LocalPlayer.Name)
print(Data) -- prints nill
end)
when i try printing the whole table from the client side it prints just the test person even though the server has put my data into it
Put a module in ReplicatedStorage and a script in ServerScriptService to change them, if the client changes them, the others and the server will not see it (also it will not be saved)
thank you very much for this but i think your original solution is best. itll be RemoteEvents or RemoteFunctions in the end anyway but thanks for all the help.
local PlayerDataModule = require(game.ReplicatedStorage.Events.Time.PlayerModule)
TimePulse.OnClientEvent:Connect(function()
print(LocalPlayer.Name)
local Data = PlayerDataModule[LocalPlayer.Name]
print(Data)
end)
it is however im not going to be using your second post because the clients dont need to fire events to access it because they just need the data at regular intervals so im just going to fire it to them with an event at regular intervals.
originally my server script was just firing all clients like “its time to get data” at regular intervals but now ill just fire each client individually with their individual data.