playerthree/signals
Team signals: typed requests between teammates of any seat kind (human, agent, policy, bot).
The game declares a closed vocabulary (manifest.signals): signal kinds with typed payloads (enums, numbers,
coordinates, entity ids — never free text) and per-role cards listing what each role answers. Seats emit them as
two reserved intents through the ordinary intent pipeline (signal, signal_update), so every seat kind, every
binding, sequences and replays carry them with no new channel. The host keeps one board per match team and
attaches the seat's slice (signals: {inbox, sent}) to every observation and the team's slice to every team view.
Shapes follow the Agent2Agent (A2A) protocol where it fits a deterministic, team-only, fog-safe match: a signal is
an A2A Task (id, lifecycle state), its payload a structured data part, role cards are Agent Card skills (capability
discovery), and delivery is push (observations, game_wait wakes). Transport, open text parts and auth stay out.
Classes
SignalBoard
Defined in: packages/playerthree/src/signals.ts:344
A match's signal boards, one per team: the deterministic state machine every host loop shares (live matches,
practice, replays, a game's own headless runner). Input is already schema-checked; time is the match tick, never
wall time. limits null: signals are off for this match (every signal intent fails disabled).
Constructors
Constructor
new SignalBoard(
manifest,
teams,
limits
): SignalBoard;Defined in: packages/playerthree/src/signals.ts:354
Parameters
| Parameter | Type |
|---|---|
manifest | AnyManifest |
teams | readonly string[] |
limits | SignalLimits | null |
Returns
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
limits | readonly | SignalLimits | null | packages/playerthree/src/signals.ts:352 |
Methods
advance()
advance(tick): void;Defined in: packages/playerthree/src/signals.ts:494
Tick boundary: open signals past expires expire, closed ones leave after keepTicks. Call before deciding.
Parameters
| Parameter | Type |
|---|---|
tick | number |
Returns
void
apply()
apply(
team,
role,
intent,
tick
): SignalAck;Defined in: packages/playerthree/src/signals.ts:406
Apply one schema-checked signal / signal_update intent from a seat at tick (the tick about to step).
Deterministic: same board, same input, same result.
Parameters
| Parameter | Type |
|---|---|
team | string |
role | string |
intent | object & Record<string, unknown> |
tick | number |
Returns
clone()
clone(): SignalBoard;Defined in: packages/playerthree/src/signals.ts:526
Independent copy (persistent-session checkpoints, replay positions).
Returns
seat()
seat(team, role): SeatSignals;Defined in: packages/playerthree/src/signals.ts:511
One seat's slice (fresh copies). Declined broadcast entries leave the decliner's inbox.
Parameters
| Parameter | Type |
|---|---|
team | string |
role | string |
Returns
team()
team(team): SignalEntry[];Defined in: packages/playerthree/src/signals.ts:521
The team's whole board (fresh copies): its team view member.
Parameters
| Parameter | Type |
|---|---|
team | string |
Returns
version()
version(team, role): number;Defined in: packages/playerthree/src/signals.ts:390
Changes counter of one seat's slice; compare against the last one an agent saw to wake it.
Parameters
| Parameter | Type |
|---|---|
team | string |
role | string |
Returns
number
limitsFor()
static limitsFor(manifest, adapter): SignalLimits | null;Defined in: packages/playerthree/src/signals.ts:364
The limits a match runs with: the manifest's, narrowed by the adapter's per-match signalLimits() (null = off).
Parameters
| Parameter | Type |
|---|---|
manifest | AnyManifest |
adapter | { signalLimits?(): SignalLimits | null; } |
adapter.signalLimits? | () => SignalLimits | null |
Returns
SignalLimits | null
Interfaces
SeatSignals
Defined in: packages/playerthree/src/signals.ts:332
A seat's slice: what it received and what it sent (the signals observation member).
Properties
| Property | Type | Defined in |
|---|---|---|
inbox | SignalEntry[] | packages/playerthree/src/signals.ts:333 |
sent | SignalEntry[] | packages/playerthree/src/signals.ts:334 |
SignalKindDef
Defined in: packages/playerthree/src/signals.ts:58
One signal kind of manifest.signals.kinds: who may send it and its typed payload.
Type Parameters
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
doc | readonly | string | Static developer text for agents (trusted): what the request means and how a responder answers it. | packages/playerthree/src/signals.ts:64 |
params | readonly | P | Typed payload. Closed schema nodes only and no str anywhere: signals carry no text by construction. | packages/playerthree/src/signals.ts:62 |
roles | readonly | readonly string[] | Roles that may send this kind. | packages/playerthree/src/signals.ts:60 |
SignalLimits
Defined in: packages/playerthree/src/signals.ts:83
control.signals: the host rule bounding what one seat can put on its team's board.
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
burst | readonly | number | - | packages/playerthree/src/signals.ts:86 |
keepTicks | readonly | number | A closed signal stays visible this many ticks (so the requester sees how it ended), then leaves the board. | packages/playerthree/src/signals.ts:92 |
maxOpen | readonly | number | Open (submitted/working) signals per sender; also the sender's share of the board. | packages/playerthree/src/signals.ts:88 |
perSecond | readonly | number | New signals per seat per second of game time (token bucket in ticks, so bots and replays agree). | packages/playerthree/src/signals.ts:85 |
ttlTicks | readonly | number | An open signal expires this many ticks after it was sent. | packages/playerthree/src/signals.ts:90 |
SignalSchemas
Defined in: packages/playerthree/src/signals.ts:120
The generated members a game composes into its manifest (signalSchemas).
Type Parameters
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
intents | readonly | object | - | packages/playerthree/src/signals.ts:121 |
intents.signal | readonly | object | - | packages/playerthree/src/signals.ts:122 |
intents.signal.doc | readonly | string | - | packages/playerthree/src/signals.ts:122 |
intents.signal.params | readonly | object | - | packages/playerthree/src/signals.ts:122 |
intents.signal.params.signal | readonly | UnionS<"kind", { [k in string]: K[k]["params"] & SendFields }> | - | packages/playerthree/src/signals.ts:122 |
intents.signal.roles | readonly | readonly string[] | - | packages/playerthree/src/signals.ts:122 |
intents.signal_update | readonly | object | - | packages/playerthree/src/signals.ts:123 |
intents.signal_update.doc | readonly | string | - | packages/playerthree/src/signals.ts:123 |
intents.signal_update.params | readonly | object | - | packages/playerthree/src/signals.ts:123 |
intents.signal_update.params.id | readonly | IdS | - | packages/playerthree/src/signals.ts:123 |
intents.signal_update.params.update | readonly | EnumS<readonly ["ack", "decline", "done", "fail", "cancel"]> | - | packages/playerthree/src/signals.ts:123 |
intents.signal_update.roles | readonly | readonly string[] | - | packages/playerthree/src/signals.ts:123 |
observation | readonly | ObjS<{ inbox: ListS<SignalEntrySchema<R, K>>; sent: ListS<SignalEntrySchema<R, K>>; }> | The signals observation member: this seat's inbox and the signals it sent. | packages/playerthree/src/signals.ts:126 |
view | readonly | ListS<SignalEntrySchema<R, K>> | The signals team-view member: the whole team board (humans, observers). | packages/playerthree/src/signals.ts:128 |
SignalSkill
Defined in: packages/playerthree/src/signals.ts:71
One capability on a role's card (an A2A Agent Card skill): the role answers kind, optionally only for the listed
values of enum params (where: { need: ['scan'] }). Routing checks cards: nobody is asked for what they cannot do.
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
kind | readonly | string | packages/playerthree/src/signals.ts:72 |
where? | readonly | object | packages/playerthree/src/signals.ts:73 |
SignalVocabulary
Defined in: packages/playerthree/src/signals.ts:76
Type Parameters
| Type Parameter | Default type |
|---|---|
K extends Record<string, SignalKindDef> | Record<string, SignalKindDef> |
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
cards | readonly | object | Per role: the signals it answers. Roles without a card answer nothing (they may still send). | packages/playerthree/src/signals.ts:79 |
kinds | readonly | K | - | packages/playerthree/src/signals.ts:77 |
Type Aliases
SignalAck
type SignalAck =
| {
ok: true;
}
| {
code: "rate_limited" | "forbidden_role";
ok: false;
}
| {
code: "signal";
ok: false;
signalCode: SignalCode;
};Defined in: packages/playerthree/src/signals.ts:311
The ack of one signal / signal_update intent.
SignalCode
type SignalCode = typeof SIGNAL_CODES[number];Defined in: packages/playerthree/src/signals.ts:49
SignalEntry
type SignalEntry = object & Record<string, unknown>;Defined in: packages/playerthree/src/signals.ts:299
One entry as seats see it. Payload params sit beside the host members.
Type Declaration
| Name | Type | Defined in |
|---|---|---|
by? | string | packages/playerthree/src/signals.ts:307 |
expires | number | packages/playerthree/src/signals.ts:305 |
from | string | packages/playerthree/src/signals.ts:302 |
id | string | packages/playerthree/src/signals.ts:301 |
kind | string | packages/playerthree/src/signals.ts:300 |
state | SignalState | packages/playerthree/src/signals.ts:306 |
tick | number | packages/playerthree/src/signals.ts:304 |
to | string | packages/playerthree/src/signals.ts:303 |
SignalEntrySchema
type SignalEntrySchema<R, K> = UnionS<"kind", { [k in keyof K & string]: K[k]["params"] & EntryFields<R> }>;Defined in: packages/playerthree/src/signals.ts:117
One board entry as every recipient sees it: the payload plus host-owned lifecycle members.
Type Parameters
SignalState
type SignalState = typeof SIGNAL_STATES[number];Defined in: packages/playerthree/src/signals.ts:37
SignalUpdate
type SignalUpdate = typeof SIGNAL_UPDATES[number];Defined in: packages/playerthree/src/signals.ts:29
Variables
SIGNAL_CODES
const SIGNAL_CODES: readonly ["disabled", "unsupported", "unknown_signal", "not_recipient", "closed", "too_many_open"];Defined in: packages/playerthree/src/signals.ts:48
Closed reasons a signal intent is refused ({ok:false, code:'signal', signalCode}):
disabled: this match has signals off;unsupported: no teammate's card answers this kind/payload at that address (yourself included);unknown_signal: no such signal on your team's board (expired ones leave it afterkeepTicks);not_recipient: you neither sent nor received it, or another teammate already took it;closed: it is already in a terminal state;too_many_open: you already havemaxOpenopen signals.
SIGNAL_ENTRY_FIELDS
const SIGNAL_ENTRY_FIELDS: readonly ["kind", "id", "from", "to", "tick", "expires", "state", "by"];Defined in: packages/playerthree/src/signals.ts:52
Entry members the host owns; signal params must not use these names.
SIGNAL_ID_PREFIX
const SIGNAL_ID_PREFIX: "sg" = 'sg';Defined in: packages/playerthree/src/signals.ts:25
Signal ids are sg_<n>, numbered per team board.
SIGNAL_INTENT
const SIGNAL_INTENT: "signal" = 'signal';Defined in: packages/playerthree/src/signals.ts:18
Reserved intent kinds when manifest.signals is declared.
SIGNAL_LIMIT_BOUNDS
const SIGNAL_LIMIT_BOUNDS: Readonly<Record<keyof SignalLimits, readonly [number, number, boolean]>>;Defined in: packages/playerthree/src/signals.ts:96
Inclusive bounds of each control.signals limit.
SIGNAL_STATES
const SIGNAL_STATES: readonly ["submitted", "working", "completed", "rejected", "failed", "canceled", "expired"];Defined in: packages/playerthree/src/signals.ts:36
A2A TaskState names: submitted (sent, nobody took it), working (acked), then terminal completed (done),
rejected (declined), failed (the responder tried and could not), canceled (by the requester) or expired
(open past its expires tick — the one state A2A lacks: a match clock, not a client, ends unanswered requests).
SIGNAL_TEAM
const SIGNAL_TEAM: "team" = 'team';Defined in: packages/playerthree/src/signals.ts:21
to value addressing every teammate whose card answers the signal.
SIGNAL_UPDATE_INTENT
const SIGNAL_UPDATE_INTENT: "signal_update" = 'signal_update';Defined in: packages/playerthree/src/signals.ts:19
SIGNAL_UPDATES
const SIGNAL_UPDATES: readonly ["ack", "decline", "done", "fail", "cancel"];Defined in: packages/playerthree/src/signals.ts:28
Updates a seat may send: responders ack / decline / done / fail, the requester cancel.
SIGNALS_FIELD
const SIGNALS_FIELD: "signals" = 'signals';Defined in: packages/playerthree/src/signals.ts:23
The reserved top-level observation/view member.
Functions
checkSignals()
function checkSignals(
m,
fail,
checkFields
): void;Defined in: packages/playerthree/src/signals.ts:220
Structural checks of manifest.signals and the generated members it requires. fail(path, why) throws.
checkFields is the manifest's own field-map check (closed nodes, field names).
Parameters
| Parameter | Type |
|---|---|
m | AnyManifest |
fail | (path, why) => never |
checkFields | (path, fields) => void |
Returns
void
emptySeatSignals()
function emptySeatSignals(): SeatSignals;Defined in: packages/playerthree/src/signals.ts:557
Empty slice for observations taken outside a match board (deploy probes, lint).
Returns
isSignalIntent()
function isSignalIntent(m, intent): boolean;Defined in: packages/playerthree/src/signals.ts:547
Is this checked intent one of the reserved signal intents of a manifest that declares signals?
Parameters
| Parameter | Type |
|---|---|
m | AnyManifest |
intent | { kind: string; } |
intent.kind | string |
Returns
boolean
signalSchemas()
function signalSchemas<R, K>(
roles,
vocab,
limits
): SignalSchemas<R, K>;Defined in: packages/playerthree/src/signals.ts:141
The reserved intents and the signals observation/view members for a vocabulary. A game spreads intents into its
intent map and adds observation / view as the signals member of its observation and view objects; the host
fills that member (a game's observe / view leave it out). defineManifest checks they match exactly.
Type Parameters
Parameters
| Parameter | Type |
|---|---|
roles | R |
vocab | SignalVocabulary<K> |
limits | SignalLimits |
Returns
SignalSchemas<R, K>
withSignals()
function withSignals(raw, signals): unknown;Defined in: packages/playerthree/src/signals.ts:552
Attach a seat's slice to a game observation (the game leaves signals out; the host owns it).
Parameters
| Parameter | Type |
|---|---|
raw | unknown |
signals | SeatSignals | SignalEntry[] |
Returns
unknown
