Phaser AE

Retro shooter textures

Pro packv3.0.0-02D and 3DLookNew

Walls, floors, ceilings, doors and liquids in the chunky pixel-art look of the early-1990s first-person shooters, made from a short spec instead of a texture pack. Each one tiles, comes with a height map and a glow mask, and is the same every time you ask for it.

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

Released October 24, 2026

Retro shooter textures: 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

retroTextures

function retroTextures(): Pack<{ retroTextures: RetroTexturesApi }>

Compose the retro texture generator under game.retroTextures. No options; every texture takes its own spec.

Helpers

normalMap

function normalMap(source: RetroHeightSource, options: RetroNormalOptions = {}): Uint8ClampedArray<ArrayBuffer>

A tangent-space normal map from a height map, as RGBA bytes in the source's strip layout. Each pixel's slope is the central difference of its neighbours' heights, wrapping at the frame's edges so the map tiles as the texture does. Red is +x (right), green is +y up the image (OpenGL convention; flipY for DirectX), blue is out of the surface, each 128 + 127 × n: a flat height is (128, 128, 255). Throws on a size that does not match its heights, a frame out of range or a strength out of range.

paintRetroTexture

function paintRetroTexture(ctx: RetroCanvasContext, texture: RetroPixels, options: number | RetroPaintOptions = {}): boolean

Paint one frame of a texture (or a normal map in the same shape) into a 2D canvas context at (x, y), pixel for pixel. Where OffscreenCanvas exists the frame goes through one and drawImage, so a kernel paint callback's scale and frame offset apply and the pixels stay sharp; otherwise putImageData writes them unscaled. Headless, with no ImageData, it does nothing. Returns whether it painted. A number in place of the options is the frame.

RAMP_SHADES

const RAMP_SHADES: 8

How many shades every resolved ramp has.

RETRO_KIND_NAMES

const RETRO_KIND_NAMES: readonly ["panel", "tech", "support", "door", "door-trim", "light", "crate", "console", "switch", "vent", "grate", "pipes", "girder", "metal-floor", "warning", "brick", "stone", "cobbles", "concrete", "tiles", "marble", "rock", "wood", "grass", "slime", "ooze", "lava", "water", "glass", "fabric", "plaster", "rack"]

Every kind of texture, in the order retroKinds lists them.

retroKinds

const retroKinds: Readonly<Record<RetroKind, RetroKindInfo>>

Every kind with its look, defaults, variants and options, by name.

retroPalettes

const retroPalettes: Readonly<Record<RetroPaletteName, readonly string[]>>

The built-in ramps by name: eight CSS colours each, darkest first. The shades step evenly in lightness and shift hue as they go (darks cooler, lights warmer, except the steels, whose highlight is a cool cyan), the way hand-made palettes of the period did, so the ramps sit together in one level.

retroTexture

function retroTexture(spec: RetroTextureSpec): RetroTexture

Make a texture. Pure and deterministic: the same spec gives the same pixels, with no clock and no Math.random. Throws, naming the field, on an unknown kind, variant or option, a size that is not a multiple of 8 from 16 to 256, a non-finite seed, an option out of its range, or a colour the kernel's parser cannot read.

retroTextureFor

function retroTextureFor(name: string, options: RetroTextureForOptions = {}): RetroTextureSpec

A texture recipe for a surface name: the recipe of the first theme that has the name (the ones asked for first, then tech, industrial, castle, neon, crypt and office), else one guessed from its words (door-red is a door with a red key stripe, old-brick is brick, slime-pit is slime), else a steel panel seeded from the name, so two unknown names differ. Always returns a fresh spec for retroTexture; throws on a theme that does not exist.

retroThemes

const retroThemes: Readonly<Record<RetroThemeName, RetroTheme>>

The built-in themes. Every recipe has a fixed seed, so a level always wears the same walls.

Types

RetroCanvasContext

interface RetroCanvasContext

The part of a 2D canvas context paintRetroTexture uses; a CanvasRenderingContext2D, an offscreen one, or a painter's.

  • putImageData(image: ImageData, x: number, y: number): void — Write pixels, ignoring the context's transform.
  • drawImage?(image: OffscreenCanvas, x: number, y: number, w: number, h: number): void — Draw an image through the context's transform (how a scaled painter's context is honoured).
  • imageSmoothingEnabled?: boolean — Smoothing for scaled draws; turned off while the pixels are drawn.

RetroHeightSource

interface RetroHeightSource

Anything with a height map in strip layout: a RetroTexture, or your own heights.

  • readonly width: number — One frame's width in pixels.
  • readonly height: number — One frame's height in pixels.
  • readonly heights: ArrayLike<number> — Heights 0..1, width * frames × height, row by row.
  • readonly frames?: number — Frames side by side; default 1.

RetroKind

type RetroKind = typeof RETRO_KIND_NAMES[number]

A kind of texture: one of RETRO_KIND_NAMES.

RetroKindInfo

interface RetroKindInfo

One kind as retroKinds describes it.

  • readonly name: RetroKind — Its name, as the spec's kind.
  • readonly about: string — What it looks like.
  • readonly palette: RetroPaletteName — The palette it uses when the spec names none.
  • readonly accent: RetroPaletteName — The accent ramp it uses when the spec names none.
  • readonly animated: boolean — Whether it has frames that loop.
  • readonly emissive: boolean — Whether its emissive mask is lit.
  • readonly variants: readonly RetroVariantInfo[] — Its layout presets; the first is the default.
  • readonly options: Readonly<Record<string, RetroOptionInfo>> — Every option it takes, with its default, range and meaning (the common grain included).

RetroNormalOptions

interface RetroNormalOptions

How normalMap works.

  • strength?: number — How steep a height step looks, 0 to 64; default 2. A step from 0.5 to 0.75 tilts about 27° at 2.
  • frame?: number — Only this frame (0-based); default every frame, side by side as in the source.
  • flipY?: boolean — Green points down the image (the DirectX convention) instead of up (the OpenGL convention); default false.

RetroOptionInfo

interface RetroOptionInfo

One option of a kind, as retroKinds lists it.

  • readonly default: RetroOptionValue — What it is when neither the spec nor the variant sets it.
  • readonly about: string — What it changes, in a sentence, with its units.
  • readonly min?: number — The smallest number it takes (numbers only).
  • readonly max?: number — The largest number it takes (numbers only).
  • readonly values?: readonly string[] — The words it takes (choices only).
  • readonly ramp?: boolean — True when it takes a ramp: a palette name or an array of CSS colours.

RetroOptionValue

type RetroOptionValue = number | boolean | string | readonly string[]

A value an option takes: a number, a switch, a choice, or a ramp (a palette name or a list of CSS colours).

RetroPaintOptions

interface RetroPaintOptions

Where and what paintRetroTexture paints.

  • frame?: number — The frame to paint (wrapping); default 0.
  • x?: number — Left edge in the context's units; default 0.
  • y?: number — Top edge in the context's units; default 0.
  • layer?: 'color' | 'emissive' | 'height' — What to paint: the colours (default), the emissive mask or the height map, as grey.

RetroPaletteName

type RetroPaletteName = | 'steel' | 'gunmetal' | 'lab' | 'stone' | 'brick' | 'rust' | 'hazard' | 'toxic' | 'concrete' | 'wood' | 'brass' | 'alien' | 'lava' | 'water' | 'marble' | 'grass' | 'rock' | 'phosphor' | 'amber' | 'lamp' | 'red' | 'blue' | 'blood' | 'glass' | 'carpet' | 'wine' | 'leather' | 'plaster'

The names of the built-in ramps, each eight CSS colours from near-black to a highlight.

RetroPixels

interface RetroPixels

Anything with RGBA pixels in strip layout: a RetroTexture, or { width, height, rgba: normalMap(t), frames }.

  • readonly width: number — One frame's width in pixels.
  • readonly height: number — One frame's height in pixels.
  • readonly rgba: ArrayLike<number> — RGBA bytes, width * frames × height.
  • readonly frames?: number — Frames side by side; default 1.
  • readonly emissive?: ArrayLike<number> — Emission 0..255 per pixel, for layer: 'emissive'.
  • readonly heights?: ArrayLike<number> — Heights 0..1 per pixel, for layer: 'height'.

RetroRamp

type RetroRamp = RetroPaletteName | readonly string[]

A ramp: a built-in name, or 2 to 16 CSS colours ordered dark to light (any form the kernel's colour parser reads). A list of any other length than eight is resampled to eight shades, blending neighbours in sRGB.

RetroTexture

interface RetroTexture

A made texture: colour, height and emission for each pixel of each frame. Frames sit side by side, so every array is a strip width * frames pixels wide and height tall, row by row: pixel (x, y) of frame f is at index y * width * frames + f * width + x. That is the layout raycast-view's texturePixels and the kernel's painted strips use.

  • readonly kind: RetroKind — The kind it was made as.
  • readonly width: number — One frame's width in pixels.
  • readonly height: number — One frame's height in pixels.
  • readonly frames: number — Frames in this strip: 1 for a still kind or a single frame, else the loop.
  • readonly loop: number — Frames in the full loop (1 for a still kind); frame loop is frame 0 again.
  • readonly rgba: Uint8ClampedArray<ArrayBuffer> — Colour, RGBA bytes; alpha is 255 except where a see-through option clears it, and a glass pane's opacity.
  • readonly heights: Float32Array<ArrayBuffer> — Height per pixel, 0 (deepest: seams, mortar, holes) to 1 (highest: rivet heads); 0.5 is the surface.
  • readonly emissive: Uint8Array<ArrayBuffer> — Emission per pixel, 0 to 255: non-zero only on lights, screens, lit lamps and buttons, slime and lava.

RetroTextureForOptions

interface RetroTextureForOptions

Options for retroTextureFor.

  • themes?: RetroThemeName | readonly RetroThemeName[] — Themes to look in first, in order; afterwards every theme is tried. Default none.
  • overrides?: Partial<RetroTextureSpec> — Fields laid over the recipe found (size, seed, palette…); options merge with the recipe's. Default none.

RetroTexturesApi

interface RetroTexturesApi

game.retroTextures: make textures, their normal maps, and paint them; the palettes and kinds to choose from.

  • make: typeof retroTexture — Make a texture from a spec: make({ kind: 'panel', size: 64, seed: 3, variant: 'quad' }). See retroTexture.
  • normalMap: typeof normalMap — A texture's normal map as RGBA bytes: normalMap(texture, { strength }). See normalMap.
  • paint: typeof paintRetroTexture — Paint a frame into a 2D canvas context, such as a game.paint callback's. See paintRetroTexture.
  • palettes: typeof retroPalettes — The built-in ramps by name.
  • kinds: typeof retroKinds — Every kind with its look, defaults, variants and options.
  • forName: typeof retroTextureFor — A recipe for any surface name, from the themes or a guess: make(forName('door-red', { themes: 'tech' })). See retroTextureFor.
  • themes: typeof retroThemes — The built-in themes: recipes by surface name for a tech base, an industrial plant, a castle, a neon arena, a crypt and an office block.

RetroTextureSpec

interface RetroTextureSpec

What to make. Only kind is needed; everything else has a default.

  • kind: RetroKind — The kind of texture (retroKinds lists them with their options).
  • size?: number — Width and height in pixels, a multiple of 8 from 16 to 256; default 64.
  • width?: number — Width in pixels, overriding size for a non-square texture (a door 64 × 128); a multiple of 8 from 16 to 256.
  • height?: number — Height in pixels, overriding size; a multiple of 8 from 16 to 256.
  • seed?: number — Chooses the noise and layout; default 1. A whole number (others are rounded). The same seed gives the same texture.
  • palette?: RetroRamp — The main ramp: a retroPalettes name or 2 to 16 CSS colours dark to light; default the kind's (or variant's).
  • accent?: RetroRamp — The second ramp, for stripes, lights, screens, rust, moss, mortar and so on; default the kind's (or variant's).
  • variant?: number | string — A layout preset of the kind, by number from 0 or by name; default 0. Its options are overridden by options.
  • frames?: number — Animated kinds: frames in one loop, 1 to 64; default 8. Still kinds always have one frame.
  • frame?: number — Animated kinds: make only this frame of the loop (wrapping, so frames is frame 0 again); default every frame.
  • options?: Readonly<Record<string, RetroOptionValue>> — The kind's options by name (and the common grain); unknown names and out-of-range values throw.

RetroTheme

type RetroTheme = Readonly<Record<string, RetroTextureSpec>>

A theme: a recipe for each surface name it knows.

RetroThemeName

type RetroThemeName = 'tech' | 'industrial' | 'castle' | 'neon' | 'crypt' | 'office'

A theme's name.

RetroVariantInfo

interface RetroVariantInfo

A named layout of a kind: a preset of its options, chosen with the spec's variant.

  • readonly name: string — Its name, usable as the spec's variant in place of its number.
  • readonly about: string — What it looks like.
  • readonly set: Readonly<Record<string, RetroOptionValue>> — The options it sets; the spec's own options override them.
  • readonly palette?: RetroPaletteName — The palette it uses when the spec names none; default the kind's.
  • readonly accent?: RetroPaletteName — The accent ramp it uses when the spec names none; default the kind's.