What it does
A level is a set of items, each with a key and a position, and a tray with room for seven by default. An item can be picked only when nothing lies on it. In layered mode a higher tile's footprint covers a lower one; in pile mode objects carry 3D bounds and an object is blocked by any higher one overlapping it; explicit mode uses only blockers you name. A picked item joins its identical keys in the tray, and a group of three, or the match size you set, clears at once, even into the last free slot. A tray that fills with unfinished groups rejects further picks, and the level is lost. Picked items have left the board, so they stop covering anything beneath.
Every pick can be previewed before it is made, and apply returns its events, selected and then perhaps matched,
for your presenter to animate. Levels can require every item cleared, or only quotas of chosen keys, and a move limit
is optional. solve gives a proven next move within a budget, and reshuffle reassigns the remaining keys along a
fresh winning route, keeping the geometry, the tray and the quotas already met, as one undoable move.
The generator is the reason to use the pack. It lays out tiles in one of sixteen silhouettes, from an X and a cross to a heart, a star and a seeded procedural shape, or piles objects as a heap, two heaps, a crescent or a scatter. It builds a route that keeps the tray under planned pressure, assigns keys to items that are genuinely reachable, and replays the route. Then it screens candidates with three matching strategies, match-first, exposed-group-first and unlock-first, over 24 seeded trials, and keeps a level the bots clear no more often than the target, so "hard" means simple play usually fails.
Features
- Tray rules — capacity, match size, grouping of identical keys, immediate clears and loss on a full tray.
- Three accessibility models — overlapping tile footprints, 3D bounds for object piles, or explicit blockers.
- Quotas and move limits — clear chosen keys a set number of times, or everything, within an optional limit.
- Safe reshuffle — keys reassigned along a validated winning route, undoable, with geometry and progress kept.
- Hints with honest answers —
solvereturns a proven continuation,unsolvableorbudget-exhausted. - Sixteen tile silhouettes — chosen by name or rotated through by level number, with a period you set.
- Procedural and authored masks — seeded shapes on an 8 or 10 cell grid with symmetry, rotation and mirroring, or
a surface you draw in rows of
Xand., or a complete layer-by-layer blueprint. - Object piles — heap, two heaps, crescent and scatter, with spacing and interlock controls, or classic stacks.
- Screened difficulty — four presets from easy to very hard, a target bot win rate and a candidate budget, with
analyzeTrayMatchto measure any level. - Undo, redo and reset — whole states, including key assignments, tray order and reshuffles.
Good for
- Triple-tile garden puzzles in the style of Tile Busters or Triple Tile, with layered tiles in shaped boards.
- 3D object-match games in the style of Match Factory, where a pile of objects is cleared into a tray.
- Mobile puzzle sagas that need many seeded levels with a difficulty curve that is measured.
- Quota challenges, such as clearing four groups of strawberries before the moves run out.
- Hand-designed showpiece levels, drawn as a mask while the pack supplies the keys, screening and solution.
- Daily levels, where a seed and a level index reproduce the same board for every player.
Make it yours
An authored level is a TrayConfig: up to 120 items with ids, keys and positions, the board size, the mode, the
tray capacity, the match size, explicit blockers, quotas and a move limit.
The generator takes a seed, a mode and a difficulty, then lets you override almost everything: the number of groups
and distinct kinds, the layers, the tray capacity and match size, the planned pressure on the tray, how many tiles
start exposed, the interlock between layers, the layout and its progression by level, the mask grid, symmetry,
rotation and mirroring, the pile spread, the target bot win rate and the candidate budget. The returned parameters
reproduce the exact level.
Three materially different setups:
- A relaxed layered board: the easy preset's 16 groups of four kinds on two layers, in a heart silhouette.
- A tense 3D pile: the very-hard object pile, 72 objects of 24 kinds, on a crescent footprint.
- A designer's level: your own surface mask in the shape of a letter, with the pack generating the layers below, the keys, the screening and a certificate.
A quick look
Generate a hard object pile and play the hinted move:
import { createTrayMatch, generateTrayMatch } from '@phaser-ae/tray-match';
const level = generateTrayMatch({ seed: 12345, difficulty: 'hard', mode: 'pile' });
const puzzle = createTrayMatch(level.config, level.solution);
const action = puzzle.solve(12000).actions[0];
if (action && puzzle.preview(action).valid) {
const result = puzzle.apply(action);
for (const e of result.events) present(e); // selected, then perhaps matched
}
if (puzzle.lost) offerUndoOrReshuffle();
Works with
tile-pairs— for removing matching pairs directly, as in mahjong solitaire, with no tray.match3— for swapping neighbours to make lines.shelf-sort— for sorting goods between shelves rather than collecting them into one tray.world-3d,render-3dandgeometry-3d— to present tiles or object piles in 3D.
Good to know
- A level holds at most 120 items, and generated tile masks at most three layers.
- Screening measures three simple strategies, not human success; a player who plans ahead can beat a "very hard" rating, and a reshuffled table is safe but makes no promise about the original difficulty.
- Pile accessibility is a bounds test, not a physics simulation or a rotated-mesh test; supply accurate bounds or explicit blockers for imported models, and keep any settling animation true to the rule layout.
- A camera angle can hide an object that the rules say is free, so offer rotation or an overhead view.
- Search, generation and reshuffling are synchronous; move large authored searches to a worker.






