Browse/Crafting & Building/Sewer / Drainage
Crafting & Building

Sewer / Drainage

Implementation of sewer / drainage that defines how players interact with this aspect of the game, including feedback and progression.

Low complexity
3 examples
2 patterns

Overview

The sewer / drainage mechanic provides a framework that establishes rules governing player behavior and system responses. 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

Simulation Games

Simulation Games use this mechanic where players weigh competing priorities to support their team effectively. The system rewards both skill and knowledge, resulting in memorable moments.

Fighting Games

Fighting Games use this mechanic where players optimize their build to tell their own story. The system encourages experimentation, resulting in satisfying progression.

Turn-Based Strategy Games

Turn-Based Strategy Games use this mechanic where players customize their experience to progress through the content. The difficulty scales with player performance, resulting in personal achievement.

Pros & Cons

Advantages

  • Enhances temporal without disrupting core gameplay
  • Rewards both pattern recognition and mechanical skill
  • Reduces tedium while maintaining challenge
  • Provides long-term progression targets for dedicated players

Disadvantages

  • May overwhelm competitive players with too many options
  • Risk of power creep in competitive environments
  • Can create confusing when RNG is unfavorable
  • Increases CPU requirements significantly
  • Requires significant balance data to implement well

Implementation Patterns

Crafting Queue

Event-driven pattern that reacts to sewer / drainage changes and updates dependent systems.

class SewerDrainageProcessor {
  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.2);
    return { ...recipe.output, quality };
  }

  rollQuality(baseChance: number) {
    const roll = Math.random();
    if (roll < baseChance * 0.05) return "legendary";
    if (roll < baseChance * 0.2) return "rare";
    if (roll < baseChance) return "uncommon";
    return "common";
  }
}

Quality Calculator

Data-driven implementation that loads sewer / drainage configuration from external definitions.

class SewerDrainageController {
  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.05) return "legendary";
    if (roll < baseChance * 0.2) return "rare";
    if (roll < baseChance) return "uncommon";
    return "common";
  }
}