SoundMaterial
A material is the physical surface a piece is made of. It is one half of the pair — material × action — that the engine resolves into an actual licensed clip, and it is the only way a mod or a non-admin editor user can name a first-party sound. Clip ids and file paths are never addressable.
8 values, declared as soundMaterialSchema in packages/shared/src/soundSets.ts. Seven of them make a
noise; silent is a sentinel that makes none.
The values#
| Value | What it sounds like | Kinds that default to it | Where you can name it |
|---|---|---|---|
wood |
Wooden tiles, meeples, board surfaces. | board, card-holder |
TableObjectDefinition.material · SoundRef · playSound({ event }) · ModSoundSet.material |
cardboard |
Punchboard counters, chits, thick tokens. | — | the same four |
metal |
Coins, metal miniatures, metal-cased dice. | — | the same four |
plastic |
Injection-moulded pieces and standard dice. | die, token |
the same four |
card |
Paper card stock — the deck and hand sounds. | card, deck |
the same four |
tile |
Ceramic or heavy resin tiles; also the rummage sounds. | bag |
the same four |
generic |
The catch-all. What playSound({ event }) uses when you omit material. |
custom |
the same four |
silent |
A sentinel, not a sound. An entity set to silent emits nothing. |
— | the same four |
Every kind has a default, so an entity with no material still sounds like something:
card → card, deck → card, die → plastic, token → plastic, board → wood, bag → tile,
card-holder → wood, custom → generic.
Where a material comes from, in order#
- A per-action override on the entity —
soundSetOverrides[action], set byapi.setObjectSoundor authored in the editor. - The entity's own
materialfield. - The per-kind default above.
api.playSound({ event: { material, action } }) bypasses all three: it names a material directly for one
play and changes nothing about any entity.
What a mod can and cannot name#
By design. A
SoundRefis either{ kind: "builtin", material }— semantic, resolved internally — or{ kind: "mod", modId, name }, pointing at a sound the mod declared in its own manifest. A first-party clip id, aSoundSetIdand a file path are all unrepresentable in the type, and the host additionally refuses a{ kind: "mod" }ref naming another mod or a name this mod never declared. That is a licensing boundary — the first-party clips are not exposed as an addressable library — and it is not expected to change. Declare what you need inmanifest.soundSetsand reference it by name.
See also#
- SoundAction — the other half of the pair.
- Runtime sound events — the moments that select an action, per kind.
api.playSound— playing one without changing anything.api.setObjectSound— changing an entity's sound permanently.- Object kinds — the per-kind defaults in their wider context.
