Phaser AE

Raycast corridor view

Pro packv3.0.0-02DLookNew

A first-person view of a grid map, drawn the way the 1992 corridor shooters drew it: one ray per screen column, a textured wall strip for each, flat sprites in front, all into one small picture. You get the chunky early-1990s look from the real technique rather than a filter over a 3D scene.

This is a Pro pack. Upgrade to Phaser Pro to use it in your games.See Phaser Pro →

Released October 24, 2026

Raycast corridor view: 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.

The pack

raycastView

function raycastView(): Pack<{ raycastView: RaycastViewApi }>

Compose the raycast view under game.raycastView. No options; each view takes its own.

Helpers

castColumns

function castColumns(map: RaycastMap, camera: RaycastCamera, options: CastOptions = {}): RaycastColumns

Cast one ray per screen column from camera across map and report what each hit: the distance along the view direction (perpendicular, the depth buffer), the face, the cell, the picture and where across the face. Column i's ray leaves at camX = 2 (i + 0.5) / width − 1 of the way from the centre to the edge of the field of view, right positive. A door is hit on its cell's mid-plane where its panel still covers (the panel slides by open along its axis into the wall beyond); a pushed wall is drawn where it is, progress of the way along dx, dz. Throws on a non-finite camera or an option out of range.

createRaycastRenderer

function createRaycastRenderer(options: RaycastOptions = {}, target?: Uint32Array): RaycastRenderer

Make a renderer: new RaycastRenderer(options, target). Throws, naming the field, on an option out of range.

DEFAULT_FOV

const DEFAULT_FOV: number

The default horizontal field of view, radians (66°).

projectSprite

function projectSprite(camera: RaycastCamera, sprite: RaycastSprite, screen: SpriteScreen): SpriteProjection | null

Project a sprite through the camera onto the screen the walls are drawn on: the same field of view, eye height and horizon, so a sprite standing on the floor meets the floor where a wall at the same distance does. Null when it is behind the eye or nearer than near. Off-screen sprites are still projected; their columns fall outside the image.

RAYCAST_HIT

const RAYCAST_HIT: { readonly none: 0; readonly wall: 1; readonly door: 2; readonly push: 3; readonly jamb: 4 }

The codes RaycastColumns.hit holds, by kind.

spriteColumns

function spriteColumns(p: SpriteProjection, width: number): [number, number]

The first and last screen columns whose centres a projection covers, clipped to 0..width-1; first > last when none.

spriteSpans

function spriteSpans(p: SpriteProjection, depth: ArrayLike<number>): Array<[number, number]>

The runs of columns where a projected sprite is in front of the walls, as [first, last] pairs left to right: column i shows when p.depth < depth[i] (the walls' RaycastColumns.dist). What the renderer clips each sprite by.

Classes

RaycastColumns

class RaycastColumns

Every column's hit from one cast, as typed arrays so a frame allocates nothing. Index i is screen column i, left to right. Reuse one by passing it as out to castColumns.

  • readonly width: number — How many columns.
  • readonly dist: Float64Array — Perpendicular distance per column, world units; Infinity where nothing was hit. This is the depth buffer sprites clip against.
  • readonly side: Uint8Array — Face per column: 0 for a face along x, 1 for a face along z.
  • readonly cellX: Int32Array — Cell column hit per column.
  • readonly cellZ: Int32Array — Cell row hit per column.
  • readonly u: Float64Array — Across-the-face coordinate per column, 0 to 1, as the viewer sees it.
  • readonly hit: Uint8Array — What each column hit, as a RAYCAST_HIT code.
  • readonly texture: string[] — Picture name per column ('' where nothing was hit).
  • constructor(width: number) — Room for width columns, a whole number from 1 to 8192. Throws on any other.
  • column(i: number): RaycastColumn — Column i as an object (a copy), for a test or a one-off question. Throws for a column outside 0..width-1.

RaycastRenderer

class RaycastRenderer

A raycaster that draws into a buffer of pixels, with no canvas: the part of a raycast view that does the work, made on its own for a test, a worker or a custom presenter. render casts the columns from the camera, draws the walls textured and shaded (faces along x by sideShade), the floor and ceiling flat or textured, everything faded toward the fog colour with distance, then the sprites far to near, each column clipped by the walls in front of it.

  • readonly width: number — Image width in pixels.
  • readonly height: number — Image height in pixels.
  • readonly pixels: Uint32Array — The image, width × height pixels row by row from the top-left, 0xAABBGGRR and opaque after a render.
  • readonly columns: RaycastColumns — The last render's columns: what each hit and how far away (the depth buffer).
  • constructor(options: RaycastOptions = {}, target?: Uint32Array) — Make one with options. target, when given, is the buffer drawn into (a view passes its canvas's pixels): at least width × height long. Throws, naming the field, on an option out of range or a target too short.
  • get settings(): RaycastSettings — Every option's value now.
  • configure(options: RaycastOptions): void — Change options from the next render; anything left out keeps its value. Throws on a value out of range, or on a new width or height.
  • addTexture(name: string, w: number, h: number, rgba: ArrayLike<number>, frames = 1): RaycastTexture — Add or replace a texture from RGBA bytes (an ImageData's data): frames frames of w × h side by side, so the bytes hold w × frames × h × 4. Throws on a size out of range (1 to 4096 pixels a side, 1 to 1024 frames) or bytes of the wrong length.
  • texture(name: string): RaycastTexture | undefined — A texture by name, or undefined.
  • has(name: string): boolean — Whether a texture of that name has been added.
  • get textureNames(): string[] — Every texture name, in the order added.
  • render(map: RaycastMap, camera: RaycastCamera, sprites: readonly RaycastSprite[] = []): RaycastColumns — Draw map from camera, with sprites (default none), into pixels, and return the columns. Every pixel is written. Throws (when strict) on a non-finite camera, a name with no texture, or a sprite frame outside its strip.

Types

CastOptions

interface CastOptions

How castColumns casts.

  • width?: number — Columns, a whole number from 1 to 8192; default 320 (or out's width).
  • fov?: number — Horizontal field of view, radians, 0.1 to 3.1; default 66° (66 * Math.PI / 180).
  • maxDistance?: number — How far a ray goes, world units, 1 to 1024; default 64. A column with nothing nearer reports 'none'.
  • jamb?: string | null — A picture for the wall faces either side of a door, seen from inside the door's cell (the door's frame); default none, the wall's own.
  • textureOf?: ((name: string, x: number, z: number, kind: RaycastHitKind) => string) | null — Choose the picture per hit (an animated wall, a used switch, a palette per floor): given the map's name, the cell and the kind of hit, return the name to draw. Called once per column, so keep it cheap. Default: the map's name.
  • out?: RaycastColumns — Columns to fill in place of new ones; its width wins over width.

RaycastCamera

interface RaycastCamera

Where the eye is. World units: cells are 1 unit, cell (x, z) spans x..x+1 and z..z+1. The engine's yaw: forward is (−sin yaw, cos yaw), so 0 faces +z and turning right adds to it.

  • x: number — Eye position across the map, world units.
  • z: number — Eye position down the rows, world units.
  • yaw: number — Facing, radians: 0 faces +z, π/2 faces −x.
  • height?: number — Eye height above the floor, world units; default the view's eyeHeight (half a wall). Kept inside the walls' height.
  • bob?: number — A small vertical offset added to the eye height (a walking bob), world units; default 0.

RaycastColumn

interface RaycastColumn

One column's hit as an object, from RaycastColumns.column(i).

  • dist: number — Distance to the hit along the view direction (perpendicular, so walls do not bow), world units; Infinity when nothing is within range.
  • side: 'x' | 'z' — 'x' when the face hit faces along x (crossing a vertical x boundary), 'z' when it faces along z.
  • x: number — The cell hit (a pushed wall reports the cell it started this step in).
  • z: number — The cell row hit.
  • texture: string — The picture name to draw ('' when nothing was hit).
  • u: number — 0 to 1 across the face, left to right as the viewer sees it, so pictures are never mirrored. A door's runs with its panel.
  • kind: RaycastHitKind — What was hit.
  • door: boolean — Whether a door panel was hit.

RaycastHitKind

type RaycastHitKind = 'none' | 'wall' | 'door' | 'push' | 'jamb'

What a column's ray stopped on: nothing within range, a wall cell's face, a door panel, a pushed wall, or a wall face beside a door seen from the doorway.

RaycastMap

interface RaycastMap

The map a raycaster draws: what cell-dungeon's CellDungeon provides. Any grid of square cells with the same four questions can be drawn, so a game with its own map type adapts it here rather than converting.

  • kindAt(x: number, z: number): CellKind — The kind of a cell; off the map is a wall.
  • textureAt(x: number, z: number): string — The picture name on a wall, door or switch cell.
  • doors(): readonly CellDoor[] — Every door with its axis and how far open it is; read once per draw.
  • pushing(): readonly CellPushWall[] — The walls sliding now, with their direction and progress; read once per draw.

RaycastOptions

interface RaycastOptions

How a raycast view looks. Every field is optional; configure changes any of them later except the resolution.

  • width?: number — Image width in pixels, a whole number from 8 to 2048; default 320. Fixed once made.
  • height?: number — Image height in pixels, a whole number from 8 to 2048; default 200. Fixed once made.
  • fov?: number — Horizontal field of view, radians, 0.1 to 3.1; default 66°.
  • sideShade?: number — Brightness of faces that face along x, against 1 for faces along z, 0 to 1; default 0.7.
  • fog?: string | null — The CSS colour distance fades toward, or null for no fading; default '#000000'.
  • fogStart?: number — Distance where fading starts, world units, 0 or more; default 4.
  • fogEnd?: number — Distance where everything is the fog colour, world units, beyond fogStart; default 24.
  • floor?: string — Floor colour, CSS, where there is no floor texture; default '#707070'.
  • ceiling?: string — Ceiling colour, CSS, where there is no ceiling texture; default '#383838'.
  • floorTexture?: string | null — A texture name for the floor, cast row by row, or null for the flat colour; default null.
  • ceilingTexture?: string | null — A texture name for the ceiling, or null for the flat colour; default null.
  • floorScale?: number — How many times the floor and ceiling textures repeat per cell, 0.05 to 64; default 1.
  • wallHeight?: number — How tall walls are drawn, world units (a cell is 1 across), 0.1 to 16; default 1. The ceiling sits on top of them.
  • eyeHeight?: number | null — Eye height above the floor, world units, between 0 and wallHeight; default half of wallHeight. A camera's height overrides it.
  • maxDistance?: number — How far rays go, world units, 1 to 1024; default 64. Beyond, the floor and ceiling run on to the horizon.
  • pixelAspect?: number — How tall a pixel shows relative to its width, 0.25 to 4; default 1 (square). 1.2 for 320 × 200 shown at 4:3.
  • jamb?: string | null — A texture name for the wall faces either side of a door, seen from the doorway; default null (the walls' own).
  • fallback?: string | null — A texture name drawn wherever a name has no texture; default null.
  • textureOf?: ((name: string, x: number, z: number, kind: RaycastHitKind) => string) | null — Choose the picture per hit (an animated wall, a used switch): (name, x, z, kind) => name; default null. Called once per column.
  • strict?: boolean — Throw on a name with no texture (and no fallback), a sprite frame outside its strip or a non-finite camera; default true (a view takes the game's dev mode). When false these draw flat grey, wrap or skip the frame.

RaycastSettings

interface RaycastSettings

Every option with its value now, as settings reports them.

  • readonly width: number — Image width in pixels.
  • readonly height: number — Image height in pixels.
  • readonly fov: number — Horizontal field of view, radians.
  • readonly sideShade: number — Brightness of faces along x.
  • readonly fog: string | null — The fog colour, or null.
  • readonly fogStart: number — Where fading starts, world units.
  • readonly fogEnd: number — Where fading ends, world units.
  • readonly floor: string — Floor colour.
  • readonly ceiling: string — Ceiling colour.
  • readonly floorTexture: string | null — Floor texture name, or null.
  • readonly ceilingTexture: string | null — Ceiling texture name, or null.
  • readonly floorScale: number — Floor and ceiling texture repeats per cell.
  • readonly wallHeight: number — Wall height, world units.
  • readonly eyeHeight: number — Eye height in use, world units.
  • readonly maxDistance: number — Ray range, world units.
  • readonly pixelAspect: number — Pixel aspect.
  • readonly jamb: string | null — Door frame texture name, or null.
  • readonly fallback: string | null — Fallback texture name, or null.
  • readonly textureOf: ((name: string, x: number, z: number, kind: RaycastHitKind) => string) | null — The per-hit texture chooser, or null.
  • readonly strict: boolean — Whether mistakes throw.

RaycastSprite

interface RaycastSprite

A flat picture that always faces the eye: an enemy, an item, a shot. World units.

  • x: number — Position across the map, world units.
  • z: number — Position down the rows, world units.
  • y?: number — Height of the picture's centre above the floor, world units; default half its height, so it stands on the floor.
  • texture: string — The picture's name, as given to texture, textureFrom or texturePixels.
  • frame?: number — Which frame of the picture's strip, a whole number from 0; default 0.
  • scale?: number — Height in world units (a wall is 1); default 1. The width follows the frame's shape.
  • tint?: string — A CSS colour multiplied into the picture; default white (none).
  • bright?: boolean — Drawn at full brightness, ignoring fog (a muzzle flash, a glowing shot); default false.

RaycastTexture

interface RaycastTexture

A picture the renderer samples: a strip of frames frames of width × height side by side.

  • readonly name: string — Its name.
  • readonly width: number — One frame's width in pixels.
  • readonly height: number — Height in pixels.
  • readonly frames: number — How many frames, side by side.
  • readonly pixels: Uint32Array — The pixels, 0xAABBGGRR, row by row across the whole strip (width × frames a row).

RaycastView

interface RaycastView

A raycast view: one picture of width × height pixels that draw repaints from a map, a camera and sprites. Show it with a sprite: game.spawn({ texture: view.key, x, y, width, height, layer }). Textures are added by name before they are drawn.

  • readonly key: string — The asset key of the picture.
  • readonly frame: number — The picture's frame index, for a sprite's frame.
  • readonly width: number — Image width in pixels.
  • readonly height: number — Image height in pixels.
  • readonly live: boolean — False headless (no canvas pixels): draws and paints do nothing.
  • readonly drawn: number — Frames drawn so far (0 headless).
  • readonly destroyed: boolean — Whether destroy has run.
  • readonly renderer: RaycastRenderer — The renderer underneath: its pixels after a draw, its textures, configure.
  • readonly columns: RaycastColumns — The last draw's columns: each one's hit and distance (the depth buffer).
  • readonly settings: RaycastSettings — Every option's value now.
  • texture(name: string, w: number, h: number, draw: (ctx: PaintContext, frame: number) => void, frames?: number): RaycastView — Paint a texture with the ordinary 2D canvas, as the kernel's paint does: frames frames of w × h pixels side by side, draw(ctx, i) once for each on its own w × h, translated and clipped to it. The pixels are read once. A name painted again is replaced. Headless the texture is registered blank and draw never runs. Throws on a size out of range (1 to 4096, 1 to 1024 frames) or after destroy in dev. Returns the view.
  • textureFrom(name: string, source: CanvasImageSource, frames?: number): RaycastView — A texture from an existing image, canvas or bitmap: frames equal frames across its width (which must divide by frames). Read once. Headless it is registered blank at the source's size. Returns the view.
  • texturePixels(name: string, w: number, h: number, rgba: ArrayLike<number>, frames?: number): RaycastView — A texture from RGBA bytes: frames frames of w × h side by side (w × frames × h × 4 bytes). Works headless too. Returns the view.
  • has(name: string): boolean — Whether a texture of that name has been added.
  • configure(options: RaycastOptions): void — Change any option but the resolution from the next draw. Throws on a value out of range.
  • draw(map: RaycastMap, camera: RaycastCamera, sprites?: readonly RaycastSprite[]): void — Draw map from camera with sprites (default none) and show it from this frame. Throws in dev on a non-finite camera, a name with no texture (unless fallback is set) or a sprite frame outside its strip, and after destroy.
  • destroy(): void — Stop drawing and give the canvas back for the next view of this size. The scene that made the view does this when it exits.

RaycastViewApi

interface RaycastViewApi

game.raycastView: live views, and the pure maths and renderer underneath them.

  • create(options?: RaycastViewOptions): RaycastView — Make a view: a picture of width × height pixels (default 320 × 200) registered as a live canvas, repainted by each draw. Show it with game.spawn({ texture: view.key, … }). Made in a scene, it is destroyed when the scene exits and its canvas is reused by the next view of that size. Throws, naming the field, on an option out of range.
  • castColumns: typeof castColumns — Cast one ray per column and report each hit: castColumns(map, camera, { width, fov, maxDistance, jamb, textureOf, out }).
  • projectSprite: typeof projectSprite — Where a sprite lands on the screen: projectSprite(camera, sprite, screen).
  • spriteColumns: typeof spriteColumns — The first and last columns a projected sprite covers.
  • spriteSpans: typeof spriteSpans — The runs of columns where a projected sprite is in front of the walls.
  • createRaycastRenderer: typeof createRaycastRenderer — A renderer with no canvas, drawing into a buffer of pixels.
  • RaycastRenderer: typeof RaycastRenderer — The renderer's class.
  • RaycastColumns: typeof RaycastColumns — The columns' class.
  • RAYCAST_HIT: typeof RAYCAST_HIT — The codes RaycastColumns.hit holds.

RaycastViewOptions

interface RaycastViewOptions extends RaycastOptions

What create takes: how the view looks, and the asset key its picture goes under.

  • key?: string — The key the picture is registered under, for spawn({ texture: key }); default 'raycast-view-1', 'raycast-view-2', …

SpriteProjection

interface SpriteProjection

Where a sprite lands on the screen, in pixels from the top-left corner (column i spans i..i+1).

  • depth: number — Distance along the view direction, world units: compared with the walls' RaycastColumns.dist.
  • x: number — Screen x of its centre.
  • left: number — Screen x of its left edge.
  • right: number — Screen x of its right edge.
  • top: number — Screen y of its top edge.
  • bottom: number — Screen y of its bottom edge.

SpriteScreen

interface SpriteScreen

The screen a sprite is projected onto: the view's resolution, field of view and eye.

  • width: number — Image width in pixels.
  • height: number — Image height in pixels.
  • fov: number — Horizontal field of view, radians.
  • eyeHeight: number — Eye height above the floor when the camera gives none, world units.
  • pixelAspect?: number — How tall a pixel shows relative to its width; default 1 (square).
  • frameAspect?: number — The frame's width over its height; default 1 (square).
  • near?: number — Nearest depth drawn, world units; default 0.05. Anything nearer, or behind the eye, is not projected.