Help on a while wait() do statement

The leaderstats of my game uses While wait() do, let’s use a level up system as example:

while wait() do
    if Xp.Value >= Maxxp.Value then
        Level.Value = Level.Value + 1
        Xp.Value = Xp.Value - Maxxp.Value
    end
end

And i saw that while wait() do is a bad practice, and now my question is, how i change this? To use something similar to while wait() do. Thanks :+1:

3 Likes

This loop certainly gets the job done, but as you pointed out its bad practice and might affect performance on a larger scale. For this issue, the solution is what’s called an Event. Events don’t constantly fire, they only do once a certain action occurs.


Switching your loop out for an event is actually really easy. We don’t always need to check the experience, simply check it when it’s changed! Roblox instances come with a neat event called .Changed which fires when a property of the instance it derives from is changed - this is perfect for our code!

function CheckExperience (NewValue) 
    --Run code here! 
end

--Create and Connect the event to CheckExperience() 
Xp.Changed:Connect(CheckExperience)

Tip: When using .Changed on a ValueContainer, it will also pass the new value as an argument (Labeled NewValue in the example above). This means we can skip defining the value and get straight to the code, precious lines saved!

Good luck with your game! :wink:

6 Likes

I can’t right now test the code since im in phone, but i can do something like this?

function CheckExperience (NewValue) 
    if Xp.Value >= Maxxp.Value then
        Level.Value = Level.Value + 1
        Xp.Value = Xp.Value - Maxxp.Value
    end
end

Xp.Changed:Connect(CheckExperience)

That’s more like it! Don’t forget you have NewValue though (Same as Xp.Value).

function CheckExperience (NewValue) 
    if NewValue >= Maxxp.Value then
        Level.Value = Level.Value + 1
        NewValue = NewValue - Maxxp.Value
    end
end

Xp.Changed:Connect(CheckExperience)

And i must index the NewValue? (NewValue = Xp.Value)

Nope! NewValue is already defined as it was sent through the event. No need to index it either, the event only fires once the value already has been changed by another script.

You should just check for the level in the function that gives the XP in the first place.

-- you can use this function anywhere e.g. if quests have been completed
-- or if someone finds something wherever in your script you want
-- as long as you use the correct arguments
-- NOTE: ALL the values mentioned above MUST be a NumberValue otherwise
-- you will have to use tonumber()
function addxp(name,userid,amount)
    local Xp = where the Xp value is stored
    local Maxxp = where the Maxxp value is stored
    local Level = where the Level value is stored
    if game.Players:FindFirstChild(name) then
        local new = Xp.Value + amount
        if new <= Maxxp.Value then
            Xp.Value = new
        else
            local missed = (Xp.Value + amount) - Maxxp.Value
            Xp.Value = missed
            Level.Value = Level.Value + 1
        end
    end
end

coroutine.wrap(function()
    local Time = 60 -- time in seconds you want between earning xp (1 min)
    local Amount = 10 -- amount of xp given current is 10
    while wait(Time) do
        addxp(player.Name, player.UserId, 10)
    end
end)();
2 Likes