Hello! I’ve spent the past few hours creating a ModuleScript for loading/saving player’s data. And I’m currently looking for any improvements!
local DataStoreService: DataStoreService = game:GetService("DataStoreService")
local dataStore: DataStore = DataStoreService:GetDataStore("PlayerData_2")
local dataTemplate = {
["Boosts"] = {
["Red"] = 0;
["Blue"] = 0;
["Green"] = 0;
["Pink"] = 0;
["Purple"] = 0;
["Golden"] = 0;
};
["CharacterPositions"] = {
["X"] = 0;
["Y"] = 0;
["Z"] = 0;
};
["Currency"] = {
["Candy"] = 0;
["Redeemed"] = 0;
["Time"] = 0;
};
["GamePasses"] = {
["X2Time"] = false;
["X5Time"] = false;
["X10Time"] = false;
["Vip"] = false;
};
["Misc"] = {
["Halloween2024"] = false;
["TransferredData"] = false;
["ReceivedVipPerks"] = false;
};
["CodesRedeemed"] = {};
["UGCsPurchased"] = {};
}
local dataModule = {}
function dataModule.loadData(player: Player)
local playerData = dataModule.getData(player)
local function loadBoosts()
for boostName: string, boostTime: number in playerData.Boosts do
player:SetAttribute(boostName.."Boost", boostTime)
end
end
local function loadLastPosition()
local posX: number = playerData.CharacterPositions.X
local posY: number = playerData.CharacterPositions.Y
local posZ: number = playerData.CharacterPositions.Z
player:SetAttribute("LastPosition", Vector3.new(posX, posY, posZ))
end
local function loadCurrency()
for currencyName: string, currencyAmount: number in playerData.Currency do
player:SetAttribute(currencyName, currencyAmount)
end
end
local function loadGamePasses()
for gamePassName: string, hasGamePass: boolean in playerData.GamePasses do
player:SetAttribute("Owns"..gamePassName, hasGamePass)
end
end
local function loadMisc()
for miscName: string, miscValue: boolean in playerData.Misc do
player:SetAttribute(miscName, miscValue)
end
end
local loadSuccess, errorMessage = pcall(function()
loadBoosts()
loadLastPosition()
loadCurrency()
loadGamePasses()
loadMisc()
end)
if not loadSuccess then
warn("Error while loading player data: "..errorMessage)
player:Kick("Error while loading your data. Please rejoin.")
end
end
function dataModule.getData(player: Player)
local playerData: any
local getSuccess, errorMessage = pcall(function()
playerData = dataStore:GetAsync("Player_"..player.UserId)
end)
if not playerData then
playerData = dataTemplate
end
for dataType, _ in dataTemplate do
if not playerData[dataType] then
playerData[dataType] = dataTemplate[dataType]
warn("Added DataType: "..dataType)
end
for dataName, dataValue in dataTemplate[dataType] do
if playerData[dataType][dataName] == nil then
playerData[dataType][dataName] = dataValue
warn("Added DataName: "..dataName)
end
end
end
if getSuccess then
print(playerData)
return playerData
else
warn("Error while getting player data: "..errorMessage)
player:Kick("Error while getting your data. Please rejoin.")
end
end
function dataModule.saveData(player: Player)
local function createPlayerData()
local playerData = table.clone(dataTemplate)
playerData["Boosts"] = {
["Red"] = player:GetAttribute("RedBoost");
["Blue"] = player:GetAttribute("BlueBoost");
["Green"] = player:GetAttribute("GreenBoost");
["Pink"] = player:GetAttribute("PinkBoost");
["Purple"] = player:GetAttribute("PurpleBoost");
["Golden"] = player:GetAttribute("GoldenBoost");
};
playerData["CharacterPositions"] = {
["X"] = if player:GetAttribute("LastPosition") then player:GetAttribute("LastPosition").X else nil;
["Y"] = if player:GetAttribute("LastPosition") then player:GetAttribute("LastPosition").Y else nil;
["Z"] = if player:GetAttribute("LastPosition") then player:GetAttribute("LastPosition").Z else nil;
};
playerData["Currency"] = {
["Candy"] = player:GetAttribute("Candy");
["Redeemed"] = player:GetAttribute("Redeemed");
["Time"] = player:GetAttribute("Time");
};
playerData["GamePasses"] = {
["X2Time"] = player:GetAttribute("OwnsX2Time");
["X5Time"] = player:GetAttribute("OwnsX5Time");
["X10Time"] = player:GetAttribute("OwnsX10Time");
["Vip"] = player:GetAttribute("OwnsVip");
};
playerData["Misc"] = {
["Halloween2024"] = player:GetAttribute("Halloween2024");
["TransferredData"] = player:GetAttribute("TransferredData");
["ReceivedVipPerks"] = player:GetAttribute("ReceivedVipPerks");
};
playerData["CodesRedeemed"] = {};
playerData["UGCsPurchased"] = {};
return playerData
end
local playerData = createPlayerData()
local function doesDataExist()
for dataType, _ in playerData do
for dataName, dataValue in dataTemplate[dataType] do
if playerData[dataType][dataName] == nil then
return false
end
end
end
return true
end
if not doesDataExist() then
warn("Player data does not fully exist. Not saving data for player: "..player.Name)
return
end
local saveSuccess, errorMessage = pcall(function()
dataStore:SetAsync("Player_"..player.UserId, playerData)
end)
if saveSuccess then
print("Successfully saved data for player: "..player.Name)
else
warn("Error while saving player data: "..errorMessage)
end
end
return dataModule