Replicate player data from the server to client

Hi there, I’m currently making a stats with datastore. I’m trying to replicate the player data from the server to the client.
Main data module:

local PlrData = {}
PlrData.__index = PlrData

local transferData = require(script.Parent.transferData)

function PlrData:newData() -- Create new data if the player is new
	local newData = {
		PlrStats = {
			Strength = 1,
			Agility = 1,
			Magic = 1,
			Vitality = 1,
			Defense = 1,
		},	
	}
	return newData
end

local SavingFor = {} 

function PlrData.init(plr)	
	local plrTable = {}
	
	local self = setmetatable({}, PlrData)
	self.dataStore = game:GetService("DataStoreService"):GetDataStore("TEsT")
	self.key = plr.UserId .. "'s Data"
	self.table = plrTable	
    return self
end

function PlrData:LoadData(plr) -- load the data of the according player
	local Data
	
	local suc, err = pcall(function()
		Data = self.dataStore:GetAsync(self.key)
	end)

	if not suc then 
		return warn(err)
 	end
	
	self.table[plr.UserId] = Data or self:newData()
	transferData:UpdateData(plr, self.table[plr.UserId])
end

There are more code to the main module but they are irrelevant to this post.
transfer data module:

local transferData = {}

local plrData = {}

local sendData = script.sendData
local RunService = game:GetService("RunService")

local function printTable(tab, string)
	for i,v in pairs(tab) do
		if type(v) == "table" then
			print(string,i," : ",v,":::")
			printTable(v, string.."     ")
		else
			print(string,i," : ",v)
		end
	end
end

function transferData:UpdateData(plr, tbl)
	if RunService:IsServer() then
		plrData[plr.UserId] = tbl
		sendData:FireClient(plr, tbl)	
	else
		plrData[plr.UserId] = tbl
	end
end

function transferData:GetData(plr)
	printTable(plrData[plr.UserId], "")
	return plrData[plr.UserId]
end

if RunService:IsClient() then
	sendData.OnClientEvent:Connect(function(tbl)
		local plr = game.Players.LocalPlayer
		
		transferData:UpdateData(plr, tbl)
	end)	
end

return transferData

It gets replicated perfectly when its server - server, since I set the self.table to the plrData[plr.UserId] in the transfer data module. I thought it would work for the client as well, but turned out it doesn’t. Does this means I would have to send a remote manually everytime the player’s data gets updated ? It feels very inefficient to me. I have tried the __index and __newindex metamethods to send the wanted data / value to the client but it doesn’t work and I have asked for help in other posts.
Any alternatives ?

I would say simply use Knit for these type of situations, Knit is a easy to use Framework, basically it is a Networking Framework that already has built in Networking for you to communicate both to the Client and Server directly, however… For your situation as of now you’re more and likely storing the DataModule in a Server Service therefore preventing the client in getting access to the Datastore, so you would need to have a Remote in-order to get the Data from the Server. Hoped this helped!

(I would highly recommend Knit, it will solve all your issues easily by just simply one-line of code to send Data to the client from the server.)

1 Like

Regardless of whether you’re using a framework or not, underlying cross-environment communication will be done in remotes so to answer your exact question yes you would need to use a remote every time you want to transfer data to the client.

I do this in my current project and most cases are the client requesting the server to perform an action and then give it back the updated data set, so via RemoteFunctions. The main bottleneck is the network round-trip but otherwise it’s the appropriate - and virtually only - way to go.

2 Likes