Player spends accumulated resources or currency on permanent stat or ability improvements chosen from a menu.
Accumulated gold is spent from a menu on permanent upgrades across several tracks — the player chooses what to buy, and each tier costs more.
Permanent upgrades are a data tree: each node states its cost and prerequisites, and buying it flips a flag and modifies a stat. Menus read the tree.
An UpgradeData resource per node: cost, the stat it changes, and the upgrades it requires first. Designers tune the tree without touching code.
class_name UpgradeData extends Resource
@export var cost: int
@export var stat: String
@export var amount: float
@export var requires: Array[String]The full upgrade list. A node is buyable only when its prerequisites are owned and you can afford it — a filtered view over the array.
func buyable(u) -> bool:
return gold >= u.cost and u.requires.all(func(r): return owned.has(r))Owned-upgrade flags plus the resulting stat block. Buying mutates the player's stats permanently — distinct from a consumable.
var owned := {}
func apply(u):
gold -= u.cost; owned[u.resource_path] = true
stats[u.stat] += u.amountIn short: Upgrade tree as Array of UpgradeData Resources; each checks prerequisite flags and cost; modifies player stat Resource
26 catalogued game(s) use this mechanic, spanning 1986–1999.
▶ Explore Upgrade Purchasing interactively — see every game + the Godot system