The client

v3 · Preview

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

Images and sounds

API

Hook Contract
useImage(key) string | undefined: the URL of the game's art key.
useSounds() Sounds: { play(key: string, options: PlaySoundOptions): SoundHandle; stopAll(type?: SoundType): void }, the same object for the whole match. PlaySoundOptions is { type: "music" | "effect"; loop?: boolean; volume?: number } and SoundHandle is { stop(): void }. play throws for a key the game has no sound for. See Sounds.
useAudioSettings() AudioSettings: { music: boolean; effects: boolean }, what the player hears now. See Sounds.

Images

Get the URL of uploaded art with useImage(key), where key is the art's key in the game's art library. The hook returns undefined when the game has no image for the key: draw a fallback then.

import { useImage } from "boardweaver/react";

export function CardBack() {
  const image = useImage("CardBack");
  return image ? <img src={image} alt="Card back" /> : <span>Card</span>;
}

When you rename an art key, change every useImage call that names it.

Sounds

Upload each sound with upload_sound, or with Upload sounds in the studio's Sounds view:

  • The file is MP3, WAV, OGG or M4A, at most 10 MiB.
  • The key is UpperCamelCase ASCII letters and digits, such as DiceRoll. The sound lives at /sounds/<Key>.
  • Uploading needs the Designer or Professional plan. Every player hears the game's sounds, whatever their plan.
  • An upload is a pending change. The studio preview plays it at once, and commit makes it permanent.
  • Upload the same key again to replace a sound. Move it with rename_file and remove it with delete_file, then change every key the client plays to match.
  • For a local file too large to pass inline, call create_upload with target { type: "sound", key }, its SHA-256 and its byte length. Then follow Upload local files to POST the raw file.

Play a sound by its key with useSounds(). Give each play a type: "music" for a soundtrack or an ambient loop, or "effect" for a sound that answers a step:

import { useEffect } from "react";
import { useLastChange, useSounds } from "boardweaver/react";

export function GameSounds() {
  const sounds = useSounds();
  const change = useLastChange();

  useEffect(() => {
    const theme = sounds.play("ThemeLoop", { type: "music", loop: true });
    return () => theme.stop();
  }, [sounds]);

  useEffect(() => {
    if (change.coalesced || change.direction === "back") return;
    if (change.steps.some((step) => step.movements.length > 0)) {
      sounds.play("PiecePlaced", { type: "effect" });
    }
  }, [change, sounds]);

  return null;
}
  • Play each step's sound from an effect on useLastChange(), so it plays as Boardweaver shows the step, for the seat's own steps and other players' alike. Skip a coalesced change and one whose direction is back.
  • Start music in an effect and stop it in the cleanup, so it ends with the component.
  • stopAll(type?) stops every playing sound, or every sound of one type.
  • volume runs from 0 to 1. iOS Safari ignores it.

Each player turns music and effects on and off, for every game or for one match, from the sound control on the bar. Boardweaver applies the choice: an effect played while effects are off does nothing, and music plays muted while music is off, so it keeps its place. Read useAudioSettings() only to show the player's choice in your own controls.

Browsers play no sound until the player presses or types in the game. Music started before that starts at the first press. Boardweaver drops an effect played before it.

Sound made with Web Audio ignores the player's settings, so a player who turned sound off still hears it. Upload a file and play it with useSounds() instead.

The Sounds page lists uploaded clips, their names, and playback controls.
The Sounds page lists uploaded clips, their names, and playback controls. Example data from the local development UI. Select the image to enlarge.
The match sound menu can override account preferences for just this match.
The match sound menu can override account preferences for just this match. Example data from the local development UI. Select the image to enlarge.

Need a hand with this?

Join our Discord