How do I script exp and levels correctly?

I know I can do something simple like

if exp >= maxexp then
level = level + 1
exp = 0
end

but the problem with that is what if the player gains 2.5x the amount of exp. it should level them up 2 times and set the exp to the remaining exp they have left. how can I do this?

3 Likes

Minus the maxexp and then compare the exp to the next level maxexp.

Here’s an example:

local levelExp = {
    100, --level1, 100
    200 --level2, 200
}

local playerLevel = 0
local playerExp = 300

function updateLevel()
    if playerExp >= levelExp[playerLevel + 1] then
        playerExp = playerExp - levelExp[playerLevel + 1]
        playerLevel = playerLevel + 1
        updateLevel()
    end
end

updateLevel()
1 Like

I suggest calculating the level from a certain mathematical function instead of defining how much exp is needed for each level and this will easily let you have infinite amount of levels without much effort.

You can for example use the y = x^(1/2) function.

local lvl;
local xp;

function onXpChange()
     lvl = math.floor(math.sqrt(xp));
end

This function can be different to satisfy your needs.
So you no longer have to think about any level thresholds and a situation when you run out of predefined levels. Also if someone out of sudden gets for example 1 million xp, this will work instantly without any need to iteratively increase your level. What is more, when someone loses xp points this will also work and recalculate the level so it will be lower.

3 Likes

I believe you need to use totalExp and a function to calculate level from totalExp.


This is just a guess.

local function getMaxExpFromLevel(level)
	return -- insert any equation for experience or any method
end

local function levelFromExp(exp, level) -- recursive example
	local max = getMaxExpFromLevel(level)

	if exp >= max then
		level = level + 1
		return levelFromExp(exp, level)
	else
		return level
	end
end

OR

You can try arithmetics instead. Utilize the % operator.

A script like that wouldn’t be laggy if you gained 1,000,000 exp? Wouldn’t the function run a load of times if you gain a really big amount of exp causing a lag spike?

1 Like

Not really, because the inputting level. The new level set after the function used replaces the old level, and then you can use the function again using the new level into the arguments.

However, there might be an issue if you have suddenly gained a beefy amount of experience somehow. There is a reason why I added a second option, where you do pure arithmetics only to calculate level from experience by immediately getting the level without having to going through the recursion.

1 Like

Spent the last little while trying to create an example and it turned out to be a precision error. Anyway, if you wanted to use an arithmetic series for this you could use something like the following. I tried to show the process the best I could but it is still quite confusing.

--[[
	I'm no expert, this is just what I've learned when I needed something like this. May be a bit hard to understand at first. a is the series, d is the common difference.
	n/2 [a1*2 + d/2n - d/2]
	n/2 [200 + 50n - 50]
	100n + 25 n^2 - 25n
	25n^2 + (100n - 25n)
	25n^2 + 75n
	
	That is how you'd create the a and b below.
	a = 25
	b = 75
	
	Proof
	n is the term (in this case 3)
	d is the sum you should get.
	an^2 + bn + d
	25*(3^2)+(75*3)-450 = 0
--]]

-- The start variable represents the first term of the arithmetic series. The increment represents the common difference. So the series would be 100, 150, 200, ...
-- The sum of the series would be in order 100, 250, 450, ...
local start = 100;
local increment = 50;

-- Refer to comment at top.
local a = 25;
local b = 75;

function getSum(terms)
  return terms / 2 * (2 * start + (terms - 1) * increment);
end

function getPossibleTerms(sum)
  return math.floor((-b + math.sqrt(b^2 + 4 * a * sum)) / (2 * a));
end

-- What term you can get with 450 as the sum. Prints 3.
print(getPossibleTerms(450));

-- How much exp you need for the third level. Prints 450.
print(getSum(3));
9 Likes

Level and EXP can be scripted any number of ways, depends on the formula you want to apply. Point is that you’re performing an equation on an arbitrary number to get some sort of value needed to up your level. For example, unless they’ve changed it, I recall that the Phantom Forces level formula is ((level+1)*1000).

The point of the topic is figuring out how to get that maximum EXP required per level value though. This piece of code wouldn’t do anything useful because you’re just setting the EXP value to the maximum value minus the current. That would look weird when EXP is being changed as well.

To calculate the amount of EXP needed for another level, yes, you would subtract the current EXP from the max EXP for the next level but you wouldn’t set the current EXP value to this evaluation. The EXP value itself is arbitrary and increments whenever actions are completed, so it’s about finding a formula where if the EXP meets or exceeds a certain number, level will be incremented.