Recently I made my first ever XP and Rank script using leaderstats and stuff.
This is the code:
local plrleaderstats = script.Parent.Parent.Parent.Parent:WaitForChild("leaderstats")
local XP = plrleaderstats:WaitForChild("XP")
local Rank = plrleaderstats:WaitForChild("Rank")
while true do
wait(0.1)
if XP.Value == script.Parent.ReachXP.Value then
script.Parent.ReachXP.Value = script.Parent.ReachXP.Value + 100
XP.Value = 0
Rank.Value = Rank.Value + 1
end
end
There’s also another script, handling the textlabel’s text:
local plrleaderstats = script.Parent.Parent.Parent.Parent:WaitForChild("leaderstats")
local XP = plrleaderstats:WaitForChild("XP")
while true do
wait(0.1)
script.Parent.Text = "XP: ".. XP.Value.. "/".. script.Parent.ReachXP.Value
end
When I give myself more points, it resets the count and puts it at 100 (the amount I gave myself, including 500 points), and keeps me at the same rank I was before. (1)
The problem is likely this line if XP.Value == script.Parent.ReachXP.Value then
When you use ==, you’re essentially stating that the two values are 100% equivalent - meaning there’s no room for deviation which occurs during e.g. floating-point error.
I’d believe >= (greater than or equals to) would ‘fix’ this.
As @Avallachi mentioned, it’s better to use >= instead of == so if you have a number greater than the needed, it’ll still run the condition. Here’s how you would do that
while true do
wait(0.1)
if XP.Value >= script.Parent.ReachXP.Value then
XP.Value -= script.Parent.ReachXP.Value
script.Parent.ReachXP.Value += 100
Rank.Value += 1
end
end
I also used compound assignments since they can h elp shorten increment/decrement code in this case. Also, I would recommend converting the while loop to a .Changed event on the XP BaseValue so it will only check the condition if XP was changed, not every tenth of a second
Is the first code a regular Script? If so, it won’t see if you change your xp on the client which you’re probably doing if you’re manually using the explorer and properties windows to edit your xp.
To go to server view where you can change values directly on the server, you’ll have to toggle this button during a playtest:
Here’s what I would do instead to make this more efficient:
Step 1: Organize the XP System in ServerScriptService
So the first thing that I would do is go ahead, is obviously handle the XP changes on the server (Since changing them client-wise wouldn’t work), so let’s go ahead, create a script inside ServerScriptService. I think it’d be more better to create a Folder inside the Player Object, and put IntValues inside them so it’s easier organize, so let’s put this inside our script:
print("[System] XP System Online")
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "stats"
leaderstats.Parent = Player
local XP = Instance.new("IntValue")
XP.Name = "XP"
XP.Parent = leaderstats
local Rank = Instance.new("IntValue")
Rank.Name = "Rank"
Rank.Parent = leaderstats
local ReachXP = Instance.new("IntValue")
ReachXP.Name = "ReachXP"
ReachXP.Value = 100
ReachXP.Parent = Player
end)
The PlayerAdded event will always fire whenever a Player object joins the game, & every player will all get the same stats when they join
Now, what we can do next is go ahead (With our variables we defined earlier) is look for a Value change whenever the XP value changes, adding onto our code:
print("[System] XP System Online")
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "stats"
leaderstats.Parent = Player
local XP = Instance.new("IntValue")
XP.Name = "XP"
XP.Parent = leaderstats
local Rank = Instance.new("IntValue")
Rank.Name = "Rank"
Rank.Parent = leaderstats
local ReachXP = Instance.new("IntValue")
ReachXP.Name = "ReachXP"
ReachXP.Value = 100
ReachXP.Parent = Player
XP.Changed:Connect(function()
if XP.Value >= ReachXP.Value then
print(Player.Name.." has ranked up!")
ReachXP.Value += 100
XP.Value = 0
Rank.Value += 1
end
end)
end)
The Changed Event will pretty much fire whenever a Value object changes, and so we’re checking if the XP Value is greater than or equal to the ReachXP Value, if it is then we can rank up that player & increase the ReachXP value!
This is a much better way of doing it, instead of while true do as it may result in minor lag/delay since it’s not doing unnecessary checks every 0.1 seconds
Step 2: Go ahead and test out the script!
If you’ve hopefully done everything well, you should try the script! Click “Play” and attempt to change the Value from the server-side! Let’s say that I change Player1’s XP to 50, nothing happens cause the Player hasn’t met the correct requirements in relation to the XPReach Value but…What if I change it to 100 XP? Then it meets the correct if statement requirements & we can go ahead and rank up that player! If everything just so happens not to, then do make sure to debug it with print() statements & breakpoints!
Full code in its entirely in ServerScriptService:
print("[System] XP System Online")
game.Players.PlayerAdded:Connect(function(Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "stats"
leaderstats.Parent = Player
local XP = Instance.new("IntValue")
XP.Name = "XP"
XP.Parent = leaderstats
local Rank = Instance.new("IntValue")
Rank.Name = "Rank"
Rank.Parent = leaderstats
local ReachXP = Instance.new("IntValue")
ReachXP.Name = "ReachXP"
ReachXP.Value = 100
ReachXP.Parent = Player
XP.Changed:Connect(function()
if XP.Value >= ReachXP.Value then
print(Player.Name.." has ranked up!")
ReachXP.Value += 100
XP.Value = 0
Rank.Value += 1
end
end)
end)
Either you’ve probably changed the value client-sided, or you’ve probably parented the variables way too much that the script couldn’t detect it? Do make sure to use print() statements when debugging your code