Phaser AE

Visibility and line of sight

Free packv3.0.0-42DLogic

A set of wall segments and the three questions a game asks of them: what can be seen from here, can A see B, and what does a ray hit first. It is pure geometry on the CPU, cheap enough for AI to ask every step.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 20, 2026

Visibility and line of sight: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

What it does

game.visibility.create() makes a set, and you fill it with the level's walls: single segments, the four edges of a rectangle, or the edges of a polygon. Each segment is a plain object, so moving a door or a crate is a matter of changing its numbers, and remove and clear take walls away.

visibility(x, y, range) returns the visibility polygon: the points a viewer at (x, y) can see to, in angle order, ready to fan into triangles and draw as a light or a fog mask. It uses the classic method, a ray cast just either side of every segment corner with the nearest hit kept, which is exact and leaves no holes. canSee says whether the straight line between two points is within range and crosses no wall, the question a guard asks about the player. raycast returns the first hit along a ray, with its point and distance, for a hit-scan weapon or a laser.

Optional bounds are a rectangle every ray stops at, usually the camera's view, so a polygon in an open world stays finite. The class, Visibility2d, is exported too, so a pack or a worker can use it without the game.

Features

  • Visibility polygons — the fan of points a viewer sees within a range, in angle order.
  • Line of sight — canSee between two points, with a maximum distance.
  • Raycasts — the nearest hit point and its distance along any direction.
  • Walls from shapes — addSegment, addRect and addPoly, from points or a flat list, closed or open.
  • Moving walls — change a segment's fields to move it, with nothing to rebuild.
  • Bounds — setBounds stops rays at a rectangle, such as the camera's view.

Good for

  • Stealth games: can the guard see the player, and what does the guard's view cover.
  • Fog of war in a continuous world, drawing what the player can see as a mask.
  • Shadowed 2D lights, through the lighting pack.
  • Hit-scan weapons and lasers that stop at the first wall.
  • Top-down shooters with free-form walls, where enemies react only to what they can see.

Make it yours

The pack has no options: a set is its walls and its bounds. Two different uses: a stealth level where each guard calls canSee towards the player within 400 units every step, and the player's own view is drawn from visibility as a darkness mask; and a lit scene where the same walls cast shadows from every light, with no fog at all.

A quick look

Walls of three kinds, then the three questions:

const v = game.visibility.create({ x: 0, y: 0, w: 640, h: 360 });   // bounds rays always stop at
v.addRect(100, 80, 32, 32);                        // four walls
v.addPoly([0, 0, 50, 10, 40, 60]);                 // a closed polygon
const wall = v.addSegment(0, 200, 640, 200);       // one wall; change wall.x1 and the rest to move it
const poly = v.visibility(px, py, 300);            // points in angle order within 300 units
const seen = v.canSee(guard.x, guard.y, hero.x, hero.y, 400);
const hit = v.raycast(ox, oy, dx, dy, 500);        // { x, y, dist } of the nearest hit, or null

Works with

  • lighting-2d — shadowed point lights, which keep one of these sets as their occluders.
  • stealth — guards with sight, hearing, suspicion and search, built on this pack.
  • fog — a tile-grid fog of war that remembers what was seen, the alternative for tile maps.

Good to know

  • The cost is rays times segments per call: hundreds of segments and a handful of polygons a frame is comfortable, and for big maps you merge runs of tiles into long segments.
  • With no walls in range, no bounds and no range limit, visibility returns an empty list: set bounds in an open world.
  • canSee ignores the bounds, while raycast and visibility include them.
  • Segments have no thickness and no inside, and there is no spatial index: every call scans every segment.
  • It is 2D only.

More Logic packs

Show all →