Money Earned / Spent
Structured approach to money earned / spent that balances depth with accessibility, creating satisfying player experiences.
Overview
Money Earned / Spent represents a design pattern that defines how players interact with this aspect of the game world. Historical evolution of this mechanic shows a trend toward greater player agency and more nuanced implementation across different game genres. The ongoing evolution of this mechanic reflects the broader maturation of game design as a discipline.
Game Examples
Action RPGs
Action RPGs use this mechanic where players allocate limited resources to collect all available items. Multiple valid strategies exist for different playstyles, resulting in creative expression.
Real-Time Strategy Games
Real-Time Strategy Games use this mechanic where players track multiple variables to unlock new abilities and options. Each decision has cascading consequences, resulting in satisfying progression.
Pros & Cons
Advantages
- Enables strategic player expression
- Creates meaningful mechanical decisions for players
- Scales well from beginner to advanced play
- Integrates naturally with economy systems
Disadvantages
- May conflict with movement systems in the game
- Increases CPU requirements significantly
- Can create frustrating when RNG is unfavorable
- Requires significant development time to implement well
- Requires significant balance data to implement well
Implementation Patterns
Settings Controller
A modular approach to money earned / spent that separates concerns and enables easy testing.
class MoneyEarnedSpentHandler {
gameState: Map<string, any> = new Map();
save(slot: number) {
const data = {
timestamp: Date.now(),
version: "2.1.0",
state: Object.fromEntries(this.gameState)
};
localStorage.setItem(`save_${slot}`, JSON.stringify(data));
}
load(slot: number) {
const raw = localStorage.getItem(`save_${slot}`);
if (!raw) return false;
const data = JSON.parse(raw);
if (data.version !== "2.1.0") {
return this.migrate(data);
}
this.gameState = new Map(Object.entries(data.state));
return true;
}
}Difficulty Adjuster
A modular approach to money earned / spent that separates concerns and enables easy testing.
class MoneyEarnedSpentManager {
saveData: Map<string, any> = new Map();
save(slot: number) {
const data = {
timestamp: Date.now(),
version: "2.1.0",
state: Object.fromEntries(this.saveData)
};
localStorage.setItem(`save_${slot}`, JSON.stringify(data));
}
load(slot: number) {
const raw = localStorage.getItem(`save_${slot}`);
if (!raw) return false;
const data = JSON.parse(raw);
if (data.version !== "2.1.0") {
return this.migrate(data);
}
this.saveData = new Map(Object.entries(data.state));
return true;
}
}Config Parser
Data-driven implementation that loads money earned / spent configuration from external definitions.
class MoneyEarnedSpentController {
saveData: Map<string, any> = new Map();
save(slot: number) {
const data = {
timestamp: Date.now(),
version: "1.5.3",
state: Object.fromEntries(this.saveData)
};
localStorage.setItem(`save_${slot}`, JSON.stringify(data));
}
load(slot: number) {
const raw = localStorage.getItem(`save_${slot}`);
if (!raw) return false;
const data = JSON.parse(raw);
if (data.version !== "1.5.3") {
return this.migrate(data);
}
this.saveData = new Map(Object.entries(data.state));
return true;
}
}