Linear Progression
Game design pattern for linear progression that creates meaningful player choices and engaging feedback loops.
Overview
This mechanic, commonly known as linear progression, provides meaningful choices and consequences for player actions. The mechanic interacts with multiple other game systems, creating emergent gameplay that extends beyond its individual components. Modern implementations often combine this mechanic with procedural elements to increase variety and replayability.
Game Examples
Card Games
Card Games use this mechanic where players time their actions precisely to establish dominance in PvP. The mechanic respects player time and investment, resulting in exploration incentives.
Boxing Games
Boxing Games use this mechanic where players decode hidden patterns to maximize their effectiveness. The system tracks multiple variables simultaneously, resulting in meaningful player agency.
Management Games
Management Games use this mechanic where players optimize their build to build a competitive advantage. Each decision has cascading consequences, resulting in risk-reward tension.
Pros & Cons
Advantages
- Creates natural competition between players
- Encourages supportive playstyles and experimentation
- Reduces tedium while maintaining challenge
- Scales well from beginner to advanced play
Disadvantages
- Creates potential for cheese strategies by experienced players
- Can lead to disengagement if overused
- Creates potential for exploits by experienced players
- Can create balance issues if not carefully balanced
- May overwhelm new players with too many options
Implementation Patterns
Stat Growth Formula
A modular approach to linear progression that separates concerns and enables easy testing.
const talentTree = {
nodes: [
{ id: "basic_strike", cost: 2, requires: [], effect: "+10% damage" },
{ id: "improved_skill", cost: 5, requires: ["basic_strike"], effect: "+25% damage, unlock combo" },
{ id: "expert", cost: 5, requires: ["improved_skill"], effect: "+50% damage, unlock ultimate" },
],
canUnlock(nodeId: string, points: number, unlocked: Set<string>) {
const node = this.nodes.find(n => n.id === nodeId);
if (!node || unlocked.has(nodeId)) return false;
return points >= node.cost
&& node.requires.every(r => unlocked.has(r));
}
};Prestige System
Data-driven implementation that loads linear progression configuration from external definitions.
const abilityTree = {
nodes: [
{ id: "novice_skill", cost: 3, requires: [], effect: "+10% damage" },
{ id: "journeyman", cost: 2, requires: ["novice_skill"], effect: "+25% damage, unlock combo" },
{ id: "mastery", cost: 3, requires: ["journeyman"], effect: "+50% damage, unlock ultimate" },
],
canUnlock(nodeId: string, points: number, unlocked: Set<string>) {
const node = this.nodes.find(n => n.id === nodeId);
if (!node || unlocked.has(nodeId)) return false;
return points >= node.cost
&& node.requires.every(r => unlocked.has(r));
}
};