local dataStoreService = game:GetService("DataStoreService")
local players = game:GetService("Players")
local dataStore = dataStoreService:GetDataStore("Name")
local function leaderboardSetUp(player)
local userId = player.UserId
local key = "Player_" .. userId
local data = dataStore:GetAsync(key)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local money = Instance.new("IntValue")
money.Name = "Money"
money.Value = data or 0
money.Parent = leaderstats
print("Leaderstats loaded.")
end
You’ve probably run into an infamous race condition that will surely be more prominent in the future which has to do with running a yielding function before PlayerAdded connects. I encourage you, as well as any other developer, to apply the following boilerplate when working with PlayerAdded:
local Players = game:GetService("Players")
local function playerAdded(player)
end
Players.PlayerAdded:Connect(playerAdded)
for _, player in ipairs(Players:GetPlayers()) do
playerAdded(player)
end
Where you originally write your PlayerAdded code you’d be writing into the function on the variable playerAdded. This boilerplate connects the given function to PlayerAdded and additionally runs the function for any players who joined the server before the PlayerAdded function connected.
An additional nitpick but please do make sure to parent your objects after you set their properties. It is also important that you pcall DataStore methods. If there is a DataStore outage, your script may either fail or cause data loss. If players still have data but the endpoints are not available you don’t handle this case of error and that can be catastrophic for your game in the long run. Last important thing is to use a table if you intend to store more than just cash - this current paradigm may lead you into creating more DataStores and keys for different data which will present you a different issue relating to overstepping DataStore limits.
Yes, though of course replace playerAdded with leaderboardSetUp. I don’t know if you run additional code so there may be other adjustments you need to make depending on your system. I just provided general boilerplate to avoid running into this race condition/yielding oversight.
what is the point of this exactly?
it would literally run once when the game starts, and this would be useless because the server script would run that code before any player was added to the :GetPlayers() table
That’s the whole point of that piece of code. If you have a yielding function before a function can be connected to PlayerAdded then its connection time will be deferred. Any player who connects to the server ahead of the PlayerAdded connection registering will not have the function run for them, so that piece of code is intended to run the function on players who did not have it run before.