How i can fix this problem?

I have a script for the level system, at the beginning of the game and also at any level for some reason I have -1000 and so on, how to solve it?

Снимок экрана (14321)

script:

game.Players.PlayerAdded:Connect(function(Plr)
	local stats = Instance.new("Folder", Plr)
	stats.Name = "Data"
	
	local Levels = Instance.new("IntValue", stats)
	Levels.Name = "Levels"
	Levels.Value = 1
	local Exp = Instance.new("IntValue", stats)
	Exp.Name = "Exp"
	Exp.Value = 0
	local ExpNeed = Instance.new("IntValue", stats)
	ExpNeed.Name = "ExpNeed"
	ExpNeed.Value = 120
end)

game.Players.PlayerAdded:Connect(function(plr)
	wait(1)
	local Exp = plr.Data.Exp
	local Levels = plr.Data.Levels
	local ExpNeed = plr.Data.ExpNeed
	
	while wait() do
		if Exp.Value >= (100 + (Levels.Value + 1)) and Levels.Value <= 50 then
			
			Levels.Value = Levels.Value +1
			Exp.Value = Exp.Value - ExpNeed.Value
			ExpNeed.Value = ExpNeed.Value + 100
			
			game.ReplicatedStorage.LevelSystem.LevelUpGui:FireClient(plr)
		end
	end
end)

gui script:

local player = game.Players.LocalPlayer
local Exp = player:FindFirstChild("Data"):WaitForChild("Exp")
local Levels = player:FindFirstChild("Data"):WaitForChild("Levels")

while wait() do
	if Levels.Value == 1000 then
		script.Parent.Text = "Max Level"
	else
		script.Parent.Text = ""..Exp.Value.."/".. tostring(100 + (Levels.Value +1))
	end
end

Quick question: Is there DataStoreService involved in between those 2 Events?

If you mean by that as in a question about if there is Datastoreservice being used in that current script, I think so because you’re saving the levels into the Datastore and the exp and all that should be automatically saving to the datastoreservice, which I think is part of replicated storage or a similar way of usage.

Okay, assuming the player levels up every time it passes the ExpNeed, the Exp.Value would rather be checked by ExpNeed.Value instead of Exp.Value >= (100 + (Levels.Value + 1)), because 100 will only be increased by 1 everytime, thus making the value a bit higher but not higher than ExpNeed.Value. That’s why the negative value comes out. I’d suggest putting this instead:

while wait() do
		if Exp.Value >= ExpNeed.Value and Levels.Value <= 50 then
			Levels.Value = Levels.Value +1
			Exp.Value = Exp.Value - ExpNeed.Value
			ExpNeed.Value = ExpNeed.Value + 100
			
			game.ReplicatedStorage.LevelSystem.LevelUpGui:FireClient(plr)
		end
	end

I’ve checked it again and it works perfectly fine for me.
Have a good day!

we use data store service, yes, but i need remove that “-2800 for 0” but, player need “-2800”, but i need fix -2800 for 0 and yes, the datastore script :

game.Players.PlayerRemoving:Connect(function(player)
	local datastore = game:GetService("DataStoreService"):GetDataStore(player.Name.."Stats")
	local statsstorage = player:FindFirstChild("Data"):GetChildren()
	for i = 1, #statsstorage do 
		datastore:SetAsync(statsstorage[i].Name, statsstorage[i].Value)
	end
end)

game.Players.PlayerAdded:Connect(function(player)
	local datastore = game:GetService("DataStoreService"):GetDataStore(player.Name.."Stats")
	
	player:WaitForChild("Data")
	wait(1)
	local stats = player:FindFirstChild("Data"):GetChildren()
	for i = 1, #stats do
		stats[i].Value = datastore:GetAsync(stats[i].Name)
	end
end)

For the DataStore there are Issues in terms of unique keys. Every player has the same Name in Data, resulting that the dataStore only stores 3 keys = the keys get overwritten every time a player left.
I would recommend using a dictionary and a unique key for saving stats, especially big data.

for example you can use this line of code to get a unique key for a player by using its UserId:

local key = tostring(player.UserId .. "_data") 

then get every data in a table with a template:

local Data = {
       ["Level"] = 0
       ["Exp"] = 0
}

Data["Level"] = Level.Value
Data["Exp"] = Exp.Value

datastore:SetAsync(key, Data)

It also reduces using dataStore functions too much, because the server has a limit to calling them.
Hope this helps

Edit: Recall script

Players.PlayerAdded:Connect(function(plr)
        local key = tostring(plr.UserId .. "_data")
        local Data = datastore:GetAsync(key)
        plr:WaitForChild("Data").Levels.Value = Data["Level"]
        plr:WaitForChild("Data").Exp.Value = Data["Exp"]
end)

It could be because one of the numbers were set to - instead of a positive value or one of the <= and >= could have been set the wrong way, I’m not an extreme pro at scripting but that could be a possible error