Trouble with levelling system

Greetings developers!
I’ve been having issues when making a levelling system w/ datastores. Seems to be working fine, but every time i rejoin the game i automatically get an extra level for no reason. How could i avoid this?
Code:

Players.PlayerAdded:Connect(function(player)	
	local Folder = Instance.new("Folder", player)
	Folder.Name = "Level"
	
	local Level = Instance.new("NumberValue", Folder)
	Level.Name = "Level" -- yeah Level.Level
	Level.Value = 1
	
	local Exp = Instance.new("NumberValue", Folder)
	Exp.Name = "Exp"
	Exp.Value = 0
	
	local NeededExp = Instance.new("NumberValue", Folder)
	NeededExp.Name = "NeededExp"
	if Level.Value == 0 then
		NeededExp.Value = 50
	else
		NeededExp.Value = Level.Value * 50 
	end
	
	Exp.Changed:Connect(function()
		if Exp.Value >= NeededExp.Value then
			Exp.Value = 0
			Level.Value += 1
			NeededExp.Value = Level.Value * 50
		end
	end)
1 Like

I don’t see any of the retrieving and putting data here at all? Otherwise, it doesn’t seem like there is any problem with this.

Are you using DatastoreSerive to save your progress when you leave or is this code directly copy and pasted and doesn’t use DatastoreService? If not, I don’t really see a problem here

We need more information on how you’re saving it.

“Exp changed” appears to be firing when you load data. My guess:

1)you are not updating the “exp needed” before loading exp gained. If exp gained is greater than 50x level 1(the default value) level is gained.

  1. exp gained might not be resetting and saving correctly. You should probably save immediately after levelling.

To fix the problem with the extra level i would add an extra function to detect when a level changed for example:

Level.Changed:connect(function()
NeededExp.Value = Level.Value * 50
end)

Maybe it would fix the problem

like @GolgiToad said earlier

Here’s the full script, i thought what i showed would be enough to fix the problem:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local LevelsStore = DataStoreService:GetDataStore("LevelsStoring")

Players.PlayerAdded:Connect(function(player)
--Setting values up
	
	local Folder = Instance.new("Folder", player)
	Folder.Name = "Level"
	
	local Level = Instance.new("NumberValue", Folder)
	Level.Name = "Level"
	Level.Value = 1
	
	local Exp = Instance.new("NumberValue", Folder)
	Exp.Name = "Exp"
	Exp.Value = 0
	
	local NeededExp = Instance.new("NumberValue", Folder)
	NeededExp.Name = "NeededExp"
	if Level.Value == 0 then
		NeededExp.Value = 50
	else
		NeededExp.Value = Level.Value * 50 
	end
		
	
	Exp.Changed:Connect(function(NewExp)
		if Exp.Value >= NeededExp.Value then
			Exp.Value -= NeededExp.Value
			Level.Value += 1
			NeededExp.Value = Level.Value * 50
		end
	end)
	
	local ddatalevels
	local expdata
	local neededexpdata
	
	
	local success, errormessage = pcall(function()
		ddatalevels = LevelsStore:GetAsync(player.UserId.."-Level")
		expdata = LevelsStore:GetAsync(player.UserId.."-Exp")
		neededexpdata = LevelsStore:GetAsync(player.UserId.."-NeededExp")
	end)
	
	if success then
		Level.Value = ddatalevels
		Exp.Value = expdata
		NeededExp.Value = neededexpdata
	else
		warn(errormessage)
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local success, errormessage = pcall(function()
		local leveldata = LevelsStore:SetAsync(player.UserId.."-Level", player.Level.Level.Value) 
		local Expdata = LevelsStore:SetAsync(player.UserId.."-Exp", player.Level.Exp.Value) 
		local NeededExpdata = LevelsStore:SetAsync(player.UserId.."-NeededExp", player.Level.NeededExp.Value) 
		
	if success then	
		print("Data was saved!")
	else	
		warn("Hello world! "..errormessage)	
	end
	
end)

game:BindToClose(function()
	for i, playepplrs in pairs(Players:GetPlayers()) do
		playepplrs:Kick("Server has been shutted down.")
	end
	wait(2)
end)

Sorry if it looks messy, it’s my first time using datastores

When you are getting an extra lvl is the level 2 or 1 after you joined? Im sorry if the question is a bit dumb but it helps me to understand your problem

I would suggest to put a wait() in between

Level.Value = 1
..
Exp.Value = 0
..

wait()

if Level.Value == 0 then
NeededExp.Value = 50
else
NeededExp.Value = Level.Value * 50
end

Exp.Changed..

Because sometimes the script is faster than the game especially witth data stores. Maybe this will fix the problem

you could just make table in datastore to save stats like this

local Key  = player.UserId
local Data = {
      Exp = player.Level.Exp.Value;
      ExpNeeded = player.Level.NeededExp.Value;
      Level = player.Level.Level.Value;
}
LevelsStore:SetAsync(Key, Data)

This seems to have fixed the problem, thanks!

1 Like