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!
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)
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)();