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:
- Basic enemies: Behaviour trees with 3–5 states each. Keep it tight.
- Named characters: Utility-based AI with hand-tuned scoring for personality.
- Ambient NPCs: Simple schedules with random variation for town life.
- 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.