Customization schema reference
This is the single reference for Caputchin's field-type and preset model, the shared foundation under every customizable surface:
- Game customization: a marketplace game's language, skin, and configuration.
- Custom game schemas: the schema you author yourself for a custom game.
- Marketplace game manifests: the
locales/skins/configurationsblocks a game author declares. - White-labeling the widget: the widget shell's built-in schema.
All four use the same field types and the same preset model described here. Customization is built from presets, and a preset is a bag of typed fields.
Field types by axis
Each axis allows a fixed set of field types:
| Axis | Allowed field types |
|---|---|
| Configuration | boolean, number, range, list, string, link |
| Locale | string only |
| Skin | color, image, audio, video, boolean, number, range, list |
A skin is not only colors and assets: it can also expose the scalar knobs boolean,
number, range, and list (a "shadows" toggle, a corner-radius number, a "pattern" choice).
These behave exactly like their configuration counterparts and resolve to their typed value (a
boolean stays true, a number stays 8); color and asset values resolve to strings.
Skin does not allow string or link (free text belongs to language; a link target is a
configuration).
What each type accepts
| Type | Value | Rules |
|---|---|---|
string | Free text | Any text. |
boolean | A toggle | true or false. |
number | A number | Any finite number. |
range | A bounded number | A finite number within the field's minimum and maximum. The step is a slider convenience; off-step values are still accepted. |
list | One choice | Must be one of the field's listed options. |
link | A URL | An http or https URL. Embedded credentials are rejected. |
color | A color | A hex color (#rgb, #rgba, #rrggbb, or #rrggbbaa) or an rgb() / rgba() value. Named colors and other color spaces are not accepted. |
image | An image | An uploaded file or an https URL ending in .png, .jpg, .jpeg, .webp, .svg, or .gif. |
audio | An audio clip | An uploaded file or an https URL ending in .mp3, .ogg, or .wav. |
video | A video | An uploaded file or an https URL ending in .mp4 or .webm. |
Caputchin validates every value when you save, so a value that does not fit its type is rejected before it can reach a visitor.
Reserved keys
Alongside its content fields, a preset carries a few reserved metadata keys (each prefixed with an underscore) that control how it is selected and resolved, not what it displays. How you set them depends on the surface: a marketplace game author writes them literally in caputchin.json; in the dashboard editor (custom games, white-label) you set them through controls and never type the key. Either way the meaning is the same.
| Key | Axis | Meaning |
|---|---|---|
_lang | Locale | The BCP-47 language tag a locale preset serves (en, es, and so on). Presets are grouped by it; several presets may share one _lang (e.g. two English variants). |
_direction | Locale | ltr or rtl. Optional, auto-derived from _lang for right-to-left languages (ar, he, fa, ur, yi, ps, sd); rarely set by hand. |
_theme | Skin | light, dark, or any. A light / dark preset shows only under that background; an any preset works under both and is eligible for either. Defaults to light when absent. |
_default | All | Marks the preset the server picks for its group when the visitor does not select one. One default per group (per mode for skin); an any skin can be the default for light, dark, or both. |
_extends | All | Names another preset to inherit from. See Extending a preset. |
Reserved metadata keys are stripped during resolution: _extends and _default never reach the game, and only the surviving metadata (_lang, _direction, _theme) plus the flattened content fields are delivered.
Extending a preset
_extends lets one preset inherit every value from another, so you author only the fields that differ instead of repeating a whole preset. Set _extends to the name of another preset in the same axis; the extending preset starts from all of that preset's values and overrides the keys it sets itself.
{
"skins": {
"presets": {
"brand-light": { "_theme": "light", "accent": "#2da44e", "bg": "#ffffff" },
"brand-light-warm": { "_extends": "brand-light", "accent": "#d97706" }
}
}
}Here brand-light-warm inherits bg from brand-light and changes only accent.
Two details:
- Skin theme shortcut. On a skin preset,
_extendsmay instead name a theme (lightordark) rather than a preset. That form resolves to whichever preset is the_defaultfor that theme, a convenient way to base a variant on "the default light skin" without naming it. - It resolves away.
_extendsis followed and then stripped; the game receives the fully merged result, never the_extendskey itself.
Where a schema comes from
The field set a preset can fill (its schema) has three sources, all using the same field types above:
- Marketplace game: the schema comes from the game author's manifest, fetched when you open the editor. You override the game's presets but do not change its schema.
- Custom game: you define the schema yourself in the dashboard, then author presets against it. See custom games.
- Widget shell (white-label): a fixed, built-in schema. You override its presets; the field set is not author-declared. See white-label the widget.
Presets and resolution
Within an axis, fields are grouped into named presets, and the server resolves one effective preset per group from the layered scopes, site key over troop over bundled default, computed per value. The selectors differ by axis: locale is chosen by the visitor's browser language, skin by the visitor's light or dark preference (a preset whose mode is any is eligible for either), and configuration is server-authoritative (the visitor cannot choose it). See the overview for the scope model.
See also
- Game customization overview: registering and managing games, plus the per-axis how-tos for configurations, language, and skin.
- Custom game dashboard schema: authoring a schema yourself for a custom game.
- The caputchin.json manifest: declaring these blocks as a marketplace game author.
- White-label the widget: the same types applied to the widget shell.