Visual issue with MaxEXP value in leveling system

  1. Fixing these 2 visual bugs with MaxEXP value 1st issue is when the player joins the game when there higher then level 1 they would have a different MaxEXP value then level 1 which has 100 MaxEXP value Ex: level 2 players would need to get 125 Exp to level up as when the player levels up by 1 level each time the MaxEXP is multiplied by 1.25 but half the time the player joins they are set at 100 MaxEXP but still have the Exp and level that they had when they last left theres no issues with the Datastores as when the player gets more exp it changes back to the MaxEXP value its supposed to be at… The 2nd issue is when the player does level up its doesnt change the MaxEXP until they get more EXP after leveling up!

First image shows my MaxEXP is 244 but thats the value from level 5 it still carries over to level 6 with no change to MaxEXP value.
image

2nd image shows that I gained some more EXP but also that the MaxEXP value has changed to the value its supposed to be even though it shouldve changed right when I leveled up.
image

third image shows that when a player who already has a higher level and has played befores MaxEXP level is set to 100 when they join but when they gain more Exp the MaxEXP value is set to where its supposed to be.
image

This is the code section thats causing the problem from what I know of.

exp.Changed:Connect(function(val)
		if exp.Value >= maxExp.Value then

			level.Value = level.Value + 1
			exp.Value = exp.Value - maxExp.Value
			maxExp.Value = maxExp.Value * 1.25
			
		end
	end)

Solutions I have tired are useing level.Changed but it just puts me at -Exp value

I saw one possible solution saying I should add a wait() but I already have one and its just the MaxEXP value thats having an issue nothing else…

Try running the code contained within the changed event once, ontop of having it in the changed event.

It’s possible that the value is changed initially before the connection is made, hence the script doesn’t fire.

i.e.

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

or

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

It still does’nt work :confused: Should I send whole script?

Yes, that would help fix your problem.

This is whole code for level system

local ds = game:GetService("DataStoreService"):GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(player)
	repeat task.wait() until player:FindFirstChild("Stats")
	local level = Instance.new("IntValue")
	level.Parent = player:FindFirstChild("Stats")
	level.Name = "Level"
	level.Value = 1

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

	local maxExp = Instance.new("IntValue")
	maxExp.Parent = level
	maxExp.Name = "Max"
	maxExp.Value = 100
	
	wait()
	local plrkey = "id_2"..player.userId
	local save1 = level
	local save2 = exp
	local save3 = maxExp

	local GetSaved = ds:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
	else
		local NumberForSaving = {save1.Value, save2.Value, save3.Value}
		ds:GetAsync(plrkey, NumberForSaving)
	end
   local function UpdateXP()
		if exp.Value >= maxExp.Value then
			level.Value = level.Value + 1
			exp.Value = exp.Value - maxExp.Value
			maxExp.Value = maxExp.Value * 1.25
		end
	end
	UpdateXP()
	exp.Changed:Connect(UpdateXP)
	
	
end)



local db = 1

local EasyEXP = math.random(40,70)
local MediumEXP = math.random(200,300)
local HardEXP = math.random(500,750)

--EASY DIFFICULTY

--RainbowRoad
workspace.ObbyWorldsASSETS.ObbyMaps.RainbowRoad:WaitForChild("Rainbow road (End)").Touched:Connect(function(hit) --Fixed EXP dupe Bug still problem with MaxEXP
	local hum = hit.Parent:FindFirstChild("Humanoid")
	local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if hum ~= nil and db == 1 and Player ~= nil and Player:FindFirstChild("Stats")  then
		db = 2
		Player.Stats.Level.Current.Value = Player.Stats.Level.Current.Value + EasyEXP
		wait(2)
		db = 1 
	end
end)
--RiverHop
workspace.ObbyWorldsASSETS.ObbyMaps.RiverHop:WaitForChild("River Hop (End)").Touched:Connect(function(hit)
	local hum = hit.Parent:FindFirstChild("Humanoid")
	local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if hum ~= nil and db == 1 and Player ~= nil and Player:FindFirstChild("Stats")  then
		db = 2
		Player.Stats.Level.Current.Value = Player.Stats.Level.Current.Value + EasyEXP
		wait(2)
		db = 1 
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_2"..plr.userId, {plr.Stats.Level.Value, plr.Stats.Level.Current.Value, plr.Stats.Level.Max.Value})
end)

Can you please post your gui script that updates user info on screen?

This is main script (local script)

repeat task.wait() until game.Workspace.CurrentCamera and game.Players.LocalPlayer
--Player-Variables
local player = game.Players.LocalPlayer
local stat = player:WaitForChild("Stats")
local level = stat:WaitForChild("Level")
local current = level:WaitForChild("Current")
local max = level:WaitForChild("Max")

--UI-Variables
local gui = script.Parent
local exterior = gui:WaitForChild("Exterior")
local label = exterior:WaitForChild("Label")
local exp = exterior:WaitForChild("EXP")
local bar = exterior:WaitForChild("Bar")

--Change stats when joins
label.Text = "Level "..level.Value
exp.Text = current.Value.."/"..max.Value.." EXP"
bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)

level.Changed:Connect(function(val)
	label.Text = "Level "..level.Value
	exp.Text = current.Value.."/"..max.Value.." EXP"
	bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
end)

current.Changed:Connect(function(val)
	exp.Text = current.Value.."/"..max.Value.." EXP"
	bar.Size = UDim2.new(current.Value/max.Value, 0, 1, 0)
end)

The issue is that you change maxexp after current and level and that doesn’t trigger the update. You have to change it before other values or add another update handler.

I managed to fix it sorta both issues are fixed but now when the player levels up they have negative EXP

local function UpdateXP()
		if exp.Value >= maxExp.Value then
			level.Value = level.Value + 1
			
		
			maxExp.Value = maxExp.Value * 1.25
			wait()
			exp.Value = exp.Value - maxExp.Value
		end
	end
	UpdateXP()
	exp.Changed:Connect(UpdateXP)
	
	
end)

changes I made above ^

1 Like

Why do you use wait() here???

should I just get rid of it? thought i needed one so it could update

1 Like

image
still not working when i spawn in

image
when i gain more exp it fixes itself but nothing is working…

actually the wait() fixed the maxEXP not showing when i join but the negative exp when level up is still an issue

Obby Worlds (Testing Game) - Roblox Studio (gyazo.com)
This the only issue im seeing now and I know it has somethin to do with the code above its cause im subtracting the MaxEXP from the exp after it updates

1 Like

I fixed the Bug where when a player levels up it does’nt update until they get more exp after leveling up how ever the bug where its not showing the players MaxEXP when they join half the time it works but other half the time it doesnt work its just set to the starter which is 100 maxExp
This is the script i updated!

local function UpdateXP()
		if exp.Value >= maxExp.Value then
			
			exp.Value = exp.Value - maxExp.Value
			maxExp.Value = maxExp.Value * 1.25
			wait()
			level.Value = level.Value + 1
		end
	end
	UpdateXP()
	exp.Changed:Connect(UpdateXP)

Nothing else besides this has changed also when the player gets Exp after joining it updates the MaxEXP back to where its supposed to be but for some reason it doesnt do it when the player joins the server half the time…
image
I think it may be somethin to do with the datastore but all the other values are loading in so idk :confused: do you know why this problem is happening?

1 Like

Yes, you definetely should. It can cause lags.

1 Like

Can you please describe your problem with more information?

1 Like

I have datastores in the level script that saves all players Exp, MaxExp and Level Values for when they join again it should load the values they had when they last left. The Exp and Level values load in for all players 100% of the time when they join however the MaxEXP only loads in half the time for all players so sometimes when player joins they will have the amount of Exp and there level from when they last left the game out of 100 MaxEXP. Example is the image above where I loaded in but it didnt load in my MaxExp so I had 246/100. 100MaxExp is what all new players start with at level 1 but if the player gained EXP after joining the MaxEXP would change back to the amount its supposed to be
Vid showing problem below vVv
Obby Worlds (Testing Game) - Roblox Studio (gyazo.com)
At the start is the Max ammount I had when I joined but once I gained more EXP the MaxEXP goes back to normal

Also getting this in the output could this be problematic to?
image

1 Like

Save the data when player disconnects instead of every update.

1 Like

I am saving all three values when the player leaves.

game.Players.PlayerRemoving:Connect(function(plr)
	ds:SetAsync("id_2"..plr.userId, {plr.Stats.Level.Value, plr.Stats.Level.Current.Value, plr.Stats.Level.Max.Value})
end)

Tried using Bindtoclose: but would keep getting errors

1 Like

This is a common problem in event-driven programming. All you have to do is encapsulate the code within the event into a separate function and call it once outside of the event on startup(as if you’re initiating a system):

local function expChanged(val: number)
	if exp.Value < maxExp.Value then return end
	level.Value += 1
	exp.Value -= maxExp.Value
	maxExp.Value *= 1.25
end

task.spawn(expChanged, exp.Value)
exp.Changed:Connect(onExpChanged)

Also, ensure the player data has loaded before calling expChanged for the first time.

1 Like

I fixed it! It wasn’t working because there was a Wait() right above local plrkey = “id_2”…player.userId
Thx for helping me figure it out!

2 Likes