Phaser AE

Table-service floor

Pro packv3.0.0-52DLogic

The rules of a restaurant time-management game, in the style of Diner Dash. You seat the parties and queue the work; a server walks the floor on real routes and does it, two hands at a time, and repeating the same task earns a combo.

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

Released October 14, 2026 · updated October 20, 2026

Table-service floor: 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

walkServe

function walkServe(): Pack<{ walkServe: WalkServeApi }>

The walk-serve pack: game.walkServe, Diner Dash's rules. No options.

Helpers

createDiner

function createDiner(options: DinerOptions = {}): Diner

Open a diner. Throws, with every fault, on options validateDiner refuses.

createDinerAutopilot

function createDinerAutopilot(diner: Diner): DinerAutopilot

The diner's autopilot.

dinerFloor

const dinerFloor: string[]

The built-in floor: # wall, . floor, a digit a table with that many seats, K the kitchen window, B the bus tub, P the podium where the queue waits, S where the server starts.

readFloor

function readFloor(plan: string[]): DinerFloor | string

Read a floor plan.

validateDiner

function validateDiner(options: DinerOptions = {}): string[]

Check a diner's options. Empty when it can be played.

Types

Diner

interface Diner

A diner.

  • readonly state: DinerState — The live server, task list, kitchen queue and combo; read it freely, but change it only through the methods.
  • readonly service: Service — The guests' shift (the customers pack): parties, patience and money.
  • readonly floor: DinerFloor — The parsed floor plan.
  • readonly options: Readonly<{ hands: number; tasks: number; speed: number }> — The settings in force: hands carried, longest task list, and walking speed in cells a second.
  • seat(party: string, table: string): Refusal — Seat a waiting party at a table, at once.
  • queue(task: Task): Refusal — Add a task to the end of the server's list.
  • partyAt(table: string): ServiceState['parties'][number] | undefined — The party at a table.
  • step(dt: number): void — Advances the diner and the shift by dt seconds in fixed 1/60 s ticks, counting at most 0.25 s per call; does nothing once the shift is over. Throws if dt is negative or not a number.
  • drain(): DinerEvent[] — Returns and clears the events since the last drain; only the latest 512 are kept.
  • snapshot(): DinerSave — Saves the whole diner and its shift as plain JSON (a deep copy).
  • restore(save: DinerSave): void — Loads a save made by snapshot, replacing the diner and shift and discarding undrained events.

DinerAutopilot

interface DinerAutopilot

A player that runs a diner.

  • act(): Task | null — Seat parties and, when the server's list is empty, give it the next task.

DinerEvent

type DinerEvent = { kind: 'arrived'; task: Task['kind'] } | { kind: 'skip'; task: Task['kind']; why: string } | { kind: 'combo'; count: number; bonus: number } | { kind: 'cooked'; party: string } | ServiceEvent

Something that happened in the diner, or with the guests.

DinerFloor

interface DinerFloor

The floor's fixed parts.

  • cols: number — Width of the plan in cells.
  • rows: number — Height of the plan in cells.
  • tables: { id: string; col: number; row: number; seats: number }[] — The tables in reading order (top to bottom, left to right): id (t1, t2...), cell and seat count.
  • kitchen: { col: number; row: number } — Cell of the kitchen window (K).
  • bus: { col: number; row: number } — Cell of the bus tub (B).
  • podium: { col: number; row: number } — Cell of the podium (P) where the queue waits.
  • walls: { col: number; row: number }[] — Cells that are wall (#).

DinerOptions

interface DinerOptions

A diner's options.

  • seed?: number — Default 1.
  • floor?: string[] — The floor plan. Default dinerFloor.
  • speed?: number — Cells a second the server walks; seconds a task takes once there. Default 4 and 0.35.
  • act?: number — Seconds a task takes once the server is at it. Default 0.35.
  • cook?: number — Seconds a ticket cooks, and more for each item on it. Default 3 and 0.8.
  • perItem?: number — Extra seconds a ticket cooks for each item on it. Default 0.8.
  • hands?: number — Hands. Default 2.
  • tasks?: number — The most tasks waiting. Default 8.
  • combo?: number — Bonus for each task in a combo of the same task. Default 5.
  • service?: Omit<ServiceOptions, 'places' | 'flow' | 'seed'> — The guests' shift (kinds, menu, arrivals, duration, goal...): the places are the floor's tables.

DinerSave

interface DinerSave

A diner saved as plain JSON.

  • diner: DinerState — The server, tasks, kitchen queue and combo.
  • service: ServiceSave — The guests' shift, as saved by the customers pack.
  • carry: number — Seconds of step time not yet spent, under one 1/60 s tick.

DinerState

interface DinerState

Where the diner stands.

  • server: Server — The server's position, route, current task and load.
  • tasks: Task[] — Tasks waiting, in order, not counting the one in progress; at most options.tasks.
  • cooking: { party: string; items: string[]; t: number; time: number }[] — Tickets cooking, and food cooked waiting at the window.
  • ready: { party: string; items: string[] }[] — Food cooked and waiting at the kitchen window for a pickup task.
  • combo: { kind: Task['kind'] | null; count: number } — The combo running: its task, length and the bonus so far.
  • bonus: number — Combo points earned so far; kept apart from the shift's money.

Hand

type Hand = { kind: 'food'; party: string; items: string[] } | { kind: 'dishes'; table: string }

What the server carries in a hand: a table's food, or its dirty dishes.

Server

interface Server

The server.

  • x: number — Horizontal position in floor cells, fractional; a cell's centre is its column plus 0.5.
  • y: number — Vertical position in floor cells, fractional; a cell's centre is its row plus 0.5.
  • path: { x: number; y: number }[] — Waypoints still to walk to, in floor cells, nearest first; empty when not walking.
  • task: Task | null — The task being walked to or done, or null when idle.
  • busy: number — Seconds left on the task being done, once the server has reached it; 0 while walking.
  • hands: Hand[] — What is being carried, at most options.hands items.
  • tickets: string[] — Ids of the parties whose orders have been taken but not yet dropped at the kitchen.

Task

type Task = | { kind: 'order'; table: string } | { kind: 'drop' } | { kind: 'pickup'; party: string } | { kind: 'deliver'; table: string } | { kind: 'check'; table: string } | { kind: 'clear'; table: string } | { kind: 'bus' }

Something to do. Tables are by id (t1, t2... in reading order).

WalkServeApi

interface WalkServeApi

What the walk-serve pack adds to a game: game.walkServe.

  • create: typeof createDiner — Open a diner.
  • validate: typeof validateDiner — Check a diner's options.
  • floor: typeof dinerFloor — The built-in floor plan.
  • autopilot: typeof createDinerAutopilot — A player for an attract mode or a test.