I recently started learning about and implementing data stores to my games. I decided to try making an RPG but wanted to know what the best way to structure my data is without repeating the same thing over and over again to get all stats in. I want to be able to store all things that would go under player data like weapon, armor, all inventory things, exp, levels, money, stats, skills, and more like that. If I were to use the data storage system I currently made, it would end up getting very very cluttered in the code. Does anyone have recommendations on a way I can set up a system that better fits my goal? Thank you in advance and here is the current code I am using (just for levels atm).
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local Database = DataStoreService:GetDataStore("Data")
local SessionData = {}
function WipeData(UID)
if SessionData[UID] then
Database:RemoveAsync(UID)
print("WIPED SESSION DATA FOR " .. UID)
elseif Database:GetAsync(UID) then
Database:RemoveAsync(UID)
print("WIPED STORED DATA FOR " .. UID)
elseif UID == "All" then
local pages: DataStoreKeyPages = Database:ListKeysAsync()
while true do
local keys: {DataStoreKey} = pages:GetCurrentPage()
for _, key in ipairs(keys) do
Database:RemoveAsync(key.KeyName)
end
if pages.IsFinished then break end
pages:AdvanceToNextPageAsync()
end
print("All data has been wiped!")
end
end
function PlayerLeaving(player)
if SessionData[player.UserId] then
print("Found data for ", player.UserId)
local success = nil
local errorMsg = nil
local attempt = 1
repeat
success, errorMsg = pcall(function()
Database:SetAsync(player.UserId, SessionData[player.UserId])
print("Data saved as:", SessionData[player.UserId])
end)
attempt += 1
if not success then
warn(errorMsg)
task.wait(3)
end
until success == true or attempt >= 5
if success == true then
print("Data saved for:", player.Name)
else print(attempt)
end
end
end
local function LoadData(player)
local Data = Instance.new("Folder")
Data.Name = "Data"
local character = player.Character or player.CharacterAdded:Wait()
local Level = Instance.new("IntValue")
Level.Name = "Level"
Level.Parent = Data
local Success = nil
local playerData = nil
local attempt = 1
repeat Success, playerData = pcall(function()
return Database:GetAsync(player.UserId)
end)
attempt += 1
if not Success then
warn(playerData)
task.wait(3)
end
until Success == true or attempt >= 5
if Success then
print("Grabbed data for ",player.UserId,":", playerData)
if not playerData then
print("Creating new data...")
playerData = {
["Level"] = 1,
}
end
SessionData[player.UserId] = playerData
else
warn("Unable to get data")
player:Kick("Data loading issue. Try again later.")
end
--int loading
Level.Value = SessionData[player.UserId].Level
--int sync
Level:GetPropertyChangedSignal("Value"):Connect(function()
SessionData[player.UserId].Level = Level.Value
end)
-- Object loading
Data.Parent = player
end
Players.PlayerRemoving:Connect(PlayerLeaving)
Players.PlayerAdded:Connect(LoadData)