Legendary Crafting
Mechanic governing legendary crafting behavior, establishing rules for player interaction, feedback, and progression within this system.
Overview
This mechanic, commonly known as legendary crafting, establishes rules governing player behavior and system responses. Designers must carefully balance the system's depth against its learning curve, ensuring that new players can engage while experienced players find room for mastery. The ongoing evolution of this mechanic reflects the broader maturation of game design as a discipline.
Game Examples
Idle / Clicker Games
Idle / Clicker Games use this mechanic where players interact with NPCs to complete objectives efficiently. The mechanic creates natural tension and release cycles, resulting in a sense of mastery.
Stealth Games
Stealth Games use this mechanic where players master complex timing to min-max their character. Multiple valid strategies exist for different playstyles, resulting in risk-reward tension.
Pros & Cons
Advantages
- Provides clear audio feedback on player actions
- Enables mechanical player expression
- Creates satisfying contextual loops
- Supports diverse viable strategies and approaches
- Creates satisfying delayed loops
Disadvantages
- Difficult to balance across a wide range of skill levels
- Can create tedious when RNG is unfavorable
- Increases storage requirements significantly
- Can create repetitive when RNG is unfavorable
- Requires significant balance data to implement well
Implementation Patterns
Assembly Pipeline
Core implementation pattern for handling legendary crafting logic with clean state management.
class LegendaryCraftingController {
recipes: Recipe[] = [];
craft(recipeId: string, inventory: Inventory) {
const recipe = this.recipes.find(r => r.id === recipeId);
if (!recipe) return null;
for (const ingredient of recipe.ingredients) {
if (!inventory.has(ingredient.id, ingredient.amount)) {
return null; // Missing materials
}
}
for (const ingredient of recipe.ingredients) {
inventory.remove(ingredient.id, ingredient.amount);
}
const quality = this.rollQuality(0.05);
return { ...recipe.output, quality };
}
rollQuality(baseChance: number) {
const roll = Math.random();
if (roll < baseChance * 0.01) return "legendary";
if (roll < baseChance * 0.15) return "rare";
if (roll < baseChance) return "uncommon";
return "common";
}
}Material Resolver
Core implementation pattern for handling legendary crafting logic with clean state management.
class LegendaryCraftingManager {
recipes: Recipe[] = [];
craft(recipeId: string, inventory: Inventory) {
const recipe = this.recipes.find(r => r.id === recipeId);
if (!recipe) return null;
for (const ingredient of recipe.ingredients) {
if (!inventory.has(ingredient.id, ingredient.amount)) {
return null; // Missing materials
}
}
for (const ingredient of recipe.ingredients) {
inventory.remove(ingredient.id, ingredient.amount);
}
const quality = this.rollQuality(0.15);
return { ...recipe.output, quality };
}
rollQuality(baseChance: number) {
const roll = Math.random();
if (roll < baseChance * 0.01) return "legendary";
if (roll < baseChance * 0.1) return "rare";
if (roll < baseChance) return "uncommon";
return "common";
}
}