Defeating enemies or completing tasks accumulates points; reaching thresholds permanently increases player stats.
XP fills automatically; crossing the threshold levels up and bumps every stat (HP/ATK/DEF) at once — a fixed package, not a chosen one.
Leveling is a threshold function over an XP integer: accumulate, cross a curve, permanently bump stats. The combat layer just feeds the number.
XP is a running total. Kills and quests add to it; the only question each time is whether it crossed the next threshold.
var xp := 0
func add_xp(n):
xp += n
while xp >= xp_for(level + 1): level_up()A StatBlock resource holds HP/ATK/DEF. Leveling mutates it; storing stats as a resource makes them easy to save and display.
class_name StatBlock extends Resource
@export var max_hp: int
@export var atk: int
@export var def: intEmit leveled_up so the UI flashes the gains and dependent systems (new spells, unlocked gear) react to the threshold crossing.
signal leveled_up(new_level)
func level_up():
level += 1; stats.atk += 2; leveled_up.emit(level)In short: xp int in GameState; on xp_changed signal: check threshold; emit stat_increased(stat_name, amount)
52 catalogued game(s) use this mechanic, spanning 1981–2000.
▶ Explore Level Up Stats interactively — see every game + the Godot system