- Added a new event-driven system for reactive storytelling, allowing rules like "When X happens, do Y." - Introduced TriggerArea class for placeable sensors in the stage. - Enhanced StickmanRig to emit signals for actions and arrivals. - Updated StageDirectorVisuals to render rules visually with labels and badges. - Modified StageSpawner to support spawning TriggerAreas. - Improved text baseline calculations in speech bubbles and rule labels. - Added tests for text baseline fixes to ensure proper rendering. - Documented the implementation plan for Phase 4 in PHASE_4_TRIGGER_EVENTS.md. - Created a polish plan for Phase 4 in PHASE_4b_POLISH.md.
17 KiB
Phase 4: Triggers & Event System — Implementation Plan
1. Overview
Phase 4 adds reactive storytelling to the Sandbox Stage. While Phase 3a gave directors sequential control (actions in a fixed order), Phase 4 gives them reactive control — "When X happens, do Y."
This unlocks:
- Cross-stickman communication (Stickman A arrives → Stickman B speaks)
- Environmental reactions (Stickman reaches crate → crate explodes)
- Branching narratives (Arrive at different waypoints → different reactions)
Crucially: Phase 4 does not replace or duplicate the Phase 3a Action Queue. Sequential actions for a single stickman (Walk → Wait → Speak → Walk) remain unchanged. Phase 4 adds cross-object reactivity.
2. Core Distinction
| Feature | Phase 3a (Already Works) | Phase 4 (New) |
|---|---|---|
| Walk → Wait → Speak → Walk | ✅ Action Queue | ✅ (unchanged) |
| Waypoint → next action | ✅ Action Runner | ✅ (unchanged) |
| Stickman A arrives → Stickman B speaks | ❌ | ✅ NEW |
| Stickman collides with prop → prop explodes | ❌ | ✅ NEW |
| Stickman enters area → all stickmen react | ❌ | ✅ NEW |
| Multiple reactions per event | ❌ | ✅ NEW |
3. The User's Mental Model
The director should think of events as "When → Then" rules that exist alongside the action queues.
- Action Queue: "Stickman A walks to the crate, waits, then speaks."
- Event Rule: "When Stickman A reaches the crate, Stickman B says 'Welcome!'"
The event rule is not part of Stickman A's queue. It's a separate rule that watches Stickman A and reacts independently.
4. Milestone Breakdown
| # | Milestone | Description |
|---|---|---|
| 4.1 | Event Data Model | Define rule structure and storage. |
| 4.2 | Trigger System | Detect and emit events from stickmen, props, and areas. |
| 4.3 | Event Rule UI | Visual rule builder (When → Then workflow). |
| 4.4 | Trigger Areas | Placeable Area2D sensors. |
| 4.5 | Prop Interaction Events | Prop collisions emit events. |
| 4.6 | Chain Reactions | Multiple actions per rule, executed in sequence. |
| 4.7 | Integration & Polish | Full end-to-end testing, bug fixes, UI polish. |
5. Milestone 4.3: Event Rule UI
5.1. The "When..." Option
The existing action popup is extended with a new section:
┌─────────────────────────────────────────────┐
│ 🚶 Walk To │
│ 💬 Speak │
│ ⏳ Wait │
│ 💥 Ragdoll │
│ 🔄 Recover │
│ ───────────────────────────────────────── │
│ ⚡ When... (opens trigger sub-menu) │
└─────────────────────────────────────────────┘
Design note: The "When..." option is visually separated (line divider) to signal it creates a rule, not a direct action.
5.2. Trigger Sub-Menu
When "When..." is clicked, the popup expands/replaces with trigger types:
┌─────────────────────────────────────────────┐
│ 📍 Arrives at a waypoint │
│ ✅ Completes any action │
│ 💬 Finishes speaking │
│ 🎯 Enters trigger area │
│ 💥 Collides with something │
│ ⬅ Back to actions │
└─────────────────────────────────────────────┘
Each trigger type corresponds to a signal emitted by stickmen or the stage.
5.3. The Rule Building Flow (6 Stages)
┌──────────────┐
│ STAGE 1 │ → User clicks stickman → popup opens
│ IDLE │
└──────┬───────┘
│ Click "When..."
▼
┌──────────────┐
│ STAGE 2 │ → User selects trigger type
│ SELECT_TRIGGER│
└──────┬───────┘
│ (If trigger needs a target: waypoint, area, prop)
▼
┌──────────────┐
│ STAGE 3 │ → User clicks the specific target
│ TARGET_ENTRY │ (e.g., a waypoint dot on the stage)
└──────┬───────┘
│
▼
┌──────────────┐
│ STAGE 4 │ → User selects the action (Speak, Walk, etc.)
│ SELECT_ACTION│
└──────┬───────┘
│ (If action needs a target: a stickman or prop)
▼
┌──────────────┐
│ STAGE 5 │ → User clicks the target stickman/prop
│ TARGET_ENTRY2│
└──────┬───────┘
│ (If action needs params: text, duration, etc.)
▼
┌──────────────┐
│ STAGE 6 │ → User fills in params
│ PARAMS │
└──────┬───────┘
│
▼
┌──────────────┐
│ STAGE 7 │ → Rule is stored. Visuals update.
│ DONE │
└──────────────┘
Escape at any stage cancels rule creation and returns to IDLE.
6. Complete UI Walkthrough: "A Reaches Waypoint → B Speaks"
Step 0: Prerequisites (Edit Mode)
- Stickman A and Stickman B are placed on the stage.
- Stickman A already has a "Walk To" action queued (with a visible waypoint marker on the stage), OR the user is about to create one.
Step 1: Create Stickman A's Walk (If Not Done)
| # | User Action | System Response |
|---|---|---|
| 1 | Click the "Direct" tool button in the palette. | Cursor changes to crosshair. |
| 2 | Click Stickman A on the stage. | Action popup appears. |
| 3 | Click "🚶 Walk To" in the popup. | Popup closes. Stage enters target placement mode. |
| 4 | Click a spot on the stage. | Blue waypoint dot appears. walk_to action added to Stickman A's queue. |
Step 2: Create the Reactive Event Rule
| # | User Action | System Response |
|---|---|---|
| 5 | Click the "Direct" tool again (if it was deselected). | Cursor changes to crosshair. |
| 6 | Click Stickman A on the stage. | Action popup appears with new "When..." option. |
| 7 | Click "⚡ When..." | Trigger sub-menu opens. |
| 8 | Click "📍 Arrives at a waypoint" | Popup closes. Cursor changes to target selector. Status bar: "Click the waypoint you want to trigger on." |
| 9 | Click the blue waypoint dot on the stage. | Waypoint glows green briefly. Popup reappears with trigger confirmed. |
| 10 | Click "💬 Speak" | Popup closes. Cursor changes to target selector. Status bar: "Click the stickman who will speak." |
| 11 | Click Stickman B on the stage. | Stickman B glows yellow. Text dialog appears. |
| 12 | Type "Hello there!" and click [OK] | Dialog closes. Toast: "Rule created!" |
Step 3: Visual Feedback (Edit Mode)
| Element | Appearance | Description |
|---|---|---|
| Dashed line | White dashed line | Connects waypoint to Stickman B. |
| Label | "When arrives → Speak 'Hello there!'" | Centered on the line. |
| Color coding | Green waypoint + orange badge on Stickman B | Shows trigger source and action target. |
| Rule badge | ⚡ icon on the label | Hover shows full rule details. |
| Delete icon | ✕ on the label | Click to remove rule. |
Step 4: Test in Play Mode
| # | User Action | System Response |
|---|---|---|
| 13 | Click "Play" button. | All queues start executing. |
| 14 | Stickman A walks to waypoint. | Normal Phase 3a behavior. |
| 15 | When Stickman A arrives, event fires. | Stickman B says "Hello there!" (speech bubble appears). |
7. Visual Feedback (Edit Mode Only)
7.1. Rule Visualization Elements
| Element | Color/Style | Position |
|---|---|---|
| Trigger badge | Green, small, "⚡" | Near source object. |
| Action badge | Orange, small, "→" | Near target object. |
| Connection line | Dashed white, alpha 0.6 | From source to target. |
| Label | White text on dark background | Centered on line. |
| Waypoint glow | Green (if trigger source) | On the waypoint dot. |
7.2. Rule Interaction
| Action | Behavior |
|---|---|
| Click rule label | Opens edit popup for that rule. |
| Click delete icon | Removes the rule (confirmation optional). |
| Hover rule label | Shows tooltip with full rule details. |
7.3. What the User Sees on the Stage
Stickman A Stickman B
┌──────┐ ┌──────┐
│ 🔵 │ │ 🔵 │
│ (A) │ │ (B) │
└──┬───┘ └──┬───┘
│ │
│ ════════════╗ │
│ (When arrives) │ │
│ ════════════╝ │
│ ── ── ── ── ── ── ── ── →│
│ (Then Speak "Got it!") │
│ │
┌──┴──────────────────────────────────┐│
│ 📍 Waypoint 3 ││
└──────────────────────────────────────┘
8. Event Data Model
8.1. Rule Structure
Rules are stored in the stage's event registry and have three parts:
Trigger — The "When" part.
| Trigger Type | Source | Target | Description |
|---|---|---|---|
arrived_at_waypoint |
Stickman | Waypoint | Stickman completes a walk. |
action_finished |
Stickman | Action type | Stickman finishes any action. |
speech_finished |
Stickman | (none) | Stickman finishes speaking. |
entered_area |
Stickman/Prop | Trigger Area | Object enters a trigger area. |
collided |
Stickman/Prop | Object | Object collides with another object. |
Action — The "Then" part.
| Action Type | Target | Params |
|---|---|---|
walk_to |
Stickman | target (Vector2) |
speak |
Stickman | text (String), duration (float) |
wait |
Stickman | duration (float) |
ragdoll |
Stickman | (none) |
recover |
Stickman | (none) |
explode_prop |
Prop | (none) — future |
spawn_prop |
Stage | type (String) — future |
8.2. Rule Storage
Rules are stored in SandboxStage._event_rules and persist across mode toggles (Play ↔ Edit). They are not saved to disk in Phase 4 (deferred to Phase 5).
8.3. Rule Evaluation
Rules are evaluated in order when an event occurs. If a rule's trigger matches the event, its actions are executed.
9. What's NOT in Phase 4
| Feature | Why Excluded |
|---|---|
| "When Stickman A arrives → Stickman A speaks" | This is just a sequential queue action (Phase 3a). |
| "When Stickman A finishes walking → Stickman A walks again" | Same as above. |
| Conditions (AND/OR logic) | Too complex for Phase 4; deferred to future. |
| Variables / counters | Deferred to future. |
| Save/Load rules to disk | Phase 5. |
| Edit/Delete actions | Phase 3c. |
| Stickman/Prop selector grids | Phase 3b. |
10. Acceptance Criteria
10.1. Cross-Stickman Events
- "When..." option appears in the action popup.
- Trigger sub-menu opens when "When..." is clicked.
- Waypoint trigger works: A arrives → B speaks.
- Action completion trigger works: A finishes speaking → B walks.
- Speech completion trigger works: A finishes speaking → B speaks.
- Multiple actions per rule work: Trigger → B speaks AND C walks.
10.2. Cross-Object Events
- Area trigger works: A enters area → B speaks.
- Prop collision trigger works: A hits crate → crate explodes.
- Prop reaction works: Trigger → prop explodes (disappears + particles).
10.3. UI & Visuals
- Rule label shows summary: "When arrives → Speak" text appears.
- Delete icon works: Click ✕ → rule removed.
- Clicking rule label opens edit popup: Click label → popup re-opens.
- Rules persist across mode toggles: Create rule → Play → Edit → rule still there.
- Rules are cleaned up when source/target objects are deleted.
10.4. Backward Compatibility
- Sequential actions still work: Walk → Wait → Speak → Walk works.
- Existing queues unchanged: Any Phase 3a scene loads and runs.
11. File Changes Summary
| File | Changes |
|---|---|
scripts/sandbox_stage.gd |
Add _event_rules, event evaluation, rule UI state machine. |
scripts/stickman_rig.gd |
Emit arrived, action_finished, speech_finished signals. |
scripts/stage_director_visuals.gd |
Draw rule lines, labels, and badges. |
scripts/trigger_area.gd |
NEW: Placeable Area2D sensor. |
scripts/prop_block.gd |
Emit collided signal. |