XP not giving a new rank?

Hey everyone,

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)

Anything is appreciated, thanks!

1 Like

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

Hmmm, still does the same thing.
Also, the “ReachXP” thing is a IntValue under the textlabel, I’m not sure if this effects anything

Are you having any errors by any chance?

Nope, nothing in the output except other stuff

So let me see if I understand correctly, it correctly updates the XP and the ReachXP but doesn’t update the Rank once the condition is met?

Yes, that’s exactly what’s happening. If you need a video example I can show one

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:

image

image

Yes, including the text “handler”, so the other script can see the text change (their both server scripts)

You’re still likely changing the value on the client, which won’t make a difference.

image

(Reached is the first script and TextSet is the second script)

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)

Oh wow, thanks!

What do you think was the problem with the original server scripts?

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 :slightly_smiling_face:

1 Like