Phase 14 - Organized directories.

This commit is contained in:
2026-10-03 19:13:39 -04:00
parent 6666173c4f
commit d950fd9d9a
307 changed files with 1452 additions and 1110 deletions
@@ -0,0 +1,157 @@
## Summary of Speech & Speech Bubble Features
The goal is to expand the existing single-bubble `SpeechBubble` system into a comic-book movie engine designed for young directors.
### 1. Data Contract & Theme Integration
- **Expanded Action Payload**: Extend the `speak` action payload to support explicit visual parameters:
```json
{
"type": "speak",
"text": "Look out for the [shake]MONSTER![/shake]",
"duration": 2.5,
"stop_current": false,
"visual": {
"bubble_style": "yell",
"font_preset": "comic",
"size_preset": "huge",
"color": "#FF3333",
"anim_mode": "typewriter"
}
}
```
- **Theme Fallbacks**: Route missing keys through `sandbox_theme.json` defaults $\rightarrow$ Global Theme $\rightarrow$ Godot `ThemeDB.fallback_font`.
### 2. Rich Text & Visual Styles
- **`RichTextLabel` Migration**: Shift text rendering from raw `draw_string()` calls to an internal `RichTextLabel` child node to enable full BBCode support (`[wave]`, `[shake]`, bolding, inline colors).
- **Shape Presets (`BubbleStyle`)**:
- **Standard**: Classic rounded rectangle + downward tail triangle.
- **Yell / Shout**: Multi-pointed starburst polygon.
- **Thought**: Arc/circle cluster cloud boundary + descending bubble chain dots.
- **Whisper**: Semi-transparent fill with dashed border lines (`draw_dashed_line()`).
- **Comic SFX**: Borderless, high-contrast banner box for sound effect popups ("BOOM!", "POW!").
### 3. Dynamic Text & Bubble Animations
- **Typewriter & Word Reveals**: Animate `visible_characters` via Godot `Tween` for letter-by-letter or word-by-word reveals.
- **Elastic Entrances & Transitions**: Scale bubble from $0 \rightarrow 1$ using `TRANS_ELASTIC` on pop-in; morph bounding sizes with smooth squish-and-stretch tweens when swapping text lines back-to-back.
- **Word-Specific Shake & Wave**: Support inline animated text effects wrapped in BBCode tags.
### 4. Advanced Layout & Stagger Stacking
- **Comic Stagger Stacking**: Allow multiple speech lines to chain into vertical bubble stacks. The bottom bubble anchors to the stickman's head via the main tail, while higher bubbles stack upward connected by bridge geometry (`draw_colored_polygon()`).
- **Mirroring & Viewport Clamping**: Keep X-scale counter-mirroring active (`_sync_speech_bubble_mirror`). Clamp bubble bounds inside `get_viewport_rect()` so bubbles flip tail anchors or offset position to remain on-screen.
### 5. Director UI Upgrades
- **Kid-Friendly Controls**: Color swatch buttons, size toggles (**Small**, **Medium**, **HUGE**), font style pickers, and an emoji grid picker inside the `Speak` parameter dialog.
- **Text Highlight Formatting Bar**: Selecting text in the dialogue input shows quick-action buttons (🫨 **Shake**, 🌊 **Wave**, 🔥 **Bounce**) that automatically inject BBCode tags.
- **Auto-Duration Calculator**: Default `duration` automatically calculates based on word count ($1.0\text{s base} + 0.2\text{s/word}$).
---
## Detailed Implementation Plan
### Phase 1: Engine Migration & Data Foundation
**Goal:** Upgrade `SpeechBubble` to use `RichTextLabel` and expand data contracts without breaking existing scene functionality.
1. **Update Action Data Pipeline**:
- Update `ActionRegistry` and `StageSceneIO` to preserve the optional `visual` dictionary payload on `speak` actions.
- Ensure `StickmanRig.speak()` parses both flat strings and full visual dictionaries.
2. **Refactor `SpeechBubble` Node Structure (`scripts/stickman_speech_bubble.gd`)**:
- Add a child `RichTextLabel` node to `SpeechBubble`.
- Set `RichTextLabel.bbcode_enabled = true` and configure autowrap.
- Modify `_draw()`: Calculate background rectangle bounds dynamically using `RichTextLabel.get_content_height()` and text size metrics, then draw the background polygon/rect and tail under the text.
### Phase 2: Animated Reveals & Line Transitions
**Goal:** Implement typewriter effects, word reveals, and smooth line-swapping transitions.
1. **Typewriter & Word Reveal Engine**:
- Add `_play_typewriter(text: String, duration: float, mode: String)` to `SpeechBubble`.
- Use a Godot `Tween` targeting `RichTextLabel.visible_characters` from `0` to total character length over the target duration.
- Implement word-by-word step incrementing by parsing space/punctuation indices in the input string.
2. **Line Swap & Elastic Transitions**:
- Update `show_text()`: If a bubble is already visible when a new `speak` command arrives:
- Scale container down ($1.0 \rightarrow 0.8$) via `EASE_IN` tween.
- Swap payload and recalculate bounds.
- Scale container back out ($0.8 \rightarrow 1.0$) using `TRANS_ELASTIC` / `EASE_OUT`.
- Add squish-and-stretch size morphing when text length changes between consecutive lines.
### Phase 3: Polygon Shape Styles & Comic Geometry
**Goal:** Generate dynamic background shapes for distinct bubble styles.
1. **Shape Draw Functions**:
- **`_draw_standard_bubble(rect)`**: Existing rounded rect + downward tail triangle.
- **`_draw_yell_bubble(rect)`**: Generate an outer jagged polygon by iterating around `rect` perimeter and alternating vertex radii with random/sine noise offsets.
- **`_draw_thought_bubble(rect)`**: Draw overlapping circles along the bounding box edges using `draw_circle()`, followed by 2–3 smaller descending circles pointing to origin.
- **`_draw_whisper_bubble(rect)`**: Draw semi-transparent background fill; outline using `draw_dashed_line()` around the perimeter.
2. **Viewport Boundary Protection**:
- Calculate global screen position of bubble rect in `_process()`.
- If top or side edges exit `get_viewport_rect()`, offset the bubble box downward/inward and flip tail geometry anchor accordingly.
### Phase 4: Staggered Multi-Bubble Stacking
**Goal:** Support chained comic bubbles stacking upward from a single character.
1. **Stack Container Logic**:
- Extend `SpeechBubble` to manage an array of child `BubbleItem` records.
- When a multi-line or stacked speech payload is received, instantiate child bubble slots.
2. **Stack Geometry & Bridge Rendering**:
- Anchor the bottom-most bubble to `SPEECH_BUBBLE_OFFSET`.
- Position preceding bubbles vertically above it with vertical spacing gaps.
- In `_draw()`, calculate bridge vertices between `Bubble N` bottom-center and `Bubble N+1` top-center, drawing connecting polygons using `draw_colored_polygon()`.
- Restrict the downward head tail exclusively to the bottom bubble in the stack.
### Phase 5: Director UI & Formatting Controls
**Goal:** Expose all visual styling tools to kids in the editor UI.
1. **Integrate Theme Controls into `Speak` Parameter Dialog**:
- Add `ColorSwatchGrid` popover hooked into theme colors.
- Add `SizeToggle` segmented control (**Small**, **Medium**, **HUGE**) mapping to font scale metrics.
- Add `StylePicker` icon buttons (**Standard**, **Yell**, **Thought**, **Whisper**).
- Embed `EmojiPicker` grid widget.
2. **Implement Selection Highlight Formatting Bar**:
- Attach a floating mini-toolbar above the dialogue `LineEdit` / `TextEdit` field in the `Speak` dialog.
- Detect text selection (`get_selected_text()`). When text is highlighted, show mini-buttons:
- 🫨 **Shake** $\rightarrow$ wraps selection in `[shake rate=20.0 level=10.0]...[/shake]`
- 🌊 **Wave** $\rightarrow$ wraps selection in `[wave amp=50.0 freq=5.0]...[/wave]`
- 🔥 **Bounce** $\rightarrow$ wraps selection in `[bounce]...[/bounce]`
3. **Auto-Duration & Stagger Helpers**:
- Add auto-duration calculation checkbox/toggle in dialog.
- Add **"+ Add Stacked Bubble"** button in the speech dialog to split longer dialogue into chained stack items easily.