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
ParameterType
manifestAnyManifest
teamsreadonly string[]
limitsSignalLimits | null
Returns

SignalBoard

Properties

PropertyModifierTypeDefined in
limitsreadonlySignalLimits | nullpackages/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
ParameterType
ticknumber
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
ParameterType
teamstring
rolestring
intentobject & Record<string, unknown>
ticknumber
Returns

SignalAck

clone()
clone(): SignalBoard;

Defined in: packages/playerthree/src/signals.ts:526

Independent copy (persistent-session checkpoints, replay positions).

Returns

SignalBoard

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
ParameterType
teamstring
rolestring
Returns

SeatSignals

team()
team(team): SignalEntry[];

Defined in: packages/playerthree/src/signals.ts:521

The team's whole board (fresh copies): its team view member.

Parameters
ParameterType
teamstring
Returns

SignalEntry[]

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
ParameterType
teamstring
rolestring
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
ParameterType
manifestAnyManifest
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


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

Type ParameterDefault type
P extends FieldsFields

Properties

PropertyModifierTypeDescriptionDefined in
docreadonlystringStatic developer text for agents (trusted): what the request means and how a responder answers it.packages/playerthree/src/signals.ts:64
paramsreadonlyPTyped payload. Closed schema nodes only and no str anywhere: signals carry no text by construction.packages/playerthree/src/signals.ts:62
rolesreadonlyreadonly 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

PropertyModifierTypeDescriptionDefined in
burstreadonlynumber-packages/playerthree/src/signals.ts:86
keepTicksreadonlynumberA closed signal stays visible this many ticks (so the requester sees how it ended), then leaves the board.packages/playerthree/src/signals.ts:92
maxOpenreadonlynumberOpen (submitted/working) signals per sender; also the sender's share of the board.packages/playerthree/src/signals.ts:88
perSecondreadonlynumberNew signals per seat per second of game time (token bucket in ticks, so bots and replays agree).packages/playerthree/src/signals.ts:85
ttlTicksreadonlynumberAn 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

Type Parameter
R extends readonly string[]
K extends Kinds

Properties

PropertyModifierTypeDescriptionDefined in
intentsreadonlyobject-packages/playerthree/src/signals.ts:121
intents.signalreadonlyobject-packages/playerthree/src/signals.ts:122
intents.signal.docreadonlystring-packages/playerthree/src/signals.ts:122
intents.signal.paramsreadonlyobject-packages/playerthree/src/signals.ts:122
intents.signal.params.signalreadonlyUnionS<"kind", { [k in string]: K[k]["params"] & SendFields }>-packages/playerthree/src/signals.ts:122
intents.signal.rolesreadonlyreadonly string[]-packages/playerthree/src/signals.ts:122
intents.signal_updatereadonlyobject-packages/playerthree/src/signals.ts:123
intents.signal_update.docreadonlystring-packages/playerthree/src/signals.ts:123
intents.signal_update.paramsreadonlyobject-packages/playerthree/src/signals.ts:123
intents.signal_update.params.idreadonlyIdS-packages/playerthree/src/signals.ts:123
intents.signal_update.params.updatereadonlyEnumS<readonly ["ack", "decline", "done", "fail", "cancel"]>-packages/playerthree/src/signals.ts:123
intents.signal_update.rolesreadonlyreadonly string[]-packages/playerthree/src/signals.ts:123
observationreadonlyObjS<{ 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
viewreadonlyListS<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

PropertyModifierTypeDefined in
kindreadonlystringpackages/playerthree/src/signals.ts:72
where?readonlyobjectpackages/playerthree/src/signals.ts:73

SignalVocabulary

Defined in: packages/playerthree/src/signals.ts:76

Type Parameters

Type ParameterDefault type
K extends Record<string, SignalKindDef>Record<string, SignalKindDef>

Properties

PropertyModifierTypeDescriptionDefined in
cardsreadonlyobjectPer role: the signals it answers. Roles without a card answer nothing (they may still send).packages/playerthree/src/signals.ts:79
kindsreadonlyK-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


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

Type Parameter
R extends readonly string[]
K extends Kinds

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 after keepTicks);
  • 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 have maxOpen open 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

ParameterType
mAnyManifest
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

SeatSignals


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

ParameterType
mAnyManifest
intent{ kind: string; }
intent.kindstring

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

Type Parameter
R extends readonly string[]
K extends Kinds

Parameters

ParameterType
rolesR
vocabSignalVocabulary<K>
limitsSignalLimits

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

ParameterType
rawunknown
signalsSeatSignals | SignalEntry[]

Returns

unknown