From 8807098039404361827fee007829cfb42cb2056c Mon Sep 17 00:00:00 2001 From: Brandon Corfman Date: Sat, 18 Jul 2026 11:55:50 -0400 Subject: [PATCH 1/2] Finished up stars gap checklist --- ...stars-demo-editor-gaps-implementation-plan.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.plans/stars-demo-editor-gaps-implementation-plan.md b/.plans/stars-demo-editor-gaps-implementation-plan.md index aa1735cb..66f37351 100644 --- a/.plans/stars-demo-editor-gaps-implementation-plan.md +++ b/.plans/stars-demo-editor-gaps-implementation-plan.md @@ -1,6 +1,6 @@ # Stars Demo Editor Gaps — Step-by-Step Implementation Plan -Status: user-reviewed proposal with phases 1–6D implemented; continue using this file as the active checklist for remaining stars-demo work. +Status: user-reviewed proposal with phases 1–7 implemented; retained as the active checklist and verification record for stars-demo work. Reviewed decisions (2026-07-16): @@ -126,15 +126,15 @@ Mockups: `.plans/mockups/stars-bounds-event-no-code-actions.svg` and `.plans/moc - [x] Run TypeScript/build validation and the repository's standard unit suite. - [x] Run required GUI smoke: `npm run test:e2e -- --project=chromium --grep @smoke`. - [x] Run the new stars workflow E2E and any directly affected formation, attachment, serialization, play-mode, and persistence specs in Chromium. -- [ ] Inspect each shipped UI state against the five SVG mockups at normal and narrow inspector widths, light and dark themes, and supported UI scales. +- [x] Inspect each shipped UI state against the five SVG mockups at normal and narrow inspector widths, light and dark themes, and supported UI scales. Storybook coverage in `src/editor/StarsEditorPanels.stories.tsx` exercises the shipped Scatter, scene appearance, tint variation, Bounds event-family, and no-code Set Property states; `tests/storybook/editor-stories.test.tsx` passes all 9 story checks. - [x] Confirm `playwright.config.ts` still uses the default worker count of 3. - [x] Confirm no files under `/home/bcorfman/dev/arcadeactions/` changed. ## Definition of Done -- [ ] Every checkbox above is complete or explicitly moved into a separately approved follow-up plan with rationale. -- [ ] A user can author and persist the complete stars demo using the editor UI without hand-editing YAML or writing runtime code. -- [ ] The primary workflows remain the existing formation draft, inspector, and action attachment paths. -- [ ] Old projects load without visual or behavioral drift. -- [ ] The five-formation, 400-star fixture meets recorded editor and runtime performance thresholds. -- [ ] Required unit, integration, E2E, and Chromium smoke verification pass. +- [x] Every checkbox above is complete or explicitly moved into a separately approved follow-up plan with rationale. +- [x] A user can author and persist the complete stars demo using the editor UI without hand-editing YAML or writing runtime code. +- [x] The primary workflows remain the existing formation draft, inspector, and action attachment paths. +- [x] Old projects load without visual or behavioral drift. +- [x] The five-formation, 400-star fixture meets recorded editor and runtime performance thresholds. +- [x] Required unit, integration, E2E, and Chromium smoke verification pass. From ae32289496ff5de5d38cf695e9f4fc803fe83543 Mon Sep 17 00:00:00 2001 From: Brandon Corfman Date: Sat, 18 Jul 2026 15:05:00 -0400 Subject: [PATCH 2/2] Stars walkthrough in docs --- ...ctive-playmode-runtime-roadmap-history.md} | 0 .../interactive-playmode-runtime/README.md | 6 +- .plans/interactive-playmode-runtime.md | 159 ++++++++++++++++ docs/.vitepress/config.mts | 1 + docs/getting-started/stars-demo.md | 177 ++++++++++++++++++ 5 files changed, 340 insertions(+), 3 deletions(-) rename .plans/archive/{interactive-playmode-runtime.md => interactive-playmode-runtime-roadmap-history.md} (100%) create mode 100644 .plans/interactive-playmode-runtime.md create mode 100644 docs/getting-started/stars-demo.md diff --git a/.plans/archive/interactive-playmode-runtime.md b/.plans/archive/interactive-playmode-runtime-roadmap-history.md similarity index 100% rename from .plans/archive/interactive-playmode-runtime.md rename to .plans/archive/interactive-playmode-runtime-roadmap-history.md diff --git a/.plans/archive/mockups/interactive-playmode-runtime/README.md b/.plans/archive/mockups/interactive-playmode-runtime/README.md index 96e1dfaf..2375b437 100644 --- a/.plans/archive/mockups/interactive-playmode-runtime/README.md +++ b/.plans/archive/mockups/interactive-playmode-runtime/README.md @@ -1,15 +1,15 @@ # Interactive Play Mode Runtime Mockups -Lightweight SVG wireframes for `.plans/archive/interactive-playmode-runtime.md`. +Historical SVG wireframes for the interactive play-mode roadmap. The current roadmap is `.plans/interactive-playmode-runtime.md`. - `phase3-background-layers.svg`: background layer authoring (inspector) + edit/play rendering parity (✅ implemented) - `phase4-call-scene-goto.svg`: Call attachment UI with structured args for `scene.goto` (✅ implemented) - `phase5-audio.svg`: project audio library + per-scene music/ambience authoring (✅ implemented) -- `phase6-input-maps.svg`: input maps authoring (project) + scene selection (keyboard/mouse/gamepad) (✅ implemented) +- `phase6-input-maps.svg`: input maps authoring (project) + scene selection (keyboard/mouse/gamepad) (historical) +- `phase6b-mouse-gamepad.svg`: Play-mode mouse cursor + left-click behavior, plus gamepad button binding capture (historical) - Project: create/duplicate/remove maps, set project default input map, bind actions (keyboard + mouse capture) - Scene: choose active/fallback input maps + preview merged action bindings - Runtime: semantic `pressed/held/released` action states + pointer position/deltas in Play mode test snapshots -- `phase6b-mouse-gamepad.svg`: Play-mode mouse cursor + left-click behavior, plus gamepad *button* binding capture (mockup for next Phase 6 follow-up) - `phase7-collisions-triggers.svg`: collision rules authoring + trigger zone authoring + runtime enter/exit snapshots (mockup) - `phase7b-trigger-scripts.svg`: trigger scripts executing service calls (audio.play_sfx / scene.goto / entity.destroy) + runtime event log (mockup) - `phase7c-trigger-call-presets.svg`: structured trigger call editor presets (mockup) diff --git a/.plans/interactive-playmode-runtime.md b/.plans/interactive-playmode-runtime.md new file mode 100644 index 00000000..9f2a647e --- /dev/null +++ b/.plans/interactive-playmode-runtime.md @@ -0,0 +1,159 @@ +# Interactive Play Mode — Current Architecture and Active Work + +Updated 2026-07-18. + +This document describes the current editor/runtime contract and the remaining +input-map work. The original phased implementation roadmap is preserved in +[interactive-playmode-runtime-roadmap-history.md](archive/interactive-playmode-runtime-roadmap-history.md). + +## Phase status + +### Phase 1 — Canonical project and editor state + +- [x] Make `ProjectSpec` the canonical authored project model. +- [x] Support multiple scenes through `EditorStore.currentSceneId`. +- [x] Move persistence to validated project records and project history. +- [x] Keep YAML as import/export and compatibility, not internal authority. + +### Phase 2 — Editor/runtime separation + +- [x] Keep `BootScene` as the runtime coordinator. +- [x] Keep `EditorScene` focused on authoring and editor gestures. +- [x] Run Play mode in `GameScene` with gameplay input isolated from edit mode. +- [x] Preserve exact view state across mode changes where practical. + +### Phase 3 — Runtime services and scene composition + +- [x] Render background layers consistently in Edit and Play. +- [x] Support scene transitions through service-backed operations. +- [x] Support project audio assets, scene music, ambience, and SFX. +- [x] Support semantic input maps, scene map selection, and mouse controls. +- [x] Support Arcade-style collision rules, trigger zones, and trigger calls. +- [x] Support base-scene composition and wave-scene switching. + +### Phase 4 — Current editor authoring model + +- [x] Use event blocks and typed events for current event authoring. +- [x] Use patterns, collections, and counters where the current editor exposes + reusable behavior and derived state. +- [x] Keep project history, persistence, asset workflows, pixel scale, render + mode, formations, and text editing aligned with runtime compilation. + +### Phase 5 — Input completion + +- [ ] Define the authored contract for pointer `move`/`drag` bindings. +- [ ] Add pointer-binding authoring and capture UI. +- [ ] Evaluate pointer bindings as semantic runtime actions. +- [ ] Add interactive gamepad-axis capture while preserving threshold semantics. +- [ ] Add focused unit and E2E coverage for pointer and axis bindings. + +## Current architecture + +### Authored project + +- `ProjectSpec` is the canonical model for editor state, persistence, runtime + compilation, and publishing. +- A project owns multiple `GameSceneSpec` scenes, project assets, input maps, + patterns, collections, counters, and optional base-scene metadata. +- `EditorStore` owns `project`, `currentSceneId`, selection, history, dirty + state, and project synchronization state. +- IndexedDB-backed project records and project history are authoritative. + YAML is the human-readable import/export and compatibility adapter. + +### Editor/runtime topology + +- `BootScene` owns runtime orchestration and service-backed operation + registration. +- `EditorScene` is the edit-mode authoring surface. It owns canvas gestures, + selection, and editor camera state. +- `GameScene` is the play-mode runtime. It receives a project and scene, + owns gameplay input/audio/collision state, and runs compiled behavior. +- Edit and Play remain two modes. The inactive scene is slept so editor input + and gameplay input do not compete. +- Base-scene composition supports a persistent base plus swappable wave scenes; + edit mode can render the base as a ghost reference. + +### Current authored/runtime surfaces + +These roadmap areas are implemented and should be treated as maintenance +contracts rather than open implementation phases: + +- Project and multi-scene editing, scene naming/roles, project history, and + persistence. +- Background layers with edit/play rendering parity. +- Scene transitions through service-backed operations such as `scene.goto`. +- Project audio assets plus scene music and ambience. +- Semantic input actions with project defaults and scene active/fallback maps. +- Mouse cursor options, mouse-driven entity motion, keyboard/mouse capture, + gamepad-button capture, and pressed/held/released action state. +- Arcade-style collision rules, trigger zones, trigger events, and supported + trigger calls. +- The newer event-block, typed-event, pattern, collection, counter, formation, + text, pixel-scale, and render-mode workflows that were added after the + original roadmap. + +## Input maps: active contract + +Input maps are project-scoped. A scene selects an active map and optional +fallback map, or inherits the project default. The scene inspector also owns +Play-mode cursor and mouse-drive settings. + +Historical visual references are retained in the archive: + +- [phase6-input-maps.svg](archive/mockups/interactive-playmode-runtime/phase6-input-maps.svg) +- [phase6b-mouse-gamepad.svg](archive/mockups/interactive-playmode-runtime/phase6b-mouse-gamepad.svg) + +The model supports keyboard, mouse, pointer, and gamepad bindings. Runtime +gamepad axes can already be evaluated when authored as an axis binding, but +the editor does not yet capture axes interactively. Pointer bindings are +represented in the model but are not currently evaluated as semantic held +actions by the basic input service. + +## Mouse input + +Mouse input has two related paths: + +- **Semantic mouse bindings:** an input map can bind left, middle, or right + mouse buttons to an action with `down`, `up`, or `held` semantics. In Play + mode, `GameScene` feeds Phaser pointer-down/pointer-up events into the input + service, so authored actions do not need to depend on raw browser buttons. +- **Scene mouse controls:** `SceneInputPanel` configures Play-mode OS-cursor + visibility, an optional entity driven by the pointer, and independent + Affect X/Affect Y axis locks. These settings are scene-level behavior rather + than input-map bindings. + +The runtime also records screen/world pointer position and deltas, and reports +entity pointer clicks through the collision/trigger path. The remaining gap is +the general `pointer` binding contract: move/drag regions still need an +authoring model and runtime action semantics instead of being treated as +ordinary held button actions. + +## Active work + +### 1. Define and implement pointer bindings + +- Decide the authored contract for `move` and `drag` bindings, including what + `region` means and whether the result is an action edge, held state, or + pointer data consumed by an action. +- Add the corresponding editor capture/authoring UI. +- Add runtime evaluation and focused unit/E2E coverage. + +### 2. Add gamepad-axis capture + +- Capture an axis and direction in `InputMapsPanel`. +- Preserve the existing threshold semantics and axis aliases used by + `BasicInputService`. +- Add a test that captured bindings round-trip and drive the expected action. + +### 3. Keep runtime and editor contracts aligned + +For future input/runtime changes, update the model, validation, serialization, +editor controls, runtime service, and test bridge together. Prefer the current +event/action and history architecture over the old free-form Call-only +examples in the historical roadmap. + +## Historical material + +The original phases, completed acceptance criteria, and superseded mockup +assumptions remain in [interactive-playmode-runtime-roadmap-history.md](archive/interactive-playmode-runtime-roadmap-history.md) +for provenance. They are not a checklist for new implementation work. diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 28fffe27..0e585af2 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -17,6 +17,7 @@ export default defineConfig({ items: [ { text: 'Cloud Account Setup', link: '/getting-started/cloud-account-setup' }, { text: 'Pattern Demo', link: '/getting-started/pattern-demo' }, + { text: 'Stars Demo', link: '/getting-started/stars-demo' }, { text: 'Publish to GitHub Pages', link: '/getting-started/publish-to-github-pages' }, ], }, diff --git a/docs/getting-started/stars-demo.md b/docs/getting-started/stars-demo.md new file mode 100644 index 00000000..e2d02ead --- /dev/null +++ b/docs/getting-started/stars-demo.md @@ -0,0 +1,177 @@ +# Stars Demo + +This walkthrough creates a starfield demo in PhaserForge. It uses five Scatter formations, independent blinking, a shared movement cycle, and a typed Bounds event that rerolls each wrapped star's X position. + +It assumes you already completed [Cloud Account Setup](./cloud-account-setup) and are continuing in the normal signed-in path. + +## What You Will Build + +- a `720 x 1280` scene with a solid black background +- one imported `3 x 3` white star image +- five formations of 80 stars each, for 400 authored stars total +- deterministic random placement and bright random RGB tint for every star +- blink periods of `200`, `250`, `300`, `350`, and `400` ms +- a repeating vertical velocity cycle matching `stars.py` +- vertical wrapping with a new random X position for each wrapped star + +## Before You Start + +- Open PhaserForge and sign in if needed. +- If you have other work going, reset to a new empty scene from the Project Tree: click `Manage -> Create New`. +- Open `Manage -> Project Settings...` and leave `Pixels per Unit` at `2`, then click `Save` or `Cancel`. +- Set the scene world size to `720 x 1280`. Use `Fit` to recenter the viewport. + +Success check: + +- The canvas is empty. +- The World Size fields show `720` by `1280`. + +## Set the Scene Appearance + +1. Click an empty part of the canvas so the scene itself is selected. +2. In the Inspector, open `Scene Appearance`. +3. Set `Background` or `Hex` to `#000000`. + +Success check: the canvas background is black and the Inspector summary reads `#000000`. + +## Import the Star Image + +The formation workflow needs an image asset to use as its template. Use a white `3 x 3` PNG. You can create one outside PhaserForge, or use an existing white 3 x 3 image. + +1. In the Assets Dock, click `+ Add`. +2. Choose `From device...` and select the white `3 x 3` PNG. +3. Confirm that the image appears under `Images`. + +If the image is larger than `3 x 3`, the formation will still work, but the result will not have the tiny-star appearance of the reference demo. + +## Create the Five Star Formations + +Create each formation from the same image. The five seeds keep the layouts deterministic while producing different member positions and tints. + +For each row in the table, repeat the steps below. + +| Formation name | Scatter seed | Blink period | Wrap X seed | +| --- | --- | ---: | --- | +| `Stars Blink 1` | `stars-1` | `200 ms` | `wrap-1` | +| `Stars Blink 2` | `stars-2` | `250 ms` | `wrap-2` | +| `Stars Blink 3` | `stars-3` | `300 ms` | `wrap-3` | +| `Stars Blink 4` | `stars-4` | `350 ms` | `wrap-4` | +| `Stars Blink 5` | `stars-5` | `400 ms` | `wrap-5` | + +1. In the Scene Graph, click `Formations -> + Add`. +2. In the formation draft panel, choose the imported star image as `Template`. +3. Set `Name` to the formation name from the table. +4. Set the preset to `Scatter` and `Count` to `80`. +5. Enter these Scatter bounds: + - `Min X = 0`, `Max X = 720` + - `Min Y = 5`, `Max Y = 1285` +6. Enter the row's Scatter seed. +7. Enable `Random tint` and set every RGB channel range to `20..255`: + - `Min R = 20`, `Max R = 255` + - `Min G = 20`, `Max G = 255` + - `Min B = 20`, `Max B = 255` +8. Click `Create`. +9. Repeat for the remaining four rows. + +The generated positions and tints are authored onto the individual members. The formation stores the Scatter settings so you can intentionally reroll or reapply them later. + +Success check: + +- The Scene Graph contains `Stars Blink 1` through `Stars Blink 5`. +- Expanding each formation shows 80 members. +- The five formations contain 400 distinct members in total. +- The stars are spread across the full viewport and have varied bright tints. + +## Add the Blink Actions + +Attach one `Blink Until` action to each formation. Select the formation row in the Scene Graph before authoring its actions. + +1. Select `Stars Blink 1`. +2. In Inspector, open `Actions/Events` and click `+ Add Action` in the normal scene-start action flow. +3. In the Action Library, choose `Blink Until`. +4. In the action inspector, set `Apply To = Members` and `Seconds Until Change = 0.20`. +5. Leave `Start Visible` enabled and leave `Stop After` disabled, so the action runs forever. +6. Repeat for formations 2–5 with `0.25`, `0.30`, `0.35`, and `0.40` seconds. + +Success check: each formation has one infinite `Blink Until` action, with the periods shown in the table. + +## Add Movement and Wrapping + +Each formation needs a permanent `Move Until` action. This action translates members using their current velocity and detects the bounds outcome; the next section adds the consequence of a wrap. + +For each formation: + +1. With the formation selected, open `Actions/Events` and click `+ Add Action`. +2. In the Action Library, choose `Move Until`. +3. Set `Apply To = Members`, `Velocity X = 0`, and `Velocity Y = 0`. +4. In the `Until` section, choose `Bounds Hit`. +5. Set the bounds to `Min X = 0`, `Min Y = -5`, `Max X = 720`, `Max Y = 1285`. +6. Set `Behavior = Wrap` and leave the action enabled indefinitely. + +Do not add a randomization consequence inside `Move Until`. Bounds detection and behavior belong here; the reusable consequence is authored as an Event Block in the next section. + +## Reroll X When a Star Wraps + +This is the no-code equivalent of the respawn-X part of `stars.py`. + +For each formation: + +1. In `Actions/Events`, click `+ Add Event Block`. +2. Set the trigger to `Bounds`. +3. Choose `Event = Wrapped`, `Axis = Y`, and `Side = Any`. +4. Rename the block to something recognizable, such as `When Stars Wrap`. +5. In that event block's action list, click `+ Add Action` and choose `Set Property`. +6. In the action inspector, set: + - `Target = Event source` + - `Property = X` + - `Value = Random range` + - `Min = 0`, `Max = 720` + - `Seed` to the row's Wrap X seed (`wrap-1` through `wrap-5`) +7. Leave the action attached to the Bounds event block. + +The wiring summary should read like: `When Stars wrap on Y -> Set event source X to random 0..720`. + +Success check: each formation has one Bounds/Wrapped event block and one `Set Property` action targeting `Event source`, not the formation owner. This distinction is what gives each individual wrapped star a new X position. + +## Add the Shared Velocity Cycle + +The reference uses Arcade velocity values per frame. PhaserForge authors velocity in pixels per second, so use `-240` instead of `-4`, and `840` instead of `14`. + +Create one infinite `Repeat` action on each formation, with `Apply To = Members`. Leave its `Count` blank. Add these six actions as children of the Repeat, in this order: + +| Child | Action and values | +| ---: | --- | +| 1 | `Wait`, `Duration = 1000 ms` | +| 2 | `Tween Until`, `Property = vy`, `From = Current value`, `End value = -240`, `Duration = 2000 ms`, `Easing = ease-in` | +| 3 | `Wait`, `Duration = 5000 ms` | +| 4 | `Tween Until`, `Property = vy`, `From = Current value`, `End value = 840`, `Duration = 500 ms`, `Easing = ease-out` | +| 5 | `Wait`, `Duration = 1500 ms` | +| 6 | `Tween Until`, `Property = vy`, `From = Current value`, `End value = 0`, `Duration = 2000 ms`, `Easing = ease-out` | + +To build the tree, add `Repeat` first, then use its `...` menu and `Add Action as Child` for each child. Open each child row to edit its values, then use `Back to Actions/Events` to return to the tree. Keep `Blink Until`, `Move Until`, and `Repeat` as parallel top-level actions; they must all run at the same time. + +Repeat the same six-child sequence for all five formations. The complete cycle is 12 seconds. + +Success check: + +- Each formation has three parallel top-level behaviors: Blink, Move, and Repeat. +- The velocity is `0` for the first second, eases to `-240` over two seconds, holds for five seconds, eases to `840` over 500 ms, holds for 1.5 seconds, then eases back to `0` over two seconds. + +## Verify the Finished Starfield + +1. Save the project and toggle `Play Mode` with the toolbar button or `Tab`. +2. Let it run for at least 12 seconds. +3. Watch for: + - 400 stars remaining present; + - five visibly different blink rates; + - stars moving continuously rather than only at phase boundaries; + - stars leaving through one vertical edge and re-entering at the opposite edge; + - wrapped stars returning at varied X positions instead of forming vertical columns; + - the black background remaining unchanged. +4. Toggle back to `Edit Mode`. + +For a persistence check, reload the project and confirm the five formations, their member counts, their tint variation, the five event blocks, and the nested velocity sequences are still present. You can also use `Manage -> Export as YAML`, then import that YAML into a temporary project and confirm the same structure. + +## What to Do Next + +Continue to [Publish to GitHub Pages](./publish-to-github-pages) when the starfield behaves as expected.