Phaser AE

Worker jobs

Pro packv3.0.0-42DLogic

Work yards for games about people who fetch, make and haul. Workers walk to a store for the inputs, work them at a site and carry the outputs on, and the yard makes sure nobody sets off for something another worker has already claimed.

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

Released October 14, 2026 · updated October 19, 2026

Worker jobs: 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

jobs

function jobs(): Pack<{ jobs: JobsApi }>

Work yards: workers who haul, work and deliver repeatable jobs, with reservations, roles, skills and tools.

Helpers

createForeman

function createForeman(yard: Yard, options: ForemanOptions = {}): Foreman

A foreman for a yard.

createYard

function createYard(def: YardDef): Yard

Open a yard. Throws, with every fault, on a yard validateYard refuses.

greystoneYard

function greystoneYard(options: { workers?: number; blocks?: number; bricks?: number; deadline?: number } = {}): YardDef

Greystone: quarry stone and cut it into blocks on the west bank; dig clay, fell wood and fire bricks on the east; load both onto the barge downstream, over the one bridge. Masons cut faster, porters carry more and walk faster, and only masons cut stone.

mark

function mark(map: readonly string[], ch: string): [number, number]

The first cell holding a character on a map. Throws if there is none.

oakshieldYard

function oakshieldYard(options: { workers?: number; planks?: number; tools?: number; deadline?: number } = {}): YardDef

Oakshield: fell timber, saw planks, mine and smelt ore, forge tools, and load the wagon with an order of planks and tools. Workers do every job at normal pace; one saw and one hammer are shared.

planPriorities

function planPriorities(yard: Yard, wants: Stock): Record<string, number>

The priorities that wants call for, by job.

validateYard

function validateYard(def: YardDef): string[]

Check a yard. Every fault, or empty when it can be run.

Constants

YARD_TICK

const YARD_TICK: number

Seconds a fixed step lasts.

Types

Foreman

interface Foreman

A foreman.

  • act(dt: number): void — Run on by dt seconds; every every seconds the priorities are set again.
  • plan(): Record<string, number> — The priorities the wants call for now, by job.

ForemanOptions

interface ForemanOptions

How a foreman decides.

  • every?: number — Seconds between plans. Default 1.
  • wants?: () => Stock — Want levels by item, asked for at each plan. Default: 3 for what the yard's goal store is short of, 0 for what it has enough of.

JobsApi

interface JobsApi

What the pack adds to the game as game.jobs.

  • create(def: YardDef): Yard — Open a yard.
  • validate(def: YardDef): string[] — Check a yard: every fault, or empty.
  • foreman(yard: Yard, options?: ForemanOptions): Foreman — A foreman who sets a yard's priorities from what is wanted.
  • plan: typeof planPriorities — The priorities wants call for.
  • presets: { oakshield: typeof oakshieldYard; greystone: typeof greystoneYard } — The yard presets.
  • mark: typeof mark — Find a letter on a map.
  • tick: number — Seconds a fixed step lasts.

Stock

type Stock = Record<string, number>

Named whole quantities.

Task

interface Task

What a worker is doing: on the way to pick up, on the way to the site, working, on the way to deliver, or putting things back after being called away.

  • job: string — Id of the job.
  • phase: 'pickup' | 'site' | 'work' | 'deliver' | 'return' — Which stage they are at: going to pick up, going to the site, working, going to deliver, or putting things back.
  • cargo: Stock — What they carry.
  • elapsed: number — Seconds of work done, at their skill.
  • made: boolean — Whether the outputs have been made.
  • back: string | null — Where, when returning, the cargo goes.

WorkerState

interface WorkerState

A worker as they are.

  • id: string — The worker's id.
  • name: string — Display name: the worker's name, else its id.
  • x: number — Where they are, in cells (a cell's centre is at its index plus a half).
  • y: number — Vertical position in cells, in the same units as x.
  • role: string — The role they take jobs in: 'any', 'rest' or a job's role.
  • ready: boolean — Whether they take work.
  • reason: string — Why they are not working, or ''.
  • task: Task | null — What they are doing now, or null when idle.
  • route: { to: [number, number]; points: { x: number; y: number }[]; i: number } | null — The walk in progress, or null: the cell they are heading for, the points to walk through (cell centres) and the index of the next point.

Yard

interface Yard

A yard.

  • readonly def: YardDef — The definition the yard was opened with; workers hired since are not in it.
  • readonly state: YardState — The live state; change it only through the yard's methods.
  • readonly width: number — Columns of cells in the map.
  • readonly height: number — Rows of cells in the map.
  • readonly tick: number — Seconds a fixed step lasts.
  • walkable(x: number, y: number): boolean — Whether a cell can be walked.
  • role(worker: string, role: string): string | null — Set a worker's role; one on a job of another role is called off it.
  • priority(job: string, priority: number): string | null — Set a job's priority (a whole number; 0 pauses it).
  • cancel(worker: string): string | null — Call a worker away from their task: what they carry goes back where it belongs.
  • ready(worker: string, ready: boolean, reason?: string): string | null — Let a worker take work, or stand them down with a reason (calling off their task).
  • consume(store: string, stock: Stock): string | null — Take stock out of a store, if it is there and not reserved.
  • give(store: string, stock: Stock): string | null — Put stock into a store, if there is room.
  • hire(worker: YardWorker): string | null — A new worker.
  • dismiss(worker: string): string | null — A worker leaves; what they carry is put straight back.
  • whyNot(job: string, worker?: string): string — Why nobody takes a job just now ('' if somebody could). With a worker, why that worker cannot.
  • reserved(store: string, item: string): number — Inputs held in a store for pickups under way.
  • room(store: string): number — The room in a store, less what is promised to it.
  • route(from: [number, number], to: [number, number]): { x: number; y: number }[] — A walking route between cells as points (cell centres are at index plus a half); empty if there is none.
  • step(dt: number): void — Run on by dt seconds, in fixed steps.
  • drain(): YardEvent[] — What has happened since the last drain (the latest 512).
  • snapshot(): YardSave — A plain copy of the whole yard, to save as JSON.
  • restore(save: YardSave): void — Replace the yard's state with a snapshot's, taken from a yard opened with the same definition. Pending events are dropped.

YardDef

interface YardDef

A yard: its map, a row of characters per row of cells (the blocked characters cannot be walked), its stores, workers, jobs and tools, and what it must deliver to be won.

  • map: string[] — Rows of characters, one per row of cells and all the same length; a character in blocked cannot be walked.
  • blocked?: string — The characters that cannot be walked. Default '#~^T'.
  • stores: YardStore[] — The stores.
  • workers: YardWorker[] — The workers at the start; more can be hired later.
  • jobs: YardJob[] — The jobs on offer.
  • tools?: Stock — How many of each tool there are.
  • goal?: { store: string; stock: Stock } — Won once this store holds this stock.
  • deadline?: number — Lost if the goal is not met within this many seconds. Default no limit.

YardEvent

type YardEvent = | { kind: 'assign'; worker: string; job: string } | { kind: 'pickup'; worker: string; job: string } | { kind: 'made'; worker: string; job: string } | { kind: 'deliver'; worker: string; job: string; outputs: Stock } | { kind: 'cancel'; worker: string; job: string } | { kind: 'returned'; worker: string } | { kind: 'hire'; worker: string } | { kind: 'leave'; worker: string } | { kind: 'won' } | { kind: 'lost' }

Something that happened.

YardJob

interface YardJob

A job, repeated for as long as it can be: take inputs from from, work them at at for time seconds (divided by the worker's skill), and carry outputs to to. A job with no inputs goes straight to its site.

  • id: string — Unique id among the jobs; priorities and whyNot name jobs by it.
  • name?: string — Display name for the presenter; the rules never read it.
  • role: string — The role it belongs to.
  • skill?: string — The skill it needs. Default the role.
  • from?: string — The store its inputs come from; needed when it has inputs.
  • at: [number, number] — The cell it is worked on.
  • to: string — The store its outputs are carried to.
  • inputs?: Stock — What it takes from from, whole numbers by item. Default none.
  • outputs: Stock — What it makes and carries to to, whole numbers by item; it must make something.
  • time: number — Seconds of work at normal skill (1), above 0; a worker with skill 2 takes half as long.
  • tool?: string — A shared tool it needs while it is worked.
  • priority?: number — 0 pauses it; higher comes first. Default 1.
  • goal?: number — No more once to holds this many of each output, counting what is on its way. Default no limit.
  • capacity?: number — Workers at its site at once. Default 1.

YardSave

interface YardSave

A yard saved as plain JSON.

  • state: YardState — The state at the moment of saving.
  • carry: number — Seconds of run time not yet spent in a fixed step.
  • hired: YardWorker[] — Workers hired since the yard opened.

YardState

interface YardState

Where the yard stands. Plain JSON.

  • ticks: number — Fixed steps run.
  • time: number — Seconds run.
  • stores: Record<string, Stock> — What each store holds.
  • workers: WorkerState[] — Every worker in the yard now.
  • priorities: Record<string, number> — Each job's priority by job id: 0 pauses it, higher comes first.
  • delivered: Stock — Everything delivered so far.
  • won: boolean — Whether the goal has been met.
  • lost: boolean — The deadline passed with the goal not met.

YardStore

interface YardStore

A store: where things are kept, on which cell, and how many things it holds in all.

  • id: string — Unique id among the stores; jobs name stores by it.
  • name?: string — Display name for the presenter; the rules never read it.
  • at: [number, number] — The cell it stands on, as [column, row]; must be open ground.
  • capacity: number — Most things it can hold in all, a whole number of 0 or more.
  • stock?: Stock — What it holds at the start, whole numbers by item; default empty. Its total may not exceed capacity.

YardWorker

interface YardWorker

A worker.

  • id: string — Unique id among the workers.
  • name?: string — Display name; default the id.
  • at: [number, number] — The cell they start on.
  • skills?: Stock — How well they do each skill: 1 is normal pace, 2 twice as fast, 0 or missing not at all. Without skills they do every job at normal pace.
  • speed?: number — Cells a second. Default 2.5.
  • carry?: number — How many things they carry at once. Default 4.
  • role?: string — The role they take jobs in: 'any' (the default) takes every job, 'rest' none, and a job's role only those.