NPC behaviour is one of those aspects of game development where the gap between “adequate” and “compelling” is enormous, and the engineering effort doesn’t scale linearly with the player’s perception of quality. A well-tuned patrol path with a few contextual reactions can feel more alive than a complex neural network that’s technically impressive but behaviourally erratic.

In our work with 2D games at Relish Games, we’ve experimented with several approaches to NPC AI. This article shares what we’ve learned about making 2D game characters feel dynamic without drowning in complexity.

Why NPC AI Matters More in 2D

There’s a counterintuitive truth about NPC behaviour in 2D games: because the visual presentation is simpler, the behaviour has to carry more weight. In a 3D game, detailed facial animations, motion-captured gestures, and environmental interactions create a sense of life even when the underlying AI is basic. In a 2D game, the behaviour IS the character.

A sprite that walks back and forth feels like a sprite walking back and forth. A sprite that pauses to look at something interesting, adjusts its path to avoid the player, and occasionally sits down to rest feels like a person.

The Behaviour Tree Approach

Behaviour trees remain the workhorse of game AI, and for good reason. They’re modular, debuggable, and intuitive to design once you understand the core concepts.

Basic Structure

A behaviour tree for a 2D NPC might look like this:

Root (Selector)
├── Combat (Sequence)
│   ├── Is Enemy Visible?
│   ├── Is Within Attack Range?
│   └── Attack
├── Alert (Sequence)
│   ├── Heard Noise?
│   ├── Move To Noise Source
│   └── Search Area
└── Idle (Sequence)
    ├── Patrol Route
    └── Random Idle Animation

The key advantage: each node is a self-contained piece of logic that you can test, tune, and reuse independently.

Making It Feel Natural

Raw behaviour trees produce robotic results. The secret to natural-feeling NPC behaviour is layering variation on top of the deterministic structure:

  • Timing variation: Don’t execute actions on exact frames. Add small random delays that prevent the metronomic feel of perfectly timed AI
  • Transition smoothness: When an NPC switches between behaviours, add brief transitional states — a character doesn’t instantly go from “idle” to “sprinting,” they startle, orient, then accelerate
  • Memory persistence: NPCs that remember where they last saw the player, even after losing line of sight, feel dramatically smarter
  • Partial awareness: Instead of binary “detected/not detected,” use awareness levels that build over time

Utility-Based AI

For NPCs with more complex decision-making — shopkeepers, allies, faction members — utility-based AI offers more nuanced behaviour.

The concept: instead of hard-coded priority, every possible action gets scored based on the current context. The NPC chooses the highest-scoring action.

Example: Town NPC

Actions and their utility scores:
- Go to work:     high in morning, low at night
- Eat at tavern:  increases with hunger, peaks at noon
- Sleep:          increases with fatigue, peaks at night  
- Chat with NPC:  moderate if nearby NPC, low if alone
- Flee danger:    zero normally, maximum if threat detected

This produces surprisingly believable daily routines without scripting each NPC’s schedule. NPCs naturally gravitate toward contextually appropriate behaviours.

The Scoring Challenge

The hard part is tuning the scoring curves. Too aggressive and NPCs flip between behaviours erratically. Too conservative and they become predictable. We’ve found that visualising the utility scores in real-time during development is essential — it turns an opaque system into something you can debug intuitively.

Steering and Navigation in 2D

Movement is where NPC AI often breaks down in 2D games. Characters that walk through each other, get stuck on corners, or take absurd paths destroy the illusion instantly.

Pathfinding Options

For tile-based 2D games, A* pathfinding is straightforward and well-documented. For free-movement 2D games, navigation mesh approaches adapted from 3D can work well with some simplification.

Key considerations:

  • Path smoothing: Raw A* paths have visible grid artifacts. Post-process paths to remove unnecessary waypoints and add gentle curves
  • Dynamic obstacles: Doors, moving platforms, and other NPCs need to be factored into path updates
  • Crowd behaviour: When multiple NPCs share space, they need basic avoidance to prevent clustering and overlap

Steering Behaviours

Craig Reynolds’ classic steering behaviours work beautifully in 2D:

  • Seek/Flee: Move toward or away from a target
  • Wander: Natural-looking random movement
  • Separation: Keep distance from other NPCs
  • Cohesion/Alignment: Group movement for squads or flocks

Combining these with pathfinding gives NPCs that navigate intelligently while moving naturally. The HGE engine’s vector math utilities make implementing these steering calculations straightforward in C++.

Perception Systems

How NPCs perceive the game world is crucial and often oversimplified. A cone-of-vision check is better than a radius check, but real perception involves more:

Sight

  • Field of view angle (typically 90–120 degrees for humanoids)
  • Maximum range (affected by lighting conditions)
  • Obstruction by walls and objects
  • Movement makes targets easier to detect

Sound

  • Sound propagation through the environment
  • Different sounds have different detection ranges
  • Walls attenuate sound (but don’t always block it)
  • Running is louder than walking

Memory

  • Where threats were last seen
  • Patrol anomalies (a door that was closed is now open)
  • Player behaviour patterns over time

Practical Implementation Tips

Start Simple

Begin with the simplest possible AI that produces acceptable behaviour. A patrol path with “chase if spotted” covers 80% of guard NPC needs. Add complexity only where the player will notice.

Debug Visually

In 2D games, overlay the AI’s decision state directly on screen during development. Show perception cones, current behaviour state, utility scores, and pathfinding routes. This is worth more than any amount of console logging.

Think in States, Not Scripts

NPCs that run through scripted sequences are brittle. NPCs that evaluate their current state and choose appropriate behaviours are resilient. When something unexpected happens — the player does something you didn’t anticipate — state-based NPCs adapt while scripted NPCs break.

Profile Early

NPC AI can become expensive when you have dozens of characters updating every frame. Profile your AI update costs early. Techniques like staggering updates (not every NPC needs to re-evaluate every frame) and reducing perception checks for off-screen NPCs keep performance manageable.

What We’d Do in Practice

For a typical 2D game with NPCs:

  1. Basic enemies: Behaviour trees with 3–5 states each. Keep it tight.
  2. Named characters: Utility-based AI with hand-tuned scoring for personality.
  3. Ambient NPCs: Simple schedules with random variation for town life.
  4. Bosses: Custom scripted phases with reactive transitions.

The goal isn’t to build the most sophisticated AI system possible. It’s to build NPC behaviour that makes your specific game world feel alive and responsive.

Explore the HGE engine demos to see 2D game systems in action, or visit our forum to discuss NPC design approaches with other developers.