Hello there! It would seem there is a need for a guide about leveling systems, based almost purely on the number of questions received. I’m going to dump a bunch of theory here on the math and ideas behind leveling systems.
In this part I will explain:
- The theory behind basic leveling systems
- The theory behind experience functions
- The theory behind add experience functions
- Basic level bar scaling
In the next part I will explain:
- Modifier systems and their implementations
- Advanced experience functions
- Sanity checks
- Choices, Choices, finding good constants
Small disclaimer, this is by no means a definitive guide, the language I use is based on my own experience with crafting such features.
The Therory Behind Basic Leveling Systems
A basic leveling system has a couple parts but can essentially be broken into this:
-
A function which dictates the amount of experience to the next level
-
A function which adds some experience
-
A way to sanity check the amount of experience being set
Basic Experience Functions
Mathematically a basic experience function is an increasing function that scales with level, simply that is:
Level * ExperienceScale
This however, does create a couple problems, for instance, level 0 needs 0 experience to get to level 1. To get around this the most basic experience function that is super usable has one addition, a second constant (besides ExperienceScale).
constant + Level * ExperienceScale
This is a rather nice approach to a rather simple problem, and it is what we will be using for the rest of this guide, in code I would have it look a little like this:
local Level = 0
local constant, ExperienceScale = 100,10
local EF = (function(level) return constant + (level*ExperienceScale) end)
It doesn’t actually matter that the function looks exactly like this, for example you could make it exponential if you hate your players.
You may also be asking, why I dedicated a function to the experience instead of a single calculation later on, this has to due with reusability in multiple functions (including the experience bar scaling) and further the ability to override the function in part 2 with more advanced experience functions where this would be our default. (Say if we were implementing this as a library for multiple games.)
And the constants are up to you, I think the values of 100 and 10 are decent but this would also depend on how much experience you give your players later on.
Add Experience Functions
Simply defined, this is the function that adds experience, and increments your level as a result.
The algorithm is rather simple, and should look something like this:
-
Take in an amount of experience
-
Check if the incoming experience overflows the level, if so increment the level add the overflow
-
Otherwise, just add the experience
A simple implementation might look like this:
local function AddExp(amount)
if (currentExperience+amount) > EF(Level) then
--Step 0: Since we overflowed calculate the exp leftover
local LeftOverExp = (currentExperience+amount)-EF(Level)
--Step 1: increment the level
Level = Level + 1
--Step 2: Since we overflowed, set the exp to 0 and recurse
currentExperience = 0
AddExp(LeftOverExp)
elseif (currentExperience+amount) == EF(Level) then
--Step 1: increment the level
Level = Level + 1
--Step 2: reset experience
currentExperience = 0
else
currentExperience = currentExperience + amount
end
end
This is a simple algorithm, although it includes no sanity checks, which I will introduce in Part 2, should you stay tuned for that.
Basic Level Bar Scaling
Because your level bar may be horizontal or vertical, I’m not actually going to explain which dimension to scale your bar, I’m also not going to explain a full GUI implementation incase you wish to implement this on other platforms. Instead, I am going to assume you either know the maximum width, or height of your level bar.
With that said, the math for this is simple and yet all too often I see it overcomplicated.
We have a few variables from earlier which we can use, specifically currentExperience and EF(Level) (or our total experience for this level.) This can be used to create a simple ratio to be multiplied by our bar height or width. The calculation would look like such:
(currentExperience/EF(Level)) * HeightOrWidth
That, would be the size that your bar should be in the current moment. I’ll leave the animation implementation to you, whether it be instant or tween in some manner.
I’ve left some things out for simplicity, however if there is significant interest I can cover those topics in part 2 or (if I do a part 3).
At the end of this I will also open source my own module for leveling systems.
Should this be a repeat post, or somewhat inadequate please let me know so I may update it.
Good luck, Vathriel
EDIT: Part 2 is out here