NPC behaviour is one of those parts of game development where the gap between “adequate” and “compelling” is huge, and the engineering effort does not scale neatly with what the player notices. A well-tuned patrol path with a few contextual reactions can feel more alive than a complex neural network that is technically impressive but behaviourally erratic.

In our work with 2D games at Relish Games, we’ve tried several approaches to NPC AI. This article sets out what tends to work in practice, and where the usual traps are when you want 2D characters to feel dynamic without turning the project into a maintenance problem.

Why NPC AI carries more weight in 2D

There’s a slightly counterintuitive truth about NPC behaviour in 2D games: because the visual presentation is simpler, the behaviour has to do more of the heavy lifting. In a 3D game, detailed facial animation, motion-captured gestures and environmental interaction can create a sense of life even when the AI itself is fairly 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.

Behaviour trees, without the theatre

Behaviour trees remain the workhorse of game AI for a reason. They are modular, debuggable and easy to reason about once the structure is in place.

A basic structure for a 2D NPC

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 main advantage is simple: each node is a self-contained piece of logic that can be tested, tuned and reused on its own.

Making the output feel less robotic

Raw behaviour trees tend to produce clean but stiff results. The trick is to layer variation on top of the deterministic structure. Timing variation matters first. Do not fire actions on exact frames; add small random delays so the NPC does not feel metronomic.

Transition smoothness matters too. When an NPC switches from idle to sprinting, there should be a brief transitional state. A character does not instantly go from “idle” to “sprinting”. They startle, orient, then accelerate.

Memory persistence makes a big difference as well. NPCs that remember where they last saw the player, even after line of sight is lost, feel much sharper. Partial awareness helps in the same way. Instead of binary “detected/not detected”, use awareness levels that build over time.

Utility-based AI for characters with a bit more judgement

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

The idea is straightforward. Instead of hard-coded priority, every possible action gets scored against the current context, and the NPC picks 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

That produces surprisingly believable daily routines without scripting every NPC schedule by hand. NPCs drift towards contextually appropriate behaviour on their own, which is usually what you want.

Where the tuning work sits

The difficult part is the scoring curves. Push too hard and NPCs flip between behaviours erratically. Make them too conservative and they become predictable. Visualising the utility scores in real time during development is essential. It turns an opaque system into something you can actually debug.

Steering and navigation in 2D

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

Pathfinding options that hold up

For tile-based 2D games, A* pathfinding is still the cleanest option and is well documented. For free-movement 2D games, navigation mesh approaches adapted from 3D can work, provided you simplify them sensibly.

Three details matter here. Path smoothing cuts out the grid artefacts that raw A* leaves behind, so you should post-process paths to remove unnecessary waypoints and add gentler curves. Dynamic obstacles such as doors, moving platforms and other NPCs need to be fed back into path updates. Crowd behaviour also needs basic avoidance, or NPCs will cluster and overlap in ways that look broken at a glance.

Steering behaviours still earn their keep

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

  • Seek/Flee: Move towards or away from a target.
  • Wander: Produce natural-looking random movement.
  • Separation: Keep distance from other NPCs.
  • Cohesion/Alignment: Support group movement for squads or flocks.

Combined with pathfinding, these give NPCs the ability to navigate intelligently while still moving in a way that looks natural. The HGE engine’s vector math utilities make those steering calculations straightforward in C++.

Perception systems that do more than spot the player

How NPCs perceive the game world is crucial, and it is often oversimplified. A cone-of-vision check is better than a radius check, but real perception has more moving parts than that.

Sight

Sight usually comes down to four things: field of view angle, maximum range, obstruction by walls and objects, and movement. For humanoids, a 90-120 degree field of view is typical. Range can be affected by lighting conditions, and moving targets are easier to detect.

Sound

Sound propagation through the environment matters just as much. Different sounds should have different detection ranges. Walls can attenuate sound, though they do not always block it completely. Running is louder than walking. That should be obvious, but plenty of AI systems still pretend otherwise.

Memory

Memory is where a lot of NPC systems become more convincing. NPCs can remember where threats were last seen, note patrol anomalies such as a door that was closed and is now open, and track player behaviour patterns over time.

Practical implementation notes

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 actually notice it.

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. That 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 did not anticipate - state-based NPCs adapt while scripted NPCs break.

Profile early

NPC AI gets expensive once dozens of characters are updating every frame. Profile the update cost early. Stagger updates so not every NPC re-evaluates on the same frame, and reduce perception checks for off-screen NPCs if you want performance to stay manageable.

What this usually looks like in a real project

For a typical 2D game with NPCs, the breakdown is usually something like this:

  1. Basic enemies: Behaviour trees with 3-5 states each. Keep them 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 point is not to build the most sophisticated AI system possible. It is to build NPC behaviour that makes the 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.