Phaser AE

Glass corridor

Pro packv3.0.0-13DArcade

A first-person throwing run on real rigid bodies: the launcher travels down a corridor, glass stands in the way, and every ball is ammunition you can lose or win back. A seeded generator builds the levels and plays each one through the physics, so every seed you ship is known to be beatable.

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

Released October 19, 2026

Glass corridor: 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

glassCorridor

function glassCorridor(): Pack<{ glassCorridor: GlassCorridorApi }>

The glass-corridor pack: Smash Hit's rules on real rigid bodies, independent of rendering.

Helpers

CORRIDOR_FAMILIES

const CORRIDOR_FAMILIES: readonly CorridorFamily[]

Every room family.

createGlassCorridor

const createGlassCorridor = (config: CorridorConfig): Promise<GlassCorridor>=> …

Create a round, the same as GlassCorridor.create.

generateCorridor

async function generateCorridor(o: CorridorOptions = {}): Promise<CorridorLevel>

Generate a level and prove it winnable by playing it through the physics. Throws on an option outside its bounds, and when no certified arrangement is found in 30 attempts.

Classes

GlassCorridor

class GlassCorridor

A corridor round on its own rigid world.

  • readonly config: CorridorConfig — The configuration it was created with (an owned copy).
  • static async create(c: CorridorConfig): Promise<GlassCorridor> — Create a round with its own physics world; resolves when the rigid-body runtime is ready. Throws on an unknown material, duplicate piece ids, or a number outside its bounds.
  • get state(): CorridorState — A fresh copy of the state, with every body's pose.
  • get solved(): boolean — Whether the round is won.
  • get lost(): boolean — Whether the round is lost.
  • get origin(): Point — Where a ball leaves now: the configured origin moved forward by the progress.
  • trajectory(velocity: Point, seconds = 2): Point[] — The free flight of a throw at velocity for seconds (0.1 to 5, default 2), as 41 points.
  • aimAt(point: Point): Point — The velocity that throws straight at point at shotSpeed.
  • fire(velocity: Point): { valid: boolean; reason: string } — Throw at velocity. Invalid, throwing nothing, when the round is over, the balls are spent or one was thrown in the last 0.2 s. Throws when the velocity is out of bounds.
  • step(dt: number): void — Advance by dt seconds (0 to 0.1) in fixed 1/120 s ticks; the remainder carries to the next call.
  • hint(): { target: string; velocity: Point } | null — A throw at the nearest piece within 26 units ahead: its id and the velocity, or null.
  • reset(): void — Rebuild the round: every piece whole, the balls restored.
  • dispose(): void — Release the physics world; the round cannot be used afterwards.

Types

CorridorConfig

interface CorridorConfig

A corridor round: the obstacles, the launcher's run, the ammunition rules.

  • pieces: LaunchPiece[] — Every piece, from 1 to 160, with distinct ids. Pieces with motion swing as they are approached.
  • rooms?: CorridorRoom[] — Rooms for the presenter. Optional; the rules ignore them.
  • origin: Point — Where shots leave from at the start, world units; it moves forward along z with state.progress.
  • gravity?: number — Gravity along y, world units a second squared, from -30 to 0. Default 0.
  • ammo: number — Balls at the start, a whole number from 1 to 80.
  • shotSpeed: number — The fastest a ball may leave, world units a second, from 5 to 40.
  • travelSpeed: number — How fast the launcher travels, world units a second, from 0 to 6.
  • end: number — The z the launcher must reach to win, from 0 to 300.
  • collisionCost: number — Balls lost for each piece run into, a whole number from 1 to 20.
  • crystalReward: number — Balls gained for each reward piece shot (running into one gives none), a whole number from 0 to 10.
  • materials?: Record<string, MaterialDef> — Materials by name, merged over DEFAULT_MATERIALS.
  • rewards?: string[] — The materials that earn balls when shot, and cost none when run into. Default ['crystal'].

CorridorFamily

type CorridorFamily = 'gallery' | 'shutters' | 'lattice' | 'slalom' | 'vault' | 'gauntlet'

The room families: a wide pane, sliding doors, a lattice of small panes, offset panes to weave between, a vault with a swinging beam and pillar, and a gauntlet of swinging gates.

CorridorLevel

interface CorridorLevel

A generated level and the proof that it can be won.

  • seed: number — The seed it was generated from.
  • difficulty: Difficulty — The difficulty it was generated at.
  • config: CorridorConfig — The round to play: pass it to createGlassCorridor.
  • parameters: Required<CorridorOptions> — The options with every default filled in; pass them back to get the same level.
  • solution: { time: number; velocity: Point }[] — A winning sequence the generator played through the physics: each throw's velocity and when it was made.
  • metrics: { family: string; encounters: string[]; groups: number; pieces: number; targets: number; certificateShots: number; duration: number; structure: string } — The level's room family and encounters, counts, the verified throw count and its duration.

CorridorOptions

interface CorridorOptions

Options for generateCorridor; each is optional and checked against its bounds.

  • seed?: number — Unsigned 32-bit seed. Default 1.
  • difficulty?: Difficulty — easy, medium, hard or very-hard. Default medium.
  • groups?: number — Rooms, from 1 to 8. Default 2, 3, 4 or 5 by difficulty, plus 1 on an odd seed.
  • pattern?: 'auto' | CorridorFamily — The room family the level opens with (the seed picks one for auto); others are mixed in after it.
  • ammo?: number — Balls at the start, from 1 to 60. Default the rooms plus 3.
  • speed?: number — Travel speed, world units a second, from 0.5 to 4. Default 1.6, 2, 2.5 or 3 by difficulty.

CorridorRoom

interface CorridorRoom

A corridor room's shape, for the presenter; the rules do not read it.

  • kind: string — The structure family of the room.
  • z: number — Where the room starts along the corridor (z), world units.
  • length: number — Length along z, world units.
  • width: number — Width across x, world units.
  • height: number — Ceiling height, world units.

CorridorState

interface CorridorState

The round's state, an owned copy.

  • time: number — Seconds simulated since the round started or was reset.
  • ammo: number — Balls left.
  • shots: number — Balls thrown.
  • score: number — Points: each destroyed piece's material score.
  • progress: number — How far the launcher has travelled along z, world units.
  • destroyed: string[] — Ids of the pieces destroyed, in order.
  • collided: string[] — Ids of the pieces run into.
  • lost: boolean — Out of balls before the end.
  • solved: boolean — The end reached.
  • stars: number — Rating from 1 to 3 once solved, 0 before: three with nothing run into and the balls back to where they began, two with nothing run into, one otherwise.
  • poses: LaunchPose[] — Every body's pose, for the renderer.

GlassCorridorApi

type GlassCorridorApi = typeof kit & { DEFAULT_MATERIALS: typeof DEFAULT_MATERIALS }

game.glassCorridor: the round, its generator and the built-in materials.