Best way to store datastore profiles on the client?

In my game, as in many, data store module loads in the player’s profile to a table when they join, edits it whenever the player obtains something for example, and when the player leaves it saves that table to the data store.

The problem I’m facing is what would be the best way to give access to that table for the client (for GUI purposes mainly)?

The only 2 things that came to mind are value objects and remote functions. The problem is that neither are ideal. Value objects are nice when it’s something basic like “Cash”, but when you have 20 different things, it feels wrong to create a value object for each and one.
The approach I use now is remote functions, where client asks the server for their data table, but this almost feels worse. One reason is that client has no way of knowing when data updates, and I feel like there must be a good solution here that I am missing.

Try selective data replication with remote events and catching and implement that local script or script

1 Like

Do you mean that whenever the server changes a player’s profile, they send the updated table to the player via a remote?

Yes maybe in a way to the client for selective breaching

1 Like

Uh not sure what you mean, the problem with this though is that there will be one local script that has this data, and no other scripts will. This means that I’ll have to set up a bindable event to communicate with other local scripts and that still feels like a bad solution. Or am I missing something?

Well in that case you might try something more centralized like this

Create a module script for client side data management and use signals and custom events for local updates

1 Like

Uh, I’m not very good with module scripts, what would module script do to achieve this result?

An example could be of that to module scripts

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local playerDataUpdated = ReplicatedStorage:WaitForChild("PlayerDataUpdated")
local getPlayerData = ReplicatedStorage:WaitForChild("GetPlayerData")

local ClientDataStore = {}
local dataCache = {}
local dataChangeEvent = Instance.new("BindableEvent")


function ClientDataStore.Init()
    dataCache = getPlayerData:InvokeServer() or {}
end


local function updateData(dataType, newData)
    dataCache[dataType] = newData
    dataChangeEvent:Fire(dataType, newData)
end

playerDataUpdated.OnClientEvent:Connect(updateData)


function ClientDataStore.GetData()
    return dataCache
end


function ClientDataStore.OnDataChange(callback)
    return dataChangeEvent.Event:Connect(callback)
end

return ClientDataStore

Local client script you would require this way:

local ClientDataStore = require(game.ReplicatedStorage.ClientDataStore)

ClientDataStore.Init()

ClientDataStore.OnDataChange(function(dataType, newData)
    print("Data changed:", dataType, newData)
    -- Update UI or other elements as needed
end)

It organizes your client-side code for managing player data but also that data can be accessed and updated good across multiple LocalScripts

3 Likes

Wow, this one example cleared up like 20% of my confusion with module scripts! TYSM!!!

1 Like

You got it! Just keep on going with data across all clients :smiley:

1 Like

I have a question, if I initialize this module in multiple local scripts, won’t this mean that dataChangeEvent:Fire(dataType, newData) will fire multiple times, once from each script I initialized the module in?

It can mostly depend on how you set up the module scripts and the events that can happen so if you need something it will respond based on module set up

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.