The pack
riseStack
function riseStack(): Pack<{ riseStack: RiseStackApi }>
The rise-stack pack. Pure logic, so it needs no backend and runs headless.
Helpers
createRiseStack
function createRiseStack(cfg: RiseConfig = {}): RiseStack
Creates a rising stack.
riseVersusBoard
function riseVersusBoard(stack: RiseStack): RiseVersusBoard
Wrap a stack for versus-garbage's createVersusMatch.
TETRIS_ATTACK_TABLES
const TETRIS_ATTACK_TABLES: RiseTables
Tetris Attack's score and garbage tables as fans have documented them (combo bonus 20 at 4 panels up to 410 at 13; chain bonus 50 at ×2 up to 1800 at ×13; a 4-combo sends a 3-wide block, a 7-combo a 6-wide one, larger combos two or three blocks). The stop times are estimates.
Classes
RiseStack
class RiseStack
A Panel de Pon stack. Call step(input) once per 60 Hz frame.
readonly cols: number— Columns.readonly rows: number— Rows.readonly colors: number— Panel colours.readonly timings: RiseTimings— Phase timings in force.readonly tables: RiseTables— Tables in force.riseSpeed: number— Rows a second the stack rises on its own; change it to speed the game up.raiseSpeed: number— Rows a second while raising.readonly grace: number— Frames of grace against the top.score: number— Score.chain: number— The chain the board is on: 1 when no chain is running.stop: number— Frames of stop time left: the stack does not rise.progress: number— How far (0 to 1) the next row has risen into view.danger: number— Frames of grace used against the top.topOut: boolean— True once the stack has topped out.cursor: XY— The cursor: its left cell.preview: number[]— Colours of the row rising into view beneath the stack.frame: number— Frames stepped.constructor(cfg: RiseConfig = {})panel(x: number, y: number): PanelView | null— The panel or garbage cell at (x, y), or null.garbage(): GarbageView[]— Every garbage block on the board.get pendingGarbage(): number— Garbage cells waiting to drop.get busy(): boolean— Whether anything is clearing, hovering or falling.swap(x: number, y: number): boolean— Swap the cells at (x, y) and (x + 1, y) now, as a pointer or a script would. False if the swap is not allowed.dropGarbage(w: number, h = 1): void— Queue a garbage block to drop at the top:wcolumns (from the left edge, alternating sides) byhrows.cancelGarbage(cells: number): number— Cancel up tocellsof queued garbage, newest first. Returns how many cells were cancelled.findSwaps(): XY[]— Swaps that would make a match at once, for hints and simple AI: the left cell of each.step(input: RiseInput = {}): RiseEvent[]— Advance one 60 Hz frame with this input. Returns what happened since the last step, in order (aswapmade between steps included).snapshot(): RiseSnapshot— The whole state as plain data.restore(snap: RiseSnapshot): void— Return to asnapshot()of a stack with the same size and rules.debugGrid(): string— The board as text, for tests:.empty,Ggarbage,*clearing, a colour digit otherwise.
RiseVersusBoard
class RiseVersusBoard implements VersusBoard<RiseInput>
A RiseStack as a VersusBoard.
readonly kind: "rise-stack"— Board family.constructor(readonly stack: RiseStack)step(input: RiseInput): void— One 60 Hz frame.take(): VersusBoardEvent[]— Events since the last call.receive(amount: number): void— Garbage arrives as full-width rows, then one block of what is left (at least 3 wide).offset(amount: number): number— Cancel queued garbage.get pending(): number— Garbage cells queued and not yet dropped.get lost(): boolean— Topped out.get score(): number— Score.snapshot(): { stack: RiseSnapshot; resolving: boolean }— Plain data.restore(snap: unknown): void— Restore asnapshot().
Types
GarbageView
interface GarbageView
A garbage block, as a renderer reads it.
id: number— Block id.x: number— Left column.y: number— Top row.w: number— Width in columns.h: number— Height in rows.state: 'idle' | 'fall' | 'clear'—idle,fall, orclearwhile it flashes before its bottom row turns into panels.
PanelState
type PanelState = 'idle' | 'swap' | 'hover' | 'fall' | 'clear' | 'popped'
A panel's phase.
PanelView
interface PanelView
A panel, as a renderer reads it.
id: number— Stable id for the panel's life (a garbage cell's id is its block's).color: number— Colour index, or -1 for garbage.state: PanelState— Its phase. Aclearpanel is flashing or waiting to pop; apoppedone is an empty-looking gap still holding up what stands on it.timer: number— Frames left in the phase.chain: boolean— Carries the chain flag: it fell because of a clear.flashing?: boolean— Aclearpanel still in its flash (before it shows its face).garbage?: number— The garbage block this cell belongs to, if any.
RiseConfig
interface RiseConfig
Configures createRiseStack.
cols?: number— Columns. Default 6.rows?: number— Rows. Default 12.colors?: number— Panel colours, 3 to 8. Default 5.seed?: number— Seed for the panels. Default 1.fillRows?: number— Rows filled at the start (a clean deal: no matches). Default 6. Ignored withlayout.layout?: readonly string[]— A starting board instead of a deal, for puzzles and tests: rows of text, top to bottom,.for empty and a digit for a colour. Fewer rows than the stack sit at its bottom. Panels left floating fall on the first frames.riseSpeed?: number— Rows a second the stack rises on its own. Default 0.25.raiseSpeed?: number— Rows a second while the raise button is held. Default 8.grace?: number— Frames the stack may press against the top before the game is lost. Default 60.timings?: Partial<RiseTimings>— Phase timings.tables?: Partial<RiseTables>— Score, stop-time and garbage tables. DefaultTETRIS_ATTACK_TABLES.
RiseEvent
type RiseEvent = | { type: 'rise' } | { type: 'swap'; at: XY } | { type: 'match'; cells: XY[]; combo: number; chain: number; points: number } | { type: 'pop'; at: XY; id: number } | { type: 'land'; ids: number[] } | { type: 'chainEnd'; chain: number } | { type: 'attack'; garbage: { w: number; h: number }[]; combo: number; chain: number } | { type: 'garbageDrop'; id: number; at: XY; w: number; h: number } | { type: 'garbageBreak'; id: number; panels: XY[] } | { type: 'danger'; frames: number } | { type: 'topOut' }
One thing that happened in a frame, in order.
RiseInput
interface RiseInput
What a frame's input does. Movement and swap are presses (one action each); raise is held.
up?: boolean— Move the cursor up a row.down?: boolean— Move the cursor down a row.left?: boolean— Move the cursor left a column.right?: boolean— Move the cursor right a column.swap?: boolean— Swap the two cells under the cursor.raise?: boolean— Raise the stack quickly while held.
RiseSnapshot
interface RiseSnapshot
The plain-data state of a stack, from snapshot().
grid: (Cell | null)[]— Grid cells, row by row (null for empty).blocks: Block[]— Garbage blocks on the board.queue: { w: number; h: number }[]— Garbage waiting to drop.groups: { cells: number[]; timer: number; pops: number; total: number }[]— Clearing groups, as indices intogrid.s: { score: number; chain: number; stop: number; progress: number; danger: number; topOut: boolean; cursor: XY; preview: number[]; nextId: number; drops: number; frame: number; rng: RngState }— The other scalar state.
RiseStackApi
type RiseStackApi = typeof api
game.riseStack — every function and class this pack carries, as one namespace.
RiseTables
interface RiseTables
The scoring and attack tables. Index n of a table is the value for n; past the end, the last entry holds.
panel: number— Points per panel cleared. Default 10.comboBonus: readonly number[]— Bonus for a combo of n panels (n ≥ 4), from index 4.chainBonus: readonly number[]— Bonus for a chain link of length n (n ≥ 2), from index 2.comboGarbage: readonly (readonly number[])[]— Garbage widths a combo of n panels sends, from index 4.comboStop: readonly number[]— Frames of stop time for a combo of n panels, from index 4.chainStop: readonly number[]— Frames of stop time for a chain link of length n, from index 2.
RiseTimings
interface RiseTimings
Frame counts (60 Hz) for each phase of a panel's life.
swap: number— A swap's slide. Default 4.flash: number— A match flashes for this long. Default 44.face: number— Then shows its face for this long before the first panel pops. Default 15.pop: number— Then one panel pops every this many frames. Default 9.hover: number— A panel that has lost its support hangs this long before it falls. Default 12.fall: number— A falling panel or block drops one row every this many frames. Default 1.
XY
interface XY
A cell position: column x from the left, row y from the top.
x: number— Column, from 0 at the left.y: number— Row, from 0 at the top.


