The client

v3 · Preview

Framework v3 is an opt-in preview available to everyone. New games use the stable framework by default.

Pending actions and failures

API

Hook Contract
usePending() { pending: PendingView | null; deferred: string[] }. PendingView is { id; kind: "decision" | "undo"; predicted: boolean; historyId? }. deferred lists ids whose result the connection lost.
useFailures() { failures: CoreFailure[]; dismiss: (id: string) => void }.

Decisions on their way

usePending().pending is the one decision or undo on its way to Boardweaver. When its predicted is true, the board already shows the result. It is false for an undo, and for a decision whose last step Boardweaver must apply first, such as a step that reveals or draws randomness. Then show that the move is on its way. The board updates when Boardweaver answers.

Failures

useFailures().failures keeps every failed step, refused decision and dropped draft step until the client calls dismiss(id). Show each one and let the player dismiss it. When Boardweaver refuses a decision, its steps that still apply come back as the draft, and the player confirms again.

An offer's label and the reason of a GAME refusal are messages from your catalogs. A REFUSED, SERVER_REFUSED or DRAFT_DROPPED failure can carry that refusal. Write a message as text with the function that useMessageText() returns:

import { FormattedMessage } from "react-intl";
import { useFailures, useMessageText } from "boardweaver/react";

export function FailureList() {
  const { failures, dismiss } = useFailures();
  const text = useMessageText();
  return (
    <>
      {failures.map((failure) => {
        const refusal = "refusal" in failure.reason ? failure.reason.refusal : null;
        return (
          <p key={failure.id} role="alert">
            {refusal?.refused === "GAME" ? (
              text(refusal.reason)
            ) : (
              <FormattedMessage id="failure" values={{ code: failure.reason.code }} />
            )}{" "}
            <button onClick={() => dismiss(failure.id)}>
              <FormattedMessage id="failure.dismiss" />
            </button>
          </p>
        );
      })}
    </>
  );
}

Need a hand with this?

Join our Discord