Hey! For my King-of-the-hill theme game, I made a DataStore method for, of course, storing UserData.
The system I have in place is well-functioning, but I am confident that it can be improved on to help with security and functional aspects.
How it works:
When a player joins, a folder with the player’s ID as its name is made under ReplicatedStorage.PlayerData
, that folder contains all the IntValues for the User. (currently my only variables are Score
and Level
. That folder can then be read but not edited by LocalScripts. And when the player leaves, the data is saved and the folder is removed.
It also controls Data changes with the TranslateCall
function.
local RepStore = game:GetService("ReplicatedStorage")
local SvrStore = game:GetService("ServerStorage")
local DatStore = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local PlayerDataFolder = RepStore.PlayerData
local InfoStore = DatStore:GetDataStore("PlayerData")
function UnloadPlayerData(PlayerID)
local success, err = pcall(function()
local PlayerData = InfoStore:GetAsync(PlayerID)
if not PlayerData.Level and PlayerData.Score then
warn("data empty")
PlayerData = {}
PlayerData.Level = 0
PlayerData.Score = 0
end
local PlayerFolder = Instance.new("Folder")
PlayerFolder.Name = PlayerID
PlayerFolder.Parent = PlayerDataFolder
for store, data in pairs(PlayerData) do
local IntHolder = Instance.new("IntValue")
IntHolder.Name = store
IntHolder.Value = data
IntHolder.Parent = PlayerFolder
end
end)
if not success then warn(err) end
end
function PackPlayerData(PlayerID)
local PlayerFolder = PlayerDataFolder:FindFirstChild(PlayerID)
local success, err = pcall(function()
local PlayerData = {}
for i, v in pairs(PlayerFolder:GetChildren()) do
PlayerData[v.Name] = v.Value
end
InfoStore:SetAsync(PlayerID,PlayerData)
end)
if success then
PlayerFolder:Destroy()
else
warn(err)
end
end
function TranslateCall(callData)
for i, v in pairs(callData) do
local PlrId = callData.PlrId
local Ttype = callData.Type
local value = callData.Value
local LPlrFol = PlayerDataFolder[PlrId]
local SVal = LPlrFol[Ttype]
SVal.Value = SVal.Value + value
end
end
Players.PlayerAdded:Connect(function(player) UnloadPlayerData(player.UserId) end)
Players.PlayerRemoving:Connect(function(player) PackPlayerData(player.UserId) end)