Back to Essays

Teaching AI to Be Bad at Games

July 10, 20256 min read

The hardest challenge in game AI isn't making it smart—it's making it lose convincingly. Here's the art and science of artificial incompetence.

In 1997, Deep Blue beat Kasparov at chess. In 2016, AlphaGo crushed Lee Sedol. In 2019, OpenAI Five destroyed professional Dota 2 teams.

Making AI that can win is solved. The real challenge? Making AI that knows how to lose.

And not just lose—lose in a way that makes players feel like they earned their victory.

The Paradox of Artificial Incompetence

Teaching AI to be bad is exponentially harder than teaching it to be good. It's easy to calculate the optimal move. It's hard to calculate the "almost optimal but believably flawed" move that creates tension without frustration.

// Easy: Make perfect AI
function getPerfectMove(gameState) {
  return minimax(gameState, Infinity);
}
 
// Hard: Make fun AI
function getFunMove(gameState, player) {
  const perfectMove = getPerfectMove(gameState);
  const playerSkill = analyzePlayer(player);
  const gameFlow = analyzeMatchTension(gameState);
  const recentHistory = getRecentMoves();
  
  return createBelievableError(
    perfectMove,
    playerSkill,
    gameFlow,
    recentHistory
  );
}

The Taxonomy of Artificial Failure

1. The Overconfidence Blunder

AI gets cocky when winning and makes risky plays:

if (this.scoreAdvantage > 30) {
  this.riskTolerance *= 1.5;
  this.showboating = true;
  // "I'll try this fancy move instead of the safe one"
}

2. The Tunnel Vision Mistake

AI becomes fixated on one strategy and misses obvious counters:

class TunnelVisionAI {
  constructor() {
    this.favoriteStrategy = this.pickRandomStrategy();
    this.stubbornness = Math.random() * 0.5 + 0.5;
  }
  
  chooseMove() {
    if (Math.random() < this.stubbornness) {
      return this.favoriteStrategy.getMove();
    }
    return this.adaptiveStrategy.getMove();
  }
}

3. The Panic Response

AI makes worse decisions under pressure:

calculateAccuracy() {
  const basePanicLevel = this.health < 20 ? 0.3 : 0;
  const timePressure = this.timeRemaining < 10 ? 0.2 : 0;
  const comboBreaker = this.inCombo ? 0.4 : 0;
  
  const totalPanic = Math.min(basePanicLevel + timePressure + comboBreaker, 0.8);
  return this.baseAccuracy * (1 - totalPanic);
}

4. The Pattern Player

AI develops exploitable habits:

class PatternAI {
  constructor() {
    this.patterns = [
      ["attack", "attack", "defend"],
      ["dodge", "counter", "retreat"],
      ["charge", "special", "recover"]
    ];
    this.currentPattern = 0;
  }
  
  getMove() {
    // Sometimes break pattern, but not too often
    if (Math.random() < 0.8) {
      return this.patterns[this.currentPattern][this.moveIndex++ % 3];
    }
    return this.randomMove();
  }
}

The Mario Kart Principle

Mario Kart's AI is a masterclass in losing with style:

  • Rubber band AI keeps races close
  • Items become more powerful for losing players
  • AI makes "mistakes" near the finish line
  • First place AI gets "nervous" when players are close

Nobody complains because it FEELS fair, even though it's completely rigged.

Dynamic Difficulty: The Invisible Hand

The best AI adjusts without the player noticing:

class DynamicDifficultyAI {
  constructor() {
    this.targetWinRate = 0.4; // Player should win 60% of the time
    this.adjustmentRate = 0.05;
    this.skill = 0.5;
  }
  
  afterMatch(playerWon) {
    if (playerWon) {
      this.skill += this.adjustmentRate;
    } else {
      this.skill -= this.adjustmentRate * 2; // Lose skill faster
    }
    
    // Hide adjustments with personality
    this.personality = this.generatePersonality(this.skill);
  }
}

The Fighting Game Philosophy

Fighting games have perfected the art of beatable AI:

Input Reading vs. Reaction

// Bad: AI reads inputs instantly
onPlayerInput(input) {
  this.counter(input); // Unfair!
}
 
// Good: AI "sees" and "reacts"
onPlayerAnimation(animation) {
  setTimeout(() => {
    if (Math.random() < this.reactionSkill) {
      this.attemptCounter(animation);
    }
  }, this.reactionTime);
}

Commitment to Moves

AI should commit to decisions like humans do:

  • Can't cancel moves mid-animation
  • Has recovery frames
  • Makes reads that can be wrong

The Storytelling of Failure

Good AI losses tell a story:

The Comeback Narrative

if (playerHealthRatio < 0.3 && aiHealthRatio > 0.7) {
  // AI gets "overconfident"
  this.aggressiveness *= 1.5;
  this.defense *= 0.7;
  this.tauntFrequency *= 2;
  // Creates dramatic comeback opportunities
}

The Learning Opponent

class LearningAI {
  constructor() {
    this.playerTendencies = {};
    this.adaptationSpeed = 0.1; // Learns slowly for fairness
  }
  
  observePlayer(action, context) {
    // Learn patterns but imperfectly
    const fuzzyContext = this.addNoise(context);
    this.playerTendencies[fuzzyContext] = action;
  }
  
  predict() {
    // Sometimes "forgets" what it learned
    if (Math.random() < 0.3) return this.randomGuess();
    return this.playerTendencies[this.currentContext];
  }
}

Real-World Masters of Failure

Street Fighter II

The AI has specific weaknesses per character. Zangief can't handle jumping attacks. Blanka falls for cross-ups. These aren't bugs—they're designed vulnerabilities.

Dark Souls

Bosses telegraph attacks heavily. They have cooldown periods. They can be backstabbed. Every seemingly unfair boss is actually full of designed weaknesses.

XCOM

The game literally cheats in the player's favor on lower difficulties, missing shots that should hit to prevent frustration spirals.

Resident Evil 4

The AI has "director" logic that ensures zombies sometimes miss grabs or arrive slightly too late to surround you completely.

The Psychology of Satisfying Victory

Players need to feel they earned their wins through:

Skill Expression

// AI recognizes and "respects" good plays
onPlayerCombo(combo) {
  if (combo.difficulty > 8) {
    this.showRespect(); // "Nice move!"
    this.caution += 0.2; // Plays more carefully
  }
}

Meaningful Mistakes

AI errors should feel like the player forced them:

  • Baited into a trap
  • Overwhelmed by pressure
  • Outsmarted by strategy

Never random incompetence.

The Future: Empathetic AI

Imagine AI that understands fun at a deeper level:

class EmpathyAI {
  async analyzePlayerState() {
    return {
      frustration: this.detectFrustration(),
      boredom: this.detectBoredom(),
      flow: this.detectFlowState(),
      learning: this.detectLearningMoments()
    };
  }
  
  async adjustBehavior(playerState) {
    if (playerState.frustration > 0.7) {
      this.makeMistake("tactical");
      this.showOpening();
    } else if (playerState.boredom > 0.6) {
      this.tryRiskyStrategy();
      this.increaseAggression();
    } else if (playerState.flow > 0.8) {
      this.matchPlayerIntensity();
    }
  }
}

Best Practices for Bad AI

1. Telegraph Everything

Players should understand why they won:

  • Visual tells before attacks
  • Audio cues for state changes
  • Clear vulnerability windows

2. Lose with Personality

Different AI characters fail differently:

  • Aggressive AI overextends
  • Defensive AI gets predictable
  • Tricky AI outsmart themselves

3. Create Teaching Moments

onPlayerMistake(mistake) {
  if (this.shouldTeach()) {
    this.punishLightly(mistake); // Show the error
    this.giveSecondChance();     // But don't destroy them
  }
}

4. The Goldilocks Zone

  • Too easy: Boring
  • Too hard: Frustrating
  • Just right: One more game!

Call to Action

Next time you're designing AI difficulty:

  1. Start with perfect AI, then add flaws - It's easier to make smart AI dumb than dumb AI smart
  2. Give each difficulty a personality - Not just number tweaks
  3. Watch player faces - Frustration and flow look different
  4. Fail forward - Every AI loss should teach something
  5. Hide the math - Players should feel outsmarted, not outmathed

The goal isn't to make AI that loses. It's to make AI that loses in a way that makes players feel like winners.

Because in the end, games aren't about creating the smartest AI.

They're about creating the best memories.


The perfect game AI is like the perfect dance partner: skilled enough to make you look good, gracious enough to let you lead, and just clumsy enough to make you feel like the star.

Tags

AIDifficultyGame DesignPlayer Psychology