Help needed on Level System

Hello Developers, I currently need help on a level system. The problem is that lets say I have a total of 54xp and in level 1, when I leave the game, the data saves and when I rejoin I am level 54.
Here is the script, any help is appreciated:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("LevelSystem") 

game.Players.PlayerAdded:Connect(function(player)
    local level = Instance.new("IntValue", player)
    level.Name = "Level"
    level.Value = 1
    
    local exp = Instance.new("IntValue", level)
    exp.Name = "Current"
    exp.Value = 0
    
    local maxExp = Instance.new("IntValue", level)
    maxExp.Name = "Max"
    maxExp.Value = 100
    
    
    exp.Changed:Connect(function(val)
        if exp.Value >= maxExp.Value then
            level.Value = level.Value + 1
            exp.Value = 0
            maxExp.Value = maxExp.Value * 1.25
        end
        

        
    end)
    
    local Data = DataStore:GetAsync(player.UserId)

    if Data then

        level.Value = Data
        exp.Value = Data
        maxExp.Value = Data

    end
    
end)





game.Players.PlayerRemoving:Connect(function(Player)

    DataStore:SetAsync(Player.UserId, Player.Level.Value) 
    DataStore:SetAsync(Player.UserId, Player.Level.Current.Value)
    DataStore:SetAsync(Player.UserId, Player.Level.Max.Value) 

end)

game.Players.PlayerAdded:Connect(function(player)
    
    while true do
        wait(1)
        player.Level.Current.Value = player.Level.Current.Value + 5
    end
    
end)

You are saving it all under one key. Make the 3 things you want to save into a table and save that once under they key. You should also put your datastore getting and saving in a pcall because it doesnt always work

1 Like

How would that be done? I am not really good with pcalls.

Errors:

  • You are connecting the same event twice.
  • You are setting 3 values to a same DataStore, so it won’t add, instead it will be replaced.
  • You are not using :BindToClose() to secure the data save after the server is closed.

Instead you should use a table for the values:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("LevelSystem") 

game.Players.PlayerAdded:Connect(function(player)
	local level = Instance.new("IntValue", player)
	level.Name = "Level"
	level.Value = 1

	local exp = Instance.new("IntValue", level)
	exp.Name = "Current"
	exp.Value = 0

	local maxExp = Instance.new("IntValue", level)
	maxExp.Name = "Max"
	maxExp.Value = 100


	exp.Changed:Connect(function(val)
		if exp.Value >= maxExp.Value then
			level.Value += 1
			exp.Value = 0
			maxExp.Value = maxExp.Value * 1.25
		end



	end)

	local Data = DataStore:GetAsync(player.UserId)

	if Data then

		level.Value = Data[1]
		exp.Value = Data[2]
		maxExp.Value = Data[3]

	end
	
	while true do
		wait(1)
		player.Level.Current.Value += 5
	end
end)





game.Players.PlayerRemoving:Connect(function(Player)
	local Values = {
		Player.Level.Value;
		Player.Level.Current.Value;
		Player.Level.Max.Value
	}

	DataStore:SetAsync(Player.UserId, Values) 

end)

game:BindToClose(function()
	for i, client in pairs(game.Players:GetPlayers()) do
		local Values = {
			client.Level.Value;
			client.Level.Current.Value;
			client.Level.Max.Value
		}

		DataStore:SetAsync(client.UserId, Values) 
	end
end)
2 Likes

Make the saving function like this:

game.Players.PlayerRemoving:Connect(function(Player)

    dataToSave = {Player.Level.Value, Player.Level.Current.Value, Player.Level.Max.Value}

    local success, error = pcall(function()
        DataStore:SetAsync(player.UserId, dataToSave)
    end)
    
    if success then
        print("success")
    else
        warn(error)
    end

end)

Sorry, I started typing this and then had to go so I took a while to post it!

EDIT: This was already said above, sorry. As I said, I started typing it before @Sarchyx had sent their post