Here is the code:
local dataStore = game:GetService("DataStoreService")
local levelData = dataStore:GetDataStore("LevelSaveSystem")
local xpData = dataStore:GetDataStore("XPSaveSystem")
local goldData = dataStore:GetDataStore("GoldSaveSystem")
game.Players.PlayerAdded:connect(function(player)
local leaderstats = Instance.new("Folder", player)
leaderstats.Name = "leaderstats"
local level = Instance.new("IntValue", leaderstats)
level.Name = "Level"
local XP = Instance.new("IntValue", leaderstats)
XP.Name = "XP"
local gold = Instance.new("IntValue", leaderstats)
gold.Name = "Gold"
local userLevel
local userXP
local userGold
local success, err = pcall(function()
userLevel = levelData:GetAsync(player.UserId) or 1
userXP = xpData:GetAsync(player.UserId)
userGold = goldData:GetAsync(player.UserId)
end)
if success then
if userLevel and userXP and userGold then
wait()
level.Value = userLevel
XP.Value = userXP
gold.Value = userGold
end
elseif err then
player:Kick("Save Data not loaded, please try rejoining.")
end
print(err)
game.Players.PlayerRemoving:connect(function(player)
local currentLevel = level.Value
local currentXP = XP.Value
local currentGold = gold.Value
local success, err = pcall(function()
levelData:SetAsync(player.UserId, currentLevel)
xpData:SetAsync(player.UserId, currentXP)
goldData:SetAsync(player.UserId, currentGold)
end)
if success then
print("Data Successfully Saved for user "..player.UserId)
end
if err then
print("There was an error in saving data!")
warn(err)
end
end)
end)

2 comments
It was actually because I had it embeded in the player added event so it just didnt run properly lol
If you ever wanted to make it so if the developer shuts down, you'd have to use BindToClose to do that. Data gets functioned or :GetAsync() whenever you join the game, when you go out and leave the game it will unfunction, I recommend getting a key such as like local Save = "Money_"..player.UserId, getting the async of that and wrapping both player removed and player added events.