Skip to content

Playcade.game()

View as Markdown

Playcade.game(definition) registers a game. The definition is one object, and only id, title, inputs and round are required.

Field Type What it does
id string kebab-case, unique in the gallery
title string The name on stream and in the gallery
tagline string, optional One sentence for the gallery card
inputs ('guess' | 'vote' | 'team')[] How players answer. The first one sets the "how to play" line
players string, optional Shown in the gallery. "1+" means fun with a single player
rounds number, optional Default 5, capped by how many questions there are. Infinity runs the game until the host presses End, for long and idle games
roundLabel(index, total) function, optional The round chip and scores card, like () => 'Puzzle #47'. Default "Round 2 of 5"
content Item[], optional The built-in questions, one per round: the game's free starter set. A host's question set replaces them
item object, optional What one question looks like, field by field. Question sets are checked against it
checkItem(item) function, optional Rules across fields, after item passed. Return a problem as a string, or null
sets boolean, optional false when the game takes no question set, like a daily puzzle everyone plays the same
saves boolean, optional true keeps progress between streams with load() and save() in the round. The host keeps it per show
layout 'wide' | 'tall', optional 'tall' gives the game most of the stage (1792 by 690, no hint row), for maps, boards and long games. Default 'wide'
round(ctx) async function One round. Resolve when the round is over
Playcade.game({
id: 'higher-or-lower',
title: 'Higher or Lower',
tagline: 'Two things, one question. Vote 1 or 2.',
inputs: ['vote'],
players: '1+',
rounds: 5,
content: PAIRS,
item: {
q: { type: 'text', label: 'The question, like "Which is older?"', max: 60 },
a: { type: 'list', label: 'First choice and its reveal line', min: 2, max: 2, each: 40 },
b: { type: 'list', label: 'Second choice and its reveal line', min: 2, max: 2, each: 40 },
answer: { type: 'number', label: 'The right choice: 0 or 1', options: [0, 1] },
},
async round(ctx) { /* see The round */ },
})

A host can play their own questions instead of a game's built-in ones. A question set is a list of questions, or { title, maker, items }. The maker is a handle like "@quizlab" and is credited as "set by @quizlab" on the lobby and reveal cards. A set only swaps questions: it can never change scoring, rounds or timing. Any question may also carry an id (a stable key) and a source (an https link that backs the answer).

Each question is checked against the game's item description before it plays, and a question that fails is skipped with a reason. Fields are one of these types:

Type Options A valid value
text max length (default 120), options Text without <, > or control characters. It goes through the safety filter
number min, max, options A number
list min and max items, each length (default 60) A list of text
map keys, min, each Text by key, like { "1": "ice cube" }
image An https link or an image data URL
object fields An object, checked field by field
any Anything. checkItem looks at it

Every field also takes a label, written for the host who fills it in, and optional: true. Optional fields default to '', [] or {}. A show never repeats itself: questions it has not played yet go first, then the ones played longest ago.

Call Returns
Playcade.match(text, answers) { ok, close }: the loose matcher, outside a round
Playcade.asset(path) A URL for a file in the game's own folder
Playcade.checkContent(gameId, set) { ok, items, problems, notes, title, maker, paid }: a question set checked against a game, before anyone plays it
Playcade.itemKey(item) A question's key: its id, or a hash of the question. A show stores the keys it played