Domain Model: Lil Beasties
Diagram
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.md in 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
Key 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.
project-lil-beasties — parent project page
arch-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 islands
story-lil-beasties-progress — earning monsters and unlocking islands
story-lil-beasties-play-anywhere — cross-device play