Documentation

Game logic

v2 · Stable

Hidden information

The three state buckets

Where a value lives decides who can see it and whether it travels.

Bucket Scope Visibility
static Per class Never on the wire. Constants: name, cost, ability text. Read via piece.def.static.
publicState Per instance Everyone. Tapped flags, counters, damage.
privateState Per instance Owner only. The server nulls it for every other viewer, so hidden information never leaves the server.
class Card extends PieceDef<{ tapped: boolean }, { victoryPoints: number }> {
  readonly kind = "card";
  readonly width = 100;
  readonly height = 140;
  readonly orientations = [{ imageSrc: GameImage.CardFront }];

  protected publicDefaults() {
    return { tapped: false };
  }
  protected privateDefaults() {
    return { victoryPoints: 0 };
  }
}

new Card({ order: 1 });                                      // defaults
new Card({ order: 1, tapped: true });                        // override public
new Card({ order: 1, privateState: { victoryPoints: 3 } });  // override private

order is required in every constructor call : pieces in a space sort ascending by it.

Framework fields

piece.publicState always carries these, and your PublicState generic must not shadow them:

type PieceDefBaseState = {
  order: number;
  currentOrientationIndex: number;
  isSelected?: boolean;
  spaceId?: string;
};

Reading privateState

piece.privateState is PrivateState | null : null means this viewer isn't the owner. Every read must handle null, in your hooks and in your client. That is the mechanism that keeps a hand hidden, so it is not optional.

Need a hand with this?

Join our Discord