How to think about Level's by ignoring them in your Game
This guide is designed to introduce a concept in how a game maker can think about levels in their game, by simply ignoring them all together (at least internally). Now leveling systems in games can be simple or complex, and this is only one method that I have found successful in my games (and is used in the Adoptables system here on the Forums), for the following reasons:
- It is simple to use and easy to store.
- It doesn't care about what stage the character or pet is in at any point.
- It is forward thinking and easily adaptable.
- It is level agnostic (no level cap).
It works by not caring when you reach a level, and by keeping a value that is incremented (we call it Power here on the forums, but you can call it whatever). This is an always incrementing number, and it doesn't reset when a threshold is met. Based on this number we can then create thresholds that signify importance to us (i.e. Levels). This reduces code, data storage, and the complexity of the code. As opposed to caring when we hit a level, we only care about changing something outside of it when a threshold is met.
What does my data structure look like?
If you were to look at this in terms of a database, you would have two tables (yes, only two!) that could manage your entire pet level / evolution system. This makes life much easier to manage things.
character
- id
- ... (name, description, gender, whatever)
- stage_id
- power
- id
- min_power
- parent
How does this work in practical use?
You would use this very simply by simply adding to the character's power column any amount of experience you wish to give them, then checking that amount against min_power in stages. Here are two snippets in PHP that show how this works in action, note that I use the parent column here to keep my stages within the concept of evolved trees (so I can branch evolutions into different areas if I choose to):
<?php
class Character {
private $_db;
/**
* Constructor
*
* @param [PDO] $_database This is the database PDO object to query the database with.
*/
function __construct($_database = NULL) {
$this->_db = $_database;
}
/**
* Returns the character data.
*
* @param [int] $id
* @return object
*/
function get($id) {
return $this->_db->prepare('SELECT * FROM characters WHERE id = ?')
->execute([$character_id])
->fetch(PDO::FETCH_OBJ);
}
/**
* Returns a stage row from stages.
*
* @param [int] $id
* @return object
*/
function get_stage($id) {
return $this->_db->prepare('SELECT * FROM stages WHERE id = ?')
->execute([$id])
->fetch(PDO::FETCH_OBJ);
}
/**
* Returns a boolean value indicating whether or not a theshold to level up can be achieved.
*
* @param [int] $character_id
* @return boolean
*/
function can_evolve($character_id) {
$character = $this->get($character_id);
$stage = $this->get_stage($character->stage_id);
// This will return a result if we have successfully hit a threshold, or FALSE if we have not based on information in the stages table.
$next_stage_power = $this->_db->prepare('SELECT min_power FROM stages WHERE id != ? AND parent = ? AND min_power >= ? AND min_power <= ? ORDER BY min_power ASC')
->execute([$stage->id, $stage->parent, $stage->min_power, $character->power])
->fetch(PDO::FETCH_OBJ);
// Have we hit a threshold in the stages table yet to evolve or level up?
if($next_stage_power !== FALSE) {
if($character->power >= $next_stage_power->min_power) {
return TRUE;
}
else {
return FALSE;
}
}
else {
return FALSE;
}
}
/**
* Returns the next stage(s) once leveling is available.
*
* @param [int] $character_id
* @return [array] object
*/
function get_next_stages($character_id) {
$character = $this->get($character_id);
$stage = $this->get_stage($character->stage_id);
$next_stage_power = $this->_db->prepare('SELECT min_power FROM stages WHERE id != ? AND parent = ? AND min_power > ? ORDER BY min_power ASC')
->execute([$stage->id, $stage->parent, $stage->min_power])
->fetch(PDO::FETCH_OBJ);
// This gets the next stage available to evolve, but only if it is available. If more then one stage is available, more then one row is returned.
return $this->_db->prepare('SELECT * FROM stages WHERE id != ? AND parent = ? AND min_power = ?')
->execute([$this->_data['pet_stage_id'], $current_stage->parent, $next_stage_power])
->fetchAll(PDO::FETCH_OBJ);
}
}
Note: This code is for reference only, I re-wrote it from a different form then it is for this forum (this forum uses a custom database wrapper), so it is for reference use only. It is to give you an idea of how this can be implemented.
In short:
In the above case, when it comes to updating a character's stage or level, I would check if they could by calling can_evolve($id), if TRUE, I could get the available stages, then set my characters stage_id column to whatever was available that I wanted to. I don't need to manage power at all during the leveling process.
In conclusion:
This is one of many ways to deal with leveling up something in a game, I find this the easiest way since it is a very simple mechanism that is forward thinking, and easy to implement from a sense of database and code, and flexible enough that what happens when a level threshold event happens - I don't have to worry about what it means in terms of experience - I just have to change what is needed to level up.
As always, I would love some feedback, this is kinda the first guide I have written in forever, and is probably quite dry unless you are familiar with some coding concepts.
View full guide