Phase 14 - Organized directories.
This commit is contained in:
@@ -0,0 +1,362 @@
|
||||
# Sandbox theme reference
|
||||
|
||||
`res://sandbox_theme.json` is the hand-editable presentation configuration for
|
||||
the Sandbox Stage (`res://scenes/stage/sandbox_stage.tscn`). It is loaded by
|
||||
`SandboxStage` during `_ready()`, before the code-built UI is created. The
|
||||
loader is `res://scripts/stage/sandbox_theme.gd` (`class_name SandboxTheme`).
|
||||
|
||||
The committed file uses schema `"2.0"`. The theme controls presentation
|
||||
defaults only; it does not save a scene, placement, or action data.
|
||||
|
||||
## Load, merge, and validation rules
|
||||
|
||||
The load path is:
|
||||
|
||||
```text
|
||||
res://sandbox_theme.json
|
||||
│
|
||||
▼
|
||||
SandboxTheme.DEFAULT_CONFIG
|
||||
│ deep-merge file values
|
||||
▼
|
||||
SandboxStage._build_ui() and visual overlays
|
||||
```
|
||||
|
||||
- Missing, unreadable, malformed, or non-object JSON uses the built-in default
|
||||
configuration and emits one warning. The stage continues to run.
|
||||
- Missing nested keys inherit the built-in value. Unknown keys are retained in
|
||||
the raw dictionary but have no effect until a consumer is added.
|
||||
- `stylebox(component)` resolves styles in this order:
|
||||
`global` → `<section>.style_defaults` → the component object. For example,
|
||||
`palette` is resolved from `global`, then `palette.style_defaults`, then
|
||||
`palette`.
|
||||
- Colors must be strings in `#RRGGBB` or `#RRGGBBAA` form. Invalid colors use
|
||||
the requested fallback and emit a warning.
|
||||
- Numeric accessors accept finite integers/floats and clamp them to the range
|
||||
requested by the consumer. Invalid or non-finite numbers use that consumer's
|
||||
fallback. Size arrays are accepted when they contain two numeric values;
|
||||
individual controls apply their own minimum sizes.
|
||||
- Font paths are `res://` resource paths. A missing resource, or a resource
|
||||
that is not a `Font`, uses `ThemeDB.fallback_font` and emits a warning.
|
||||
- The theme is loaded once per Sandbox Stage instance. Restart the scene (F6)
|
||||
to see edits; there is no live file watcher or reload button.
|
||||
|
||||
The live grid size, snap toggle, and grid visibility are stored in
|
||||
`user://sandbox_settings.json`. `grid.snap_size` supplies the initial grid-size
|
||||
default; it does not overwrite a value already saved in user settings.
|
||||
|
||||
## Schema overview
|
||||
|
||||
Every current top-level block is listed below. The values shown are the
|
||||
defaults in the committed `sandbox_theme.json` (not necessarily the fallback
|
||||
used by an older caller).
|
||||
|
||||
### Current consumer status
|
||||
|
||||
The schema intentionally includes forward-looking values for the reusable
|
||||
widget and speech work. The current Sandbox runtime applies these groups:
|
||||
|
||||
- `global` style values used by resolved styleboxes and the selector control
|
||||
theme (background/border/radius/padding); `global.text_color` and
|
||||
`global.muted_text_color` are available presentation values but are not
|
||||
applied to every existing label automatically.
|
||||
- `fonts.ui_font`, `emoji_font`, bold/italic variants, the nested `sizes`
|
||||
entries for action popups, tooltips, status pills, queue/rule/action editors,
|
||||
panel rows/titles, `file_menu`, `file_menu_popup`, and `mode_switcher`, plus
|
||||
the related `flags`.
|
||||
- `mode_colors.edit`, `direct`, `play`, and `guide`; `grid.snap_size` as the
|
||||
first-run grid default; dialog sizes/fonts; `chrome.mode_switcher` width;
|
||||
palette width/card size/drag threshold/style; selector cell and thumbnail
|
||||
sizes; and all `overlays` values.
|
||||
|
||||
These declared values currently remain reserved or require a legacy adapter:
|
||||
|
||||
- `chrome.top_bar.height`, `status_bar.height`, `mode_frame`, `mode_badge`,
|
||||
and `tooltip` describe the intended chrome contract, but the corresponding
|
||||
layout/style constants are still authored in `SandboxStage`.
|
||||
- `popups.action_menu.font_size` and `popups.asset_selector.backdrop_alpha`
|
||||
are reserved component overrides. The active action-menu size comes from
|
||||
`fonts.sizes.action_popup`; selector `cell_size` and `thumbnail_size` are
|
||||
active.
|
||||
- `palette.icon_size` and `palette.selected_border_width` are reserved for
|
||||
the palette card renderer; the current card has its own glyph/border values.
|
||||
- `fonts.sizes.assignment_badge`, `rule_label`, `asset_label`, and
|
||||
`asset_badge` are part of the resolved schema, but the current direct call
|
||||
into `StageDirectorVisuals` still reads the legacy flat badge/label names.
|
||||
Use the legacy names documented below when changing those director visuals.
|
||||
- `fonts.presets` and every `widgets` list are exposed through reusable
|
||||
controls, but the current Sandbox Speak action does not instantiate those
|
||||
controls yet. They are future speech-customization data.
|
||||
|
||||
### `version`
|
||||
|
||||
| Key | Format | Current value | Notes |
|
||||
|---|---|---:|---|
|
||||
| `version` | string | `"2.0"` | Use `"2.0"` when using the nested schema below. |
|
||||
|
||||
### `global`
|
||||
|
||||
Global style values are inherited by `SandboxTheme.stylebox()` and the default
|
||||
control theme.
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `font_preset` | string | `"ui"` | Named base-font selection for future/general UI use. |
|
||||
| `font_size` | integer | `18` | Default `Control` font size. |
|
||||
| `text_color`, `muted_text_color` | color string | `#F5F7FA`, `#AAB2C0` | Primary and secondary text colors. |
|
||||
| `bg_color`, `surface_color` | color string | `#171B24F2`, `#252B38FA` | Global and raised-surface backgrounds. |
|
||||
| `border_color` | color string | `#FFFFFF33` | Default border color. |
|
||||
| `border_width` | integer | `1` | Default border width. |
|
||||
| `corner_radius` | integer | `10` | Default corner radius. |
|
||||
| `padding`, `spacing` | integer | `8`, `8` | Default style padding and layout spacing. |
|
||||
|
||||
### `fonts`
|
||||
|
||||
Font paths may be empty (`""`) to use the engine fallback. `presets` is an
|
||||
object of arbitrary preset IDs; each entry has a display `label` and a `path`.
|
||||
The committed file provides `ui`, `comic`, `pixel`, and `scary` entries.
|
||||
|
||||
| Key | Format | Default | Consumer |
|
||||
|---|---|---:|---|
|
||||
| `ui_font`, `emoji_font` | `res://` path or empty | `""` | Base UI and emoji-capable stage/director controls. |
|
||||
| `ui_font_bold`, `ui_font_italic` | `res://` path or empty | `""` | Optional style variants; bold can be generated from the base font when no dedicated path is supplied. |
|
||||
| `presets` | object `{id:{label,path}}` | see JSON | `font_presets()` and future font selectors. |
|
||||
| `sizes.action_popup` | integer | `24` | Director/action popup text. |
|
||||
| `sizes.action_popup_emoji` | integer | `22` | Effective popup size when a popup font is active (Godot popup menus have one font size). |
|
||||
| `sizes.assignment_badge` | integer | `20` | Reserved resolved-theme value; current director visuals use legacy `fonts.assignment_badge_font_size`. |
|
||||
| `sizes.rule_label` | integer | `18` | Reserved resolved-theme value; current director visuals use legacy `fonts.rule_label_font_size`. |
|
||||
| `sizes.status_pill` | integer | `18` | Mode badge/pill. |
|
||||
| `sizes.tooltip` | integer | `18` | Cursor-attached targeting tooltip. |
|
||||
| `sizes.file_menu` | integer | `22` | `File` button in the top bar. |
|
||||
| `sizes.file_menu_popup` | integer | `26` | File menu and Open Recent popup rows. |
|
||||
| `sizes.mode_switcher` | integer | `24` | Edit/Direct/Play buttons. |
|
||||
| `sizes.queue_panel`, `sizes.rule_panel` | integer | `22`, `22` | Queue and rule editor panels. |
|
||||
| `sizes.action_editor`, `sizes.rule_editor` | integer | `22`, `22` | Action and rule editor controls. |
|
||||
| `sizes.panel_row`, `sizes.panel_title` | integer | `20`, `24` | Editor row text and panel titles. |
|
||||
| `sizes.asset_label`, `sizes.asset_badge` | integer | `18`, `14` | Reserved asset-card text sizing. |
|
||||
| `flags.panel_title_bold` | boolean | `true` | Bold queue/rule panel titles. |
|
||||
| `flags.rule_label_bold` | boolean | `false` | Bold director rule labels. |
|
||||
| `flags.badge_bold` | boolean | `true` | Bold director badges. |
|
||||
| `flags.action_popup_bold`, `flags.action_popup_italic` | boolean | `false`, `false` | Popup style flags. |
|
||||
|
||||
### `mode_colors`
|
||||
|
||||
Each value is a color string. These accents are used by the mode badge/frame,
|
||||
active mode controls, targeting feedback, and related stage chrome.
|
||||
|
||||
| Key | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `edit` | `#22C6FF` | Edit-mode accent. |
|
||||
| `direct` | `#FFB300` | Direct-mode accent. |
|
||||
| `play` | `#33DD77` | Play-mode accent. |
|
||||
| `guide` | `#22C6FF` | Terrain painting guide line. |
|
||||
|
||||
### `grid`
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `snap_size` | finite number | `15.0` | Initial grid size, clamped to the stage's supported range. |
|
||||
|
||||
### `chrome`
|
||||
|
||||
`style_defaults` is the optional common style object for chrome components. Its
|
||||
style keys follow the `global` style formats (`bg_color`, `border_color`,
|
||||
`border_width`, `corner_radius`, `padding`).
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `style_defaults` | style object | `{ "bg_color":"#171B24F2", "corner_radius":10 }` | Shared chrome style base. |
|
||||
| `top_bar.height` | number | `64` | Top navigation bar height. |
|
||||
| `status_bar.height` | number | `38` | Bottom status bar height. |
|
||||
| `mode_switcher.segment_min_width` | number | `124` | Minimum width of each Edit/Direct/Play segment. |
|
||||
| `mode_frame.border_width` | integer | `3` | Colored stage frame width. |
|
||||
| `mode_badge.corner_radius` | integer | `12` | Mode badge corner radius. |
|
||||
| `mode_badge.padding` | number | `10` | Mode badge padding. |
|
||||
| `tooltip.bg_color` | color | `#101010E6` | Targeting tooltip background. |
|
||||
| `tooltip.border_width` | integer | `1` | Targeting tooltip border. |
|
||||
| `dialogs.queue_size` | `[width,height]` | `[680,520]` | Queue editor window minimum size. |
|
||||
| `dialogs.rule_size` | `[width,height]` | `[720,560]` | Rule editor window minimum size. |
|
||||
| `dialogs.action_size` | `[width,height]` | `[560,390]` | Action editor window minimum size. |
|
||||
| `dialogs.confirm_size` | `[width,height]` | `[620,300]` | Rename, unsaved, missing-assets, and other confirmation/error windows. |
|
||||
| `dialogs.font_size` | integer | `22` | Dialog controls/buttons. |
|
||||
| `dialogs.message_font_size` | integer | `26` | Centered AcceptDialog message text. |
|
||||
|
||||
### `popups`
|
||||
|
||||
`style_defaults` accepts the normal style keys and is inherited by popup
|
||||
components.
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `style_defaults` | style object | bg `#202633FA`, border `#FFFFFF33`, radius `12`, padding `12` | Common popup surface. |
|
||||
| `action_menu.font_size` | integer | `24` | Reserved action-menu component override; use `fonts.sizes.action_popup` for the active menu. |
|
||||
| `dialog` | object | `{}` | Reserved per-dialog popup overrides. |
|
||||
| `asset_selector.backdrop_alpha` | finite number | `0.55` | Reserved selector backdrop opacity. |
|
||||
| `asset_selector.cell_size` | `[width,height]` | `[190,220]` | Prop/stickman selector cell size. |
|
||||
| `asset_selector.thumbnail_size` | `[width,height]` | `[156,156]` | Prop/stickman selector thumbnail size. |
|
||||
|
||||
### `palette`
|
||||
|
||||
`style_defaults` uses normal style keys and styles the stage placement palette.
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `style_defaults` | style object | bg `#252B38FA`, radius `10`, padding `6` | Palette surface/card base. |
|
||||
| `dock_width` | number | `116` | Palette width in Edit mode and stage-frame inset. |
|
||||
| `card_size` | `[width,height]` | `[96,94]` | Placement-card minimum size; the card keeps room for its label. |
|
||||
| `icon_size` | number | `30` | Reserved palette icon/glyph size. |
|
||||
| `drag_threshold` | number | `8` | Pointer distance before a card becomes a drag. |
|
||||
| `selected_border_width` | integer | `3` | Reserved selected palette card border. |
|
||||
|
||||
### `overlays`
|
||||
|
||||
`style_defaults` controls dashed overlay geometry in world pixels; colors are
|
||||
RGBA strings.
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---:|---|
|
||||
| `style_defaults.line_width` | number | `2` | Dashed trajectory/guide width. |
|
||||
| `style_defaults.dash_length` | number | `8` | Dash length. |
|
||||
| `style_defaults.dash_gap` | number | `5` | Gap length. |
|
||||
| `terrain_guide.color` | color | `#22C6FF` | Terrain paint guide. |
|
||||
| `valid.color` | color | `#4DE66680` | Valid director target/placement feedback. |
|
||||
| `same_type.color` | color | `#FFFFFF26` | Same-type placement feedback. |
|
||||
| `invalid.color` | color | `#FF4D4D80` | Invalid target/placement feedback. |
|
||||
|
||||
### `widgets`
|
||||
|
||||
These lists feed reusable controls (`EmojiQuickGrid`, `FontPresetPicker`, and
|
||||
`PresetSizeToggle`). They are data sources, not speech-action persistence.
|
||||
|
||||
| Key | Format | Default | Purpose |
|
||||
|---|---|---|---|
|
||||
| `swatches` | array of color strings | white, black, cyan, amber, green, red | Color selector entries. |
|
||||
| `size_presets` | array of `{id,label,value}` objects | Small/Medium/HUGE (`20/28/40`) | Size selector entries; `value` is an integer-like size. |
|
||||
| `emoji` | array of strings | eight emoji entries | Emoji quick-grid entries. |
|
||||
|
||||
## Practical edits
|
||||
|
||||
Make the top navigation easier to read:
|
||||
|
||||
```json
|
||||
{
|
||||
"fonts": {
|
||||
"sizes": {
|
||||
"file_menu": 26,
|
||||
"file_menu_popup": 30,
|
||||
"mode_switcher": 28
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Change the mode frame and make the stage colors more distinct:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode_colors": {
|
||||
"edit": "#4DD9FF",
|
||||
"direct": "#FF8A3D",
|
||||
"play": "#65E68A",
|
||||
"guide": "#4DD9FF"
|
||||
},
|
||||
"chrome": { "mode_frame": { "border_width": 4 } }
|
||||
}
|
||||
```
|
||||
|
||||
Give selectors larger cards and thumbnails:
|
||||
|
||||
```json
|
||||
{
|
||||
"popups": {
|
||||
"asset_selector": {
|
||||
"cell_size": [220, 260],
|
||||
"thumbnail_size": [190, 190]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make kid-facing editors and confirmations larger:
|
||||
|
||||
```json
|
||||
{
|
||||
"chrome": {
|
||||
"dialogs": {
|
||||
"queue_size": [760, 600],
|
||||
"rule_size": [800, 640],
|
||||
"font_size": 26,
|
||||
"message_font_size": 30
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
"sizes": {
|
||||
"queue_panel": 24,
|
||||
"rule_panel": 24,
|
||||
"action_editor": 24,
|
||||
"rule_editor": 24,
|
||||
"panel_row": 22,
|
||||
"panel_title": 28
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Legacy v1 files
|
||||
|
||||
Older Phase 4b/3c theme files used flat keys such as
|
||||
`fonts.action_popup_font_size`, `fonts.queue_panel_font_size`,
|
||||
`fonts.panel_title_font_size`, and mode keys such as
|
||||
`mode_colors.edit_accent` and `mode_colors.guide_line`. They remain accepted.
|
||||
The loader aliases the legacy mode names and selected flat font-size names into
|
||||
the nested structure, while `SandboxStage` retains the old precedence for a
|
||||
file that does not declare version `"2.0"`.
|
||||
|
||||
The complete legacy names still read by the current runtime are:
|
||||
|
||||
```text
|
||||
fonts.action_popup_font_size fonts.action_popup_emoji_size
|
||||
fonts.assignment_badge_font_size fonts.assignment_badge_radius
|
||||
fonts.rule_label_font_size fonts.status_pill_font_size
|
||||
fonts.tooltip_font_size fonts.queue_panel_font_size
|
||||
fonts.rule_panel_font_size fonts.action_editor_font_size
|
||||
fonts.rule_editor_font_size fonts.panel_row_font_size
|
||||
fonts.panel_title_font_size fonts.panel_title_bold
|
||||
fonts.rule_label_bold fonts.badge_bold
|
||||
fonts.action_popup = { size, bold, italic }
|
||||
|
||||
mode_colors.edit_accent mode_colors.direct_accent
|
||||
mode_colors.play_accent mode_colors.guide_line
|
||||
```
|
||||
|
||||
For a migration, copy the values into the nested keys in this document and set
|
||||
`"version": "2.0"`. Keep only one spelling of each setting so the result is
|
||||
easy to maintain.
|
||||
|
||||
## Fonts, emoji, and troubleshooting
|
||||
|
||||
- Use project-relative paths such as `res://fonts/kids_font.ttf`; do not use a
|
||||
machine-specific absolute path.
|
||||
- If text falls back to the Godot default, check the path, import status, and
|
||||
that the resource is actually a `Font`/font file. Restart the Sandbox after
|
||||
correcting it.
|
||||
- Emoji availability depends on the selected font and platform glyph support.
|
||||
A missing `emoji_font` is non-fatal; the normal UI fallback remains usable.
|
||||
- If a color or number is ignored, check JSON commas/quotes, use a supported
|
||||
color form, and keep numbers finite. The warning identifies the affected key.
|
||||
- If a selector or dialog looks cramped, increase its size array and its
|
||||
related font size together; restart F6 to reload the file.
|
||||
|
||||
## Speech customization status
|
||||
|
||||
`fonts.presets` (`ui`, `comic`, `pixel`, `scary`), `widgets.size_presets`,
|
||||
`widgets.swatches`, and `widgets.emoji` are the reusable data contract for a
|
||||
future speech-customization UI. They are intentionally available now so a
|
||||
future Speak dialog can consume the same theme.
|
||||
|
||||
The current Sandbox speech action still stores and renders text through the
|
||||
existing `StickmanSpeechBubble`; these theme lists do not yet change saved
|
||||
speech actions, bubble shape, bubble colors, or bubble font at runtime. Do not
|
||||
assume that changing a preset changes an existing speech action. Treat
|
||||
speech-specific fields under `popups.dialog` or future bubble sections as
|
||||
reserved until that feature is implemented.
|
||||
Reference in New Issue
Block a user