Lil Beasties
Notes
Project Page 1
-
Lil Beasties
project-lil-beastiesVision
A monster music game for kids — choose monsters, place them on islands, and hear them perform together. Each monster plays a different musical part (beat, bass, melody, harmony, percussion, vocal). Complete performances to win new monsters and unlock new islands. Built with Rails 8 + Phaser 4. Duolingo aesthetic. Deploy through the pal-e pipeline, wrap for App Store with Hotwire Native.
User Stories
Key Story Note Role Success Metric perform Perform Music Kid Place 3 monsters, hear them play music together progress Progress Through Islands Kid Complete island 1, win monster, unlock island 2 play-anywhere Play Anywhere Player Same progress on phone and desktop Architecture
- Domain Model — monsters with musical parts, islands as levels, placement grid
- Data Flow — Rails API + Phaser game loop + audio layering (to be created)
- Deployment — k3s + ArgoCD + Harbor (to be created)
Key decisions:
- Rails 8 monolith — game state, auth, API all in one app
- Phaser 4 in Stimulus controllers — sprites, game loop, audio, touch input at 60fps
- Six musical parts (beat, bass, melody, harmony, percussion, vocal) — same BPM/key, any combo works
- One monster per part per island — no stacking, enforced by Placement validation
- Earn monsters through performance, not purchase — progression drives collection
- Islands are levels — each one is a new stage for building a new song
- Island-first landing — kids see their current island immediately after login
- Hotwire Native for iOS App Store wrapper
- Keycloak for auth (existing platform SSO)
Board
Status
2026-06-06: Tone.js audio stack documented (PR #9 merged). Phaser handles visuals only, Tone.js owns AudioContext + Transport for beat-synced loop playback. All docs aligned: architecture, user-stories, music-theory. Issues #1-3, #7 updated with part/sound/vibe terminology + Tone.js references. Next: scaffold Rails app (Issue #1).
Milestones
Milestone Issues Gate Status M1: Playable prototype #1 Scaffold + #2 Phaser island + #3 Sprites Place 3 monsters on an island, hear them play music Not started M2: Progression loop #7 Island progression + monster rewards Complete island 1, win monster, unlock island 2 Not started M3: Ship it #4 Keycloak auth + #5 Deploy pipeline Live on cluster, accessible via Tailscale Funnel Not started Repos
Repo Platform Role Status lil-beasties Forgejo Rails 8 + Phaser 4 monolith Active
Architecture 1
-
Domain Model: Lil Beasties
arch-domain-lil-beastiesDomain Model: Lil Beasties
Diagram
erDiagram Player ||--o{ PlayerMonster : owns Player ||--o{ Island : "progresses through" Monster ||--o{ PlayerMonster : "instance of" PlayerMonster ||--o{ Placement : "placed as" Island ||--o{ Placement : contains Player { string username string uid string provider integer current_level } Monster { string name enum musical_part integer level_unlocked string sprite_key string sound_key } PlayerMonster { references player_id references monster_id datetime acquired_at } Island { string name string theme integer level_number integer grid_width integer grid_height boolean completed references player_id } Placement { references player_monster_id references island_id integer grid_x integer grid_y }Components
Component Purpose Notes Player User account linked to Keycloak SSO uid/provider from OmniAuth. current_level tracks progression. Monster Shared catalog -- each monster is a (part, sound, vibe) tuple musical_part (enum) = role in the song. sound_key = audio loop variant. sprite_key = visual personality. Multiple vibes per part. level_unlocked controls when it enters the catalog. PlayerMonster Ownership join -- player has earned this monster Created when player completes an island. First monster chosen at game start via audition. Island A performance stage -- the level the kid plays Completed when 3+ of 6 parts are filled. Each island has a visual theme. Created sequentially as player progresses. Placement A monster placed at a grid position on an island Unique constraint on [island_id, grid_x, grid_y]. Enforces one monster per musical_part per island. Musical Parts
Every monster has three properties: part (role in the song), sound (audio loop variant), and vibe (visual personality). Multiple monsters can share a part but have different sounds and vibes. All audio: 120 BPM, C major, 4-bar seamless loops. One monster per part per island — no stacking. See
docs/music-theory.mdin repo for the full audio design.Part Sound Monster Vibe beat Kick, snare pattern Stompy rock monster bass Low-end groove Big round belly monster melody Lead tune Singing bird-like monster harmony Chords, pads Floaty cloud monster percussion Shakers, clicks, fills Spiky bug monster vocal Oohs, ahhs, chants Little mouth monster Gameplay Loop
flowchart TB START[Game start] --> CHOOSE[Choose first monster] CHOOSE --> ISLAND[Go to Island 1] ISLAND --> PLACE[Place monsters on grid] PLACE --> PERFORM[Monsters play their parts together] PERFORM --> COMPLETE{Enough parts filled?} COMPLETE -->|No| PLACE COMPLETE -->|Yes| WIN[Win new monster!] WIN --> NEXT[Unlock next island] NEXT --> ISLAND2[Go to new island] ISLAND2 --> PLACEKey Decisions
- Part / sound / vibe model: Six parts define the roles; sound and vibe are paired variants within each part. Kids pick personality, the system guarantees musicality.
- One per part per island: Prevents stacking. Gives the kid a reason to collect different types. Enforced at the Placement level.
- Audition before placing: Kids preview a monster's sound before committing to a placement.
- 3 of 6 to complete: Minimum viable song is beat + bass + melody. All 6 is the goal but not required.
- Earn, don't buy: Monsters are rewards for completing islands. No shop, no coins.
- Islands are levels: Each island has a theme. Completed when 3+ parts are filled. Unlocks the next island.
- Monster as catalog: Shared table, seeded on deploy. level_unlocked controls catalog growth. Starts with 6 (one per part), grows to multiple vibes per part.
- Grid-based placement: Integer x/y on a fixed grid. Uniqueness constraint is the collision detection.
- Client-side rendering: Phaser runs on the user's device (WebGL/Canvas). Rails serves game state via API.
- No user table — Keycloak owns identity: Player stores uid/provider from OmniAuth. No passwords, no emails.
Related
project-lil-beasties— parent project pagearch-dataflow-lil-beasties— how data moves at runtime (to be created)arch-deployment-lil-beasties— where services run (to be created)story-lil-beasties-perform— performing music on islandsstory-lil-beasties-progress— earning monsters and unlocking islandsstory-lil-beasties-play-anywhere— cross-device play
User Story 3
-
Progress Through Islands
story-lil-beasties-progress## story: Progress Through Islands ### Role Kid (Lucas's child) ### Key progress ### Want As a **kid**, I want to **complete islands by filling musical parts and unlock new islands** ### So That So that **I can earn new monster vibes and build new songs** ### Acceptance Criteria - Islands are levels with a level_number and theme - Placing enough monsters (3+ of 6 parts) completes the island - Completing an island rewards a new monster (new vibe for an existing part) - Completing an island unlocks the next island - Later islands unlock more vibes per part -- kids gain expressive range as they progress - Player's current_level tracks progression - Monster.level_unlocked controls catalog growth across levels ### Success Metric Complete island 1, win monster, unlock island 2. ### Related Architecture - `arch-domain-lil-beasties` -- Island.level_number, Island.completed, Monster.level_unlocked ### Related - `project-lil-beasties` -- parent project page - `board-lil-beasties` -- project board - `docs/music-theory.md` in repo -- completion threshold, catalog growth
-
Perform Music
story-lil-beasties-perform## story: Perform Music ### Role Kid (Lucas's child) ### Key perform ### Want As a **kid**, I want to **place monsters on an island and hear them play music together** ### So That So that I can **compose my own songs by choosing which monsters perform** ### Acceptance Criteria - Player can browse available monsters per part, each with a distinct sound and vibe - Player can audition a monster (tap preview, monster opens mouth, plays a sample) - Player can place a monster on an island grid slot for its part - Each placed monster plays its audio loop; loops layer together (120 BPM, C major) - One monster per musical part per island (no stacking the same role) - Multiple vibe options per part give kids a choice within each role - Monsters play idle and singing animations at 60fps - Touch input works for placing/moving monsters on mobile ### Success Metric Place 3 monsters, hear them play music together. ### Related Architecture - `arch-domain-lil-beasties` -- Monster.musical_part, Monster.sound_key, Monster.sprite_key, Placement, Island ### Related - `project-lil-beasties` -- parent project page - `board-lil-beasties` -- project board - `docs/music-theory.md` in repo -- part/sound/vibe model, audio constraints
-
Play Anywhere
story-lil-beasties-play-anywherestory: Play Anywhere
Role
Player (kid or parent)
Key
play-anywhere
Want
As a player, I want to play on my phone or computer with my progress saved
So That
So that I can pick up where I left off on any device
Acceptance Criteria
- Player can log in via Keycloak SSO
- Island progress and monster collection persist across sessions and devices
- App is deployed and accessible via browser
- Responsive design works on mobile and desktop
- Health check endpoint returns 200
Success Metric
Player completes island 1 on phone, opens desktop, sees the same progress and collection.
Related Architecture
arch-deployment-lil-beasties— k3s + ArgoCD deploymentarch-domain-lil-beasties— Player entity, Keycloak integration
Related
project-lil-beasties— parent project pageboard-lil-beasties— project board
Review 2
-
Review: Scaffold Rails 8 app + data model (re-review)
review-1329-2026-06-05-r2Verdict: APPROVED
Re-review of board item #1329 after refinement. Previous review (
review-1329-2026-06-05) returned NEEDS_REFINEMENT with 5 findings. All 5 have been addressed.Previous Findings Resolution
- [x] Database conflict -- RESOLVED. Issue now says "PostgreSQL for dev via docker-compose per rails-base pattern." Constraints section updated. Aligns with
rails-base/docker-compose.yml(postgres:17-alpine). - [x] Dockerfile clarification -- RESOLVED. File Targets entry now reads: "Dockerfile -- production container only (dev uses docker-compose with Harbor base image, no Dockerfile needed)." AC updated to "Production Dockerfile builds successfully."
- [x] Multi-database clarification -- RESOLVED. Constraints section now says "Multi-database (Solid Cache/Queue/Cable) is production config -- dev uses single PostgreSQL database." Matches
rails-base/docs/multi-database.md. - [x] Architecture note -- RESOLVED.
arch-domain-lil-beastiesnote created with full ER diagram (Mermaid), Components table, Key Decisions, and Related links. Active status, tagged architecture. Project page Architecture section links to it. - [x] Story note -- RESOLVED.
story-lil-beasties-collectnote exists (was created with the project, predating the first review). Contains Role, Key, Want, So That, Acceptance Criteria, Success Metric, Related Architecture. Active status, tagged user-story. Project page user-stories table links to it correctly.
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Standalone
- [x] Repo -- ldraney/lil-beasties
- [x] User Story -- present, well-formed
- [x] Context -- thorough, includes data model relationships and UX flow
- [x] File Targets -- 12 files listed (11 to create + 1 Dockerfile for production)
- [x] Acceptance Criteria -- 11 criteria, all verifiable
- [x] Test Expectations -- 4 test items + run command (
docker compose run web rails test) - [x] Constraints -- 5 constraints, clear boundaries
- [x] Checklist -- present
- [x] Related -- references project-lil-beasties and arch-domain-lil-beasties
Traceability
- [x] story:collect label -- Collect Monsters
- [x] story note verified --
story-lil-beasties-collectexists in pal-e-docs, active, properly structured - [x] story entry on project page --
project-lil-beastiesuser-stories table has "collect" row linking tostory-lil-beasties-collect - [x] arch:rails-monolith label -- present on board item
- [ ] arch note partial --
arch-domain-lil-beastiesexists (domain model), but noarch-rails-monolithnote exists. The label references "rails-monolith" as the architecture component, but the backing note covers the domain model, not the monolith architecture itself. This is a minor naming mismatch -- acceptable for a greenfield project where the domain model IS the first architectural artifact. Non-blocking advisory: consider creatingarch-rails-monolithwhen deployment architecture is defined (ticket #5), or relabel toarch:domain-lil-beasties. - [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/lil-beasties/issues/1, open
File Targets
- [x] All 12 file targets are new files to create -- repo contains only README.md (confirmed via Forgejo API). Greenfield scaffold.
- [x]
docker-compose.yml-- source template confirmed at~/rails-base/docker-compose.yml(postgres:17-alpine, Harbor ruby-rails-build image, port 9999) - [x] Dockerfile -- clarified as production-only. No template in rails-base (confirmed:
~/rails-base/Dockerfiledoes not exist), so agent must write from scratch. Acceptable -- production Dockerfile is project-specific. - [x] Rails models, controller, views, routes, seeds -- standard rails generate targets
Repo Placement
OK -- Forgejo issue filed on ldraney/lil-beasties, ticket targets same repo. Single-repo scope.
Dependencies
- No blocking dependencies -- this is the first ticket on the board (standalone, foundational).
- Board item #1330 (Integrate Phaser 4 + first island scene) depends on this ticket -- needs Rails app and islands#show view.
- Board item #1332 (Keycloak auth integration) depends on this ticket -- issue references "auth wiring comes in #4, stub for now."
- Dependencies are implicitly documented in constraints ("Root route must redirect to login if unauthenticated (auth wiring comes in #4, stub for now)"). Sufficient for a greenfield project.
Acceptance Criteria
- [x] All 11 criteria are concrete and agent-verifiable
- [x] Test commands are real:
docker compose run web rails test - [x] Multi-database now correctly scoped to production config
- [x] No missing criteria for the stated scope
Blast Radius
- Greenfield project -- no existing consumers affected.
- Database conflict resolved -- now aligned with rails-base platform standard (PostgreSQL for dev).
- No downstream risks for this scaffold ticket.
Decomposition Assessment
- 12 file targets in 1 repo, 11 acceptance criteria, 4 test expectations
- Borderline by raw numbers, but this is a
rails newscaffold -- most files are generated by rails commands, not hand-written - Agent workflow is sequential: copy docker-compose, rails new, generate models, configure routes, write seeds, write tests
- No decomposition needed -- a single focused agent pass with rails generators can complete this
Recommendations
No action needed. All previous findings resolved. One non-blocking advisory noted in Traceability (arch label naming mismatch).
- [x] Database conflict -- RESOLVED. Issue now says "PostgreSQL for dev via docker-compose per rails-base pattern." Constraints section updated. Aligns with
-
Review: Scaffold Rails 8 app + data model
review-1329-2026-06-05Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Standalone
- [x] Repo -- ldraney/lil-beasties
- [x] User Story -- present
- [x] Context -- present, thorough
- [x] File Targets -- 12 files listed
- [x] Acceptance Criteria -- 11 criteria
- [x] Test Expectations -- 4 test items + run command
- [x] Constraints -- present
- [x] Checklist -- present
- [x] Related -- present
Traceability
- [x] story:collect label -- Collect Monsters
- [x] story entry on project-lil-beasties user-stories table -- "collect" row exists, links to story-lil-beasties-collect
- [ ] story note MISSING -- story-lil-beasties-collect note does not exist in pal-e-docs. [SCOPE] Create story note story-lil-beasties-collect.
- [x] arch:rails-monolith label -- Rails monolith component
- [ ] arch note MISSING -- no arch-rails-monolith note found in pal-e-docs. [SCOPE] Create architecture note arch-rails-monolith.
- [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/lil-beasties/issues/1, open
File Targets
- [x] All 12 file targets are new files to create -- repo currently contains only README.md. Greenfield scaffold, no existing-file verification needed.
- [ ] Dockerfile -- ISSUE: rails-base/docs/starting-a-new-project.md says "No Dockerfile needed for dev" and uses docker compose with a pre-built ruby-rails-build image from Harbor. If the ticket intends a production Dockerfile, this needs clarification. [BODY] Clarify whether Dockerfile is for production only, or remove if dev uses docker-compose with base image.
Repo Placement
OK -- Forgejo issue filed on ldraney/lil-beasties, ticket targets same repo. Single-repo scope.
Dependencies
- No blocking dependencies -- this is the first ticket on the board (standalone, foundational).
- Board item #1330 (Integrate Phaser 4 + first island scene) depends on this ticket -- it needs the Rails app and islands#show view to mount Phaser onto.
- Board item #1332 (Keycloak auth integration) depends on this ticket -- the issue references "auth wiring comes in #4, stub for now."
- Dependencies are implicitly documented in the constraints section ("Root route must redirect to login if unauthenticated (auth wiring comes in #4, stub for now)") but not explicitly listed as blocked-by/blocks relationships.
Acceptance Criteria
- Criteria are concrete and verifiable by an agent.
- "App boots and passes rails test" is a real, runnable command.
- However: AC says "Multi-database configured: primary + solid_cache + solid_queue + solid_cable" but the rails-base multi-database doc shows this as a production-only concern. Dev uses a single database. The AC should clarify this is production config only.
Blast Radius
- Greenfield project -- no existing consumers affected.
- Constraint conflict: ticket says "Use SQLite for dev, PostgreSQL for prod" but rails-base pattern uses PostgreSQL for both dev and prod via docker-compose. The docker-compose.yml in rails-base runs a PostgreSQL container for dev. Using SQLite for dev would diverge from the platform standard and could cause dev/prod parity issues. [BODY] Resolve database conflict: align with rails-base pattern (PostgreSQL for dev via docker-compose) or document why SQLite is preferred for this project.
Decomposition Assessment
- 12 file targets in 1 repo
- 11 acceptance criteria
- 4 test expectations
- Estimated agent work: well beyond 5 minutes -- generating a full Rails app, creating 5 models with migrations, seeds, routes, controller, view, Dockerfile, and database config is substantial.
- However: this is a rails new scaffold + model generation. Most file targets are generated by rails commands (rails new, rails generate model), not hand-written. The agent workflow is sequential: generate app, generate models, configure routes, write seeds. This can be done in a single focused pass if the agent runs rails generators inside docker compose.
- Recommendation: borderline. The high file/AC count is inflated because rails new generates most of them. A skilled agent running generators can complete this in one pass. No decomposition needed IF the scope conflicts below are resolved first.
Recommendations
- [SCOPE] Create story note
story-lil-beasties-collectin pal-e-docs -- the project user-stories table links to it but it does not exist. - [SCOPE] Create architecture note
arch-rails-monolithin pal-e-docs -- the board item has the label but no backing note. - [BODY] Resolve database conflict in Constraints section: ticket says "Use SQLite for dev" but rails-base platform pattern uses PostgreSQL for dev via docker-compose. Pick one and update the ticket.
- [BODY] Clarify Dockerfile file target: rails-base says "No Dockerfile needed for dev" and uses a pre-built Harbor image. If this is a production Dockerfile, label it as such. If not needed, remove from file targets.
- [BODY] Clarify multi-database AC: specify this is production config; dev uses single database per rails-base/docs/multi-database.md.
Board 1
-
Lil Beasties
board-lil-beastiesNo content
Repos 1
-
lil-beastiesactive