Ending Grades / Tiers
Implementation of ending grades / tiers that defines how players interact with this aspect of the game, including feedback and progression.
Overview
This mechanic, commonly known as ending grades / tiers, provides meaningful choices and consequences for player actions. The implementation varies significantly across genres, with each game adapting the core concept to fit its specific design goals and target audience. Understanding the design principles behind this mechanic helps developers create more engaging and balanced game experiences.
Game Examples
Sandbox Games
Sandbox Games use this mechanic where players solve environmental puzzles to maximize their effectiveness. The mechanic respects player time and investment, resulting in strategic variety.
Flight Simulators
Flight Simulators use this mechanic where players explore the environment to express their creativity. The learning curve is steep but rewarding, resulting in satisfying progression.
Pros & Cons
Advantages
- Scales well from beginner to advanced play
- Provides long-term engagement for dedicated players
- Creates natural tension between players
- Creates satisfying contextual loops
- Provides long-term progression targets for dedicated players
Disadvantages
- May create a knowledge wall for new players
- Can feel unfair if progression is too slow
- Requires extensive balance testing to avoid edge cases
- Difficult to balance across a wide range of skill levels
Implementation Patterns
Choice Evaluator
Optimized pattern for ending grades / tiers that minimizes per-frame computation cost.
class EndingGradesTiersSystem {
currentNode: string = "greeting";
flags: Set<string> = new Set();
getDialogue() {
const node = DIALOGUE_TREE[this.currentNode];
return {
text: node.text,
choices: node.choices.filter(c =>
!c.requires || c.requires.every(f => this.flags.has(f))
)
};
}
choose(choiceIndex: number) {
const node = DIALOGUE_TREE[this.currentNode];
const choice = node.choices[choiceIndex];
if (choice.setsFlag) this.flags.add(choice.setsFlag);
this.currentNode = choice.next;
return this.getDialogue();
}
}