How to make a stealth game with AI
A caught player should already have known it was coming. That means the rules of sight are drawn on the screen, not hidden in the code.
Jump to a section
Stealth breaks down when detection is invisible. A guard spots the player through a wall, or from behind, and the only thing the player learns is that the game is unfair. So draw every vision cone, give being seen a duration the player can watch running out, and make the guard react somewhere the player can see it.
A player who gets caught should already have known it was coming. That needs three things. The rules of sight are on the screen. The moment of detection has a length. The guard reacts before anything resets. Hide any one of them and the level becomes trial and error.
Four steps to a guard worth sneaking past#
A wedge on the floor is the whole specification of what a guard can see. Draw it first and the maths follows from the picture.
If the bar is full before you have noticed it, the rise rate is too fast to play against.
It should head for where you were, not for where you are. This test catches the worst bug in the genre.
Walls, routes and a locked door are level design. Level design over unreadable guards is guesswork.
Build a top down stealth game as ONE self-contained .html file. No
frameworks and no image files.
LEVEL: a room of wall rectangles, a player, two guards and an exit.
Walls block both movement and sight.
VISION: each guard has a facing direction, a sight distance and a cone
half angle. It can see the player only if all three hold. The player is
within the distance. The angle between the guard's facing and the
direction to the player is under the half angle. A straight line between
the two crosses no wall.
DRAW THE CONE: fill every guard's cone each frame as a translucent
wedge, cut off where a wall blocks it, so the drawing agrees with the
check. Shift its colour from calm to alarmed as suspicion rises.
SUSPICION: each guard holds a value from 0 to 1. It climbs while the
player is visible and falls more slowly while not. Draw it as a small
bar above the guard. At 1 the guard is alerted. Nothing is instant.
GUARD STATES: PATROL, SUSPICIOUS, SEARCH, RETURN. Show the current one
as a mark above the guard's head. SUSPICIOUS stops and turns towards the
player. SEARCH walks to the last place the player was seen and looks
around. RETURN goes back to the nearest patrol point.
PATROL: each guard owns a list of points, each with a wait in seconds.
It walks to a point, waits there turning slowly, then takes the next one
and loops.
LAST KNOWN POSITION: store where the player was at the instant suspicion
filled. The guard walks there. It must never read the player's current
position while searching.
CAUGHT: the player returns to the start of the level, and only after the
guard has visibly reacted first.
MOTION: everything moves by the seconds elapsed since the last frame,
clamped to 0.05, so a tab left in the background cannot walk a guard
straight through a wall.
PHONE: a drag anywhere moves the player, and
canvas { touch-action: none; } in the CSS.
CONFIG: one object at the top with the sight distance, the cone half
angle, the suspicion rise and fall rates, the two walk speeds and the
patrol wait, each commented.
The cone and the suspicion bar are the two things people delete, because they look like debug drawing. They are the interface. Change the distances, the angle and the rates as much as you like. Keep the three part sight check together, because dropping the wall test is what makes a guard feel like a cheat.
The player must always know why they were seen#
Four conditions decide whether a guard can see the player, and they want testing cheapest first. Is the player within the sight distance? Is the player inside the cone, which is a comparison between the facing direction and the direction to the player? Is the line between them clear of walls? Has all of that held for long enough?
The wall test is the one that gets left out, and it is the one players notice. A guard that sees through walls is not a difficult guard. It is a guard the player cannot model. Every decision in this genre is a prediction about what an enemy knows, so an enemy that breaks its own rules does not add difficulty. It adds noise.
Drawing the cone is not debug output. It is the interface. A translucent wedge on the floor states the distance, the angle and the facing all at once, and it updates as the guard turns. Cut it off at the walls so the drawing agrees with the check, because a cone drawn through a wall promises a danger that is not there.
Colour is the cheapest channel available. Keep a cone cool while the guard is calm and push it warm as suspicion climbs. The player then reads the threat level of a whole room out of the corner of their eye, without stopping to study any single guard.
Detection takes a moment, and the moment is visible#
Instant detection is the other half of the same fault. If one frame inside a cone ends the level, the player had no decision to make and no chance to back out. Give each guard a number between zero and one. It rises while the player is visible and falls more slowly while the player is not.
The ratio between those two rates is the difficulty of the entire game, and it belongs in the config object. A quick rise with a quick fall gives a twitchy game of dashes between cover. A slow rise with a very slow fall gives a cautious one, where one mistake follows you around the level. Neither is wrong. One of them is what you meant.
Draw the number as a small bar above the guard. It is a few lines and it changes what the player is doing, from guessing and reloading to watching and deciding. Make the full bar loud. A sound and a jump in the cone colour as it fills are what turn being caught into something that happened rather than something that was decided off screen.
- A mark above the head for the state. Calm, a question mark, an exclamation mark. Three glyphs tell the player everything they need about what a guard is currently doing.
- A noise radius you can see. If running makes a sound, draw the ring it reaches. An invisible noise rule is the same fault as an invisible cone, and it is harder to guess at.
- A quiet moment at the start. Spawning inside a cone is not a challenge. Place the player out of sight and let them look at the room before anything moves.
- React before the reset. Half a second of the guard turning and the cone flashing is enough. A level that cuts straight to black has taught the player nothing.
A patrol is a list of points and a wait at each#
A guard that walks a loop without ever stopping is barely an obstacle, because the gap behind it is the same width everywhere. The waiting is what turns a route into a puzzle. Give each guard an array of points, each with a number of seconds to stand there, and let it turn slowly on the spot while it waits.
Now the level has a rhythm. There is a moment when a corridor is clear and a moment when it is not, and the player learns the pattern by watching rather than by dying. Two guards on loops of different lengths produce windows that open and close without you having designed a single one of them.
Keep the routes visible while you are testing. A key that draws each guard's points and the lines between them turns an hour of confusion into a glance. It is the same argument as the cone. You cannot tune a behaviour you are unable to see.
| The player says | What is happening | Ask for |
|---|---|---|
| It saw me through a wall | There is no line of sight check | A line test against every wall before sight counts |
| It saw me from behind | Detection is by distance alone | A facing direction and a cone half angle |
| I was caught with no warning | Suspicion fills in a single frame | A slower rise and a bar drawn above the guard |
| It knew exactly where I went | The guard is reading the live position | A stored last known position and nothing newer |
| Guards are trivial to walk past | The patrol never stops anywhere | A wait in seconds at every patrol point |
Every row is a sentence a real player says out loud, and every one of them maps to a single missing line.
Last known position, not teleportation#
The interesting part of a stealth game is the few seconds after being seen. That stretch only exists if the guard can be wrong about where you are. So store the player's position at the instant suspicion filled, send the guard to that spot, and do not look at the player again while the search is running.
Then breaking line of sight does something. Ducking behind a crate and slipping two rooms across is a plan, it works, and the player thought of it rather than being shown it. A guard reading the live position deletes every plan of that kind at once, and leaves running as the only idea the game can support.
Give the search an ending. The guard arrives, looks around for a few seconds, then walks back to the nearest patrol point and carries on. Without that, the level slowly fills with guards standing in corners where something once happened, and an early mistake makes the rest of the level unplayable.
If you want a cleverer search later, widen it rather than cheating. A guard can check a couple of points around the last known position instead of standing on it. That is still built only from what the guard legitimately saw, so the player can still follow the reasoning and still plan against it.
🎮Games on this site
Common questions#
Can AI make a stealth game?
Yes, and the vision cone is less maths than it sounds. The part to be specific about is what the player can see of the rules. Asked for a stealth game with no detail, a model will usually write detection by distance alone, which catches the player from behind and through walls.
Why do my guards see through walls?
Because sight is being tested as a distance and an angle with no line of sight check. Add a third test: the straight line from guard to player must cross none of the wall rectangles. Then cut the drawn cone off at the same walls, so the picture and the rule agree.
How do I draw a vision cone?
As a translucent wedge on the floor from the guard's position, using the sight distance as its length and the cone half angle either side of the facing direction. Fill it every frame and let its colour follow the suspicion value. It costs almost nothing and it is most of the game's interface.
Should being spotted be instant?
No. Instant detection gives the player nothing to react to and no way to learn. Use a value that rises while visible and falls while not, draw it over the guard, and alert only when it fills. The rise and fall rates are where the difficulty of the game actually lives.
How do I make a guard patrol?
A list of points, each with a wait in seconds. The guard walks to the next point, stands there for its wait while turning slowly, then moves on and loops. The waits are what create gaps a player can time, which is what makes a route feel designed rather than random.
What should a guard do after losing sight of the player?
Walk to the place the player was last seen, look around, then return to its patrol. Store that position once, at the moment detection completed, and never update it from the player's live position. Breaking line of sight has to work or none of the other mechanics matter.
Where to go next#
One room, two guards and an exit is already a game, and it is enough to find out whether your cones read. Publish it once a stranger can get past a guard on purpose rather than by luck. The page keeps the model and the prompt beside it.
The general method is in how to make a game with AI, and the drawing and input side is in the 2D guide. Tension built out of what the player cannot see is the subject of the horror guide. Patrol routes have a lot in common with the paths in the tower defence guide. Fixes for specific faults are in the prompt guide, and the categories page is the quickest way round the rest of the arcade.
Built something? Put it on Agent Games.
Publishing takes a file and a minute. Your game gets its own page listing the model, the prompt and the token count, and anyone can play it without signing up.
Read next