My current system involves of one script that has a PlayerAdded event connected to a function that runs PlayerData module, which then runs my LeaderStats module. The PlayerData module also runs when the PlayerRemoving event is fired.
Server Script:
local Services = script.Parent.Services;
local Players = game:GetService("Players");
local PlayerDataService = require(Services.PlayerDataService); --module script
local function onPlayerAdded(player: Player)
PlayerDataService.onPlayerAddedAsync(player)
end
local function onPlayerRemoving(player: Player)
PlayerDataService.onPlayerRemoving(player)
end
Players.PlayerRemoving:Connect(onPlayerRemoving)
Players.PlayerAdded:Connect(onPlayerAdded)
game:BindToClose(function()
for _, player in Players:GetPlayers() do
onPlayerRemoving(player)
end
end)
Player Data Module
--!strict
local DataStoreService = game:GetService("DataStoreService")
local mainDataStore = DataStoreService:GetDataStore("mainDataStore", "DEV");
local LeaderstatsService = require(script.Parent.LeaderstatsService)
local PlayerDefaultData = require(script.PlayerDefaultData) --module script
--[[
local PlayerDefaultData = {}
export type playerData = {
minutes: number,
points: number,
}
PlayerDefaultData._defaultData = {
minutes = 0,
points = 0
}:: playerData
return PlayerDefaultData
]]--
local prefix = "user_";
_G._playerData = {}:: {[Player]: PlayerDefaultData.playerData};
local PlayerDataService = {}
function PlayerDataService.onPlayerAddedAsync(player: Player)
assert(player:IsA("Player"), "Invalid player argument")
local key = prefix..player.UserId;
local data: PlayerDefaultData.playerData;
local success, err = pcall(function()
data = mainDataStore:GetAsync(key);
end)
if not success then
warn(err)
data = PlayerDefaultData._defaultData;
elseif not data then
data = PlayerDefaultData._defaultData;
end
_G._playerData[player] = data;
LeaderstatsService.newPlayer(player, data.minutes, data.points)
end
function PlayerDataService.onPlayerRemoving(player: Player)
assert(player:IsA("Player"), "Invalid player argument")
local key = prefix..player.UserId;
local data: PlayerDefaultData.playerData = _G._playerData[player];
print(data)
local tries = 0;
local MAX_TRIES = 5;
local success, err
repeat
success, err = pcall(function()
mainDataStore:SetAsync(key, data)
end)
tries += 1
until success or tries == MAX_TRIES;
if success then print("SUCCESSFULLY SAVED DATA") end
end
return PlayerDataService
Leaderstats Module
--!strict
local LeaderstatsService = {}
function LeaderstatsService.newPlayer(player: Player, minutes: number, points: number)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player;
local _minutes = Instance.new("IntValue")
_minutes.Name = "Minutes"
_minutes.Parent = leaderstats
_minutes.Value = minutes
local _points = Instance.new("IntValue")
_points.Name = "Points"
_points.Parent = leaderstats
_points.Value = points
end
return LeaderstatsService
Sorry if this is super messy and all over the place. I am new to SSA and any advice would greatly be appreciated! I was thinking of having the LeaderstatsModule create a new leaderstats object that has methods to edit the minute value and point value. With this I would edit the minute value and point value after loading the data from the datastore and setting it within the PlayerAdded event.