Skip to content

feat: add Flutter + Flame engine specialists (4 agents) - #92

Open
quangdao0809 wants to merge 18 commits into
Donchitos:mainfrom
quangdao0809:main
Open

feat: add Flutter + Flame engine specialists (4 agents)#92
quangdao0809 wants to merge 18 commits into
Donchitos:mainfrom
quangdao0809:main

Conversation

@quangdao0809

Copy link
Copy Markdown

Summary

  • Adds Flutter + Flame as a supported engine option alongside Godot, Unity, and Unreal
  • 4 new agent definition files: flame-specialist (primary), flame-widget-specialist, flame-shader-specialist, flame-audio-specialist
  • Each agent follows the same collaboration-protocol and delegation-map pattern as existing engine specialists
  • setup-engine skill updated with Flutter+Flame engine option, honest tradeoffs, Dart naming conventions, routing table, and knowledge-gap cutoff (Flutter 3.19 / Dart 3.3 / Flame 1.14)
  • agent-roster.md, agent-coordination-map.md, and CLAUDE.md updated consistently

Sub-specialist coverage

Agent Owns
flame-specialist FlameGame lifecycle, component system, camera/world, collision detection, input routing
flame-widget-specialist Flutter widget layer, GameWidget overlays, HUD, state management (Riverpod/Bloc)
flame-shader-specialist Fragment shaders (.frag GLSL), FragmentProgram API, SpriteBatch, particle systems
flame-audio-specialist flame_audio, BGM lifecycle, SFX pooling, iOS/web platform audio quirks

Test plan

  • Run /setup-engine flutter-flame — verify guided mode surfaces Flutter+Flame as option
  • Run /setup-engine flutter 1.0 — verify CLAUDE.md template and routing table are written correctly
  • Spawn flame-specialist agent — verify collaboration protocol and delegation map work
  • Verify agent-roster.md Engine Leads table includes flame-specialist

🤖 Generated with Claude Code

…b-specialists)

Adds full Flutter+Flame support to the game studio architecture:
- 4 new agent files: flame-specialist (primary), flame-widget-specialist,
  flame-shader-specialist, flame-audio-specialist
- setup-engine skill updated with Flutter+Flame engine option, honest tradeoffs,
  Dart naming conventions, routing table, and knowledge gap cutoff
- agent-roster.md and agent-coordination-map.md updated with Flutter+Flame section
- CLAUDE.md agent count bumped to 53 and engine options updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@quangdao0809
quangdao0809 requested a review from Donchitos as a code owner June 24, 2026 10:28
QuangDao and others added 17 commits July 18, 2026 07:33
…ource, tests)

Brings 483 previously-uncommitted files under version control: full GDD set,
ADRs, architecture docs, production/epics, Flutter+Flame source (src/lib),
platform scaffolding (iOS/macOS/Android/web), and test suites. This work was
accumulating only on local disk with no git history.

Firebase client config files (GoogleService-Info.plist, google-services.json)
are excluded via .gitignore — they identify the Firebase project and are kept
local rather than committed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…pproval-001..006,008)

Implements ParentApprovalRepository.approveTask()/rejectTask() per ADR-0013:
a single atomic Firestore transaction that turns an approved task into xu,
energy, seed, level-up, and chest-milestone rewards, or a reject with no
economy writes. Both idempotency-gated on task.status as the first read.

ADR-0013 marked Accepted. 39 tests across both stories plus dedicated unit
tests for the pure nextLevelThreshold()/xuBonus() formulas.

Epic left open (not fully Complete): 2 DoD items require a real caller
emitting GameEvents, which only a future Parent Dashboard UI (Donchitos#21) provides.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ession guard)

Adds ADR-0014 (route guard architecture, two-tree StatefulShellRoute design),
the Main Navigation Shell epic (6 stories) and Parent Dashboard UI epic (4
stories, blocked pending Nav Shell), and closes Story 001: root redirect and
session guard logic in router_provider.dart with test coverage.

Story: main-navigation-shell/story-001-root-redirect-session-guard.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t Override, exit dialog, floating chips

Implements all 6 stories: Root Redirect (001, previously landed), Child Shell
3-tab StatefulShellRoute with Flame preservation (002), Parent Shell 2-tab
StatefulShellRoute (003), Parent Override switch-mode flow (004), child
back-button exit dialog + root-navigator push contract (005), and the
floating Profile/Xu/Contextual-badge chip cluster (006).

Every story's code review (flame-specialist + qa-tester) found and fixed a
real issue: a provider desync bug, a forbidden-API violation, a cross-shell
provider-contamination bug, and a dispose-time AnimationController crash
among them. Full suite: 420/420 passing, flutter analyze clean.

Unblocks Parent Dashboard UI (Donchitos#21), whose epic was blocked on this routing
layer since 2026-07-18.

Story: main-navigation-shell/story-002..006

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…& Family tab Reset PIN (TR-parentdash-003, TR-parentdash-004)

Story: parent-dashboard-ui/story-002-create-custom-task, story-003-family-tab-reset-pin

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ring & event emission (TR-parentdash-001)

Task Library post-closure fix: family-wide familyPendingTasksProvider and
TaskModel.id/childId, unblocking Story 001's multi-child correctness AC.

Story: parent-dashboard-ui/story-001-pending-list-approve-reject

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…cepted)

Unblocks Parent Dashboard UI Story 004, the epic's final story. Resolves a
Stack-vs-existing-test conflict via MaterialBanner/ScaffoldMessenger, verified
against installed Flutter SDK source; registers new architecture registry
stances for the banner state and its forbidden Stack-overlay pattern.

Story: parent-dashboard-ui/story-004-fcm-banner-state-machine

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rentdash-002)

Closes the Parent Dashboard UI epic at 4/4 stories. Implements ADR-0015's
BannerState/BannerActions reducer, rendered via MaterialBanner/ScaffoldMessenger
(no Stack) at the Parent Shell level, with defer/coalesce/banner-slot-conflict
logic matching every GDD edge case.

Fixes 8 regressions in pre-existing Main Navigation Shell / Auth & Account
tests that broke once ParentShellScaffold started reading FirebaseMessaging.

Story: parent-dashboard-ui/story-004-fcm-banner-state-machine

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Parent Dashboard UI (Donchitos#21) closing didn't fully unblock this epic as the
prior note implied — only the GameEventBus replay-risk acknowledgment DoD
item closed (Story 001). The manual offline/reconnect verification pass
remains genuinely unperformed and is now the sole gate to full completion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…I bootstrap

Closes Pet Interaction (Donchitos#14): tap/swipe gesture classification, per-type
cooldown, SLEEPING/PLEASED input guards, no-mutation + background/foreground
resilience, and hit-area minimum enforcement (TR-petinteraction-001..004).

- ADR-0016: Pet Interaction Input Handling (Accepted) — gesture classification,
  cooldown mechanism, hit-area contract
- ADR-0017: Pet Room Screen Rendering & Interaction Contract (Accepted) —
  ratifies Formula 2 (tap hit-area padding) and z-order/modal/lifecycle rules
- Story 001: DragCallbacks-only gesture classification & GameEventBus emission
- Story 002: SLEEPING peek + PLEASED-in-progress input guards
- Story 003: per-type cooldown (tap 1.0s / swipe 2.0s), stored-timestamp +
  lazy comparison, no scheduled Timer
- Story 004: no-persistent-mutation verification + background/foreground
  resilience fix — GameEventBus.peekLastEvent() (new, read-only) stops a
  freshly-mounted MochiComponent from replaying a stale petInteracted event
  into a spurious PLEASED animation
- Story 005: hit-area >=80x80dp cross-epic contract verification against
  Pet Room Screen UI's Formula 2 output

Bootstraps Pet Room Screen UI (Donchitos#18) as a dependency: epic + 7 stories created,
Story 001 (Formula 2 — hit_area_formula.dart, padding formula) implemented and
closed to unblock Pet Interaction Story 005. Remaining 6 stories left Ready,
unimplemented, out of this scope.

Known follow-up (flagged, not fixed): Story 002's 2.0s PLEASED reaction
outlasts Story 003's 1.0s tap cooldown, making the tap cooldown practically
unreachable in normal play — a cross-story design question, not a defect in
either story, tracked separately.

55 new tests across 6 files. Full suite: 563 passed, 1 pre-existing unrelated
skip, 0 failures. flutter analyze clean (13 pre-existing unrelated info-lints).

Story: TR-petinteraction-001..004, TR-petroom-003

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Story 003 (Flame Canvas Composition, Z-Order & Modal Mutual Exclusivity,
ADR-0017) mounts RoomBackgroundComponent + MochiComponent into the real
PetRoomGame for the first time — fixes the black-screen bug where neither
component was ever wired into the running app despite being fully built and
tested. Adds showModal/dismissModal, the chrome/context_menu/wardrobe overlay
contract, and an interim real Mochi sprite (mochi_baby_happy_idle.png) loaded
at the PetRoomGame level to avoid a Flame 1.37 unhandled-Future gotcha in
MochiComponent's own widely-unit-tested onLoad().

Two more bugs found via live browser testing after Story 003 closed, fixed
and code-reviewed (flame-specialist + flame-widget-specialist + qa-tester,
3 parallel reviews — see story-003's Post-Closure Fix section for full
findings):
- camera.viewfinder.anchor defaults to Anchor.center in Flame 1.37, painting
  Mochi/background from screen-center instead of top-left. Fixed by setting
  Anchor.topLeft explicitly in PetRoomGame.onLoad().
- RoomBackgroundComponent's implicit SpriteComponent.autoResize shrank its
  size to the 1x1px placeholder sprite's native size, undoing an onGameResize
  sync. Fixed with explicit size: Vector2.zero(), autoResize: false.
- XuChip/ContextualBadgeChip (Main Navigation Shell, unrelated epic) rendered
  as a full-screen-height bar instead of a small pill — bare Center() expands
  to fill FloatingChipCluster's loose-but-finite Row height. Fixed with
  Center(widthFactor: 1, heightFactor: 1).

3 regression tests added per qa-tester's BLOCKING finding (no bug fix should
ship without a test that would have caught it) plus a touch-target upper-
bound gap flame-widget-specialist found in the existing chip tests.

Also generates the 5 Mochi Young mood sprites via ppgen (PerfectPixel Studio,
Gemini 3 Pro Image/OpenRouter) per design/assets/specs/mochi-young-mood-
sprites.md — asset-production only, not yet wired into any code (Pet
Leveling Donchitos#16 has no epic yet). Two known imperfections logged honestly in
asset-manifest.md (weak ear-taper, SAD pose upright instead of lying down).

572 tests passing (569 baseline + 3 new), 1 pre-existing unrelated skip,
flutter analyze clean.

Story: TR-petroom-001

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ng GameEvent

Adds GameEventType.modalVisibilityChanged (payload: bool), emitted from
PetRoomGame.showModal()/.dismissModal() — inlined inside those two methods
rather than at each external call site (the story's own illustrative
sample), since Story 003 already makes them the only sanctioned way to
mutate the modal overlay keys, so this covers every real modal open/close
with no separate call-site discipline required.

MochiComponent.onTrigger gains a guard checked before ADR-0007's existing
LEVELING_UP-interrupt gate: while a modal is open, defer the
highest-priority pending trigger into _pendingVisual instead of playing it,
replayed once the modal closes. Base Mood state updates are never gated —
only the visual.

Code review (flame-specialist + qa-tester, independently) found the same
real bug: _onTriggerComplete's unconditional _play(next) on a dequeued
ADR-0007 _queued trigger bypassed the new modal gate entirely — if a modal
opened while LEVELING_UP was already playing, and something was queued
before the modal opened, the dequeued trigger would play on top of the
still-open modal once LEVELING_UP's timer completed. Fixed by routing that
dequeue through the same _queuePendingVisual priority-merge helper the
modal guard uses, with a regression test reproducing the exact sequence.

9 tests (8 original + 1 regression for the fixed bug). 581 passing (572
baseline + 9), 1 pre-existing unrelated skip, flutter analyze clean.

Story: TR-petroom-004

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…-CR7)

Implements the mood/energy status row (AC-CR7) via a new PetRoomStatusRow
widget wired into the 'chrome' overlay key. AC-CR8 (level progress bar) is
explicitly deferred as Blocked pending the Pet Leveling & Evolution epic,
which does not exist yet.

Also fixes a cross-epic regression this story's production wiring exposed:
Riverpod's default retry-with-backoff on _activeChildEnergyDocProvider
(time_decay_providers.dart) was leaking a Timer past widget-tree disposal.
Disabled via retry: null, with dedicated regression tests correcting an
earlier false assumption that the provider drops to 0.0 on any stream
error — it actually (and correctly) preserves the last known value.

Story: pet-room-screen-ui-006

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…heet

Implements all 7 ACs: the tap-on-Mochi context menu (Thay đồ / Vuốt ve /
Đóng) and the Wardrobe bottom sheet (3 slot tabs, item grid filtered by
ItemModel.slot, loading shimmer / inline error+retry). Both mount via
Story 003's showModal/dismissModal, never mutating overlays directly.

Code review (flame-widget-specialist + qa-tester) found and fixed 5 real
issues: both widgets read MediaQuery.sizeOf instead of game.size for
layout (confirmed via a live diagnostic test this rendered Wardrobe at
~68% of the visible canvas instead of the spec's 60-65%), menu button tap
targets under the 48dp minimum, a missing GameEventBus reset in test
setup, an under-tested wardrobe slot, and no regression test for a tap
falling through the wardrobe sheet to its scrim.

Known gap surfaced by this story (documented in the story file and
EPIC.md, not just a code comment): showModal('context_menu') has no
production caller anywhere — Pet Interaction's own ratified GDD/ADR-0016
already binds tap-on-Mochi directly to the PLEASED animation, conflicting
with this GDD's "tap-on-Mochi opens context menu" prose. The menu is
fully implemented and tested but unreachable by any real player action
until a follow-up ADR/story reconciles the two.

Story: pet-room-screen-ui-007

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…la 1)

Implements Formula 1's fixed accounting contract (drawCalls_sceneFlame =
1 background + 1 Mochi base + 3 equipment slots = 5) as pure Dart
constants/function, per ADR-0001's scope. No Flame/Flutter import, no
live component-tree walk — deliberately out of scope per the story's own
Implementation Notes.

Code review (flame-specialist): Approve, no Required Changes.

Story: pet-room-screen-ui-002

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ratifies already-existing, already-tested behavior (ADR-0014's
StatefulShellRoute/IndexedStack never-dispose guarantee + Flame's raw
Ticker bypassing TickerMode) with 2 new regression tests: a triggered-
state animation cycled through all 3 Child Shell tabs while offstage,
proving it keeps advancing and settles correctly with no replay on
return; and a static source-scan proving PetRoomGame() is constructed
exactly once, at the screen layer.

No production code changed. Code review (flame-specialist + qa-tester):
both Approve, no Required Changes — 4 non-blocking suggestions actioned
(wider timing margin, full 3-tab cycle, a doc citation fix, and
comment-stripping in the static scan to reduce future false-positive
risk).

This closes out the Pet Room Screen UI epic — all 7 stories Complete.
Two cross-epic follow-ups remain open (documented in EPIC.md): Story
007's tap-on-Mochi gesture conflict, and Story 006's AC-CR8 blocked on
the not-yet-created Pet Leveling & Evolution epic.

Story: pet-room-screen-ui-005

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resolves the tap-on-Mochi gesture conflict Story 007's code review
surfaced: the context menu it built had zero production trigger, since
Pet Interaction's ratified GDD/ADR-0016 already binds tap-on-Mochi to
PLEASED. User decision: keep tap=PLEASED unchanged; open the context
menu via a new dedicated MochiOptionsButton (persistent icon button, not
a new Flame gesture) instead of reusing tap or repurposing long-press
(reserved by pet-interaction.md's Open Question Donchitos#1 for a distinct future
interaction).

Corrects the GDD's stale "tap-on-Mochi opens context menu" prose across
the Overview, Core Rule 5, the UI Requirements list, the States/
Transitions diagram, and Edge Cases 2 and 5 — the last of which needed
an actual behavior decision (the button now ignores taps during Mochi's
non-interruptible LEVELING_UP celebration, preserving that Edge Case's
original intent).

Code review (flame-widget-specialist + qa-tester) found and fixed real
issues: 3 more stale GDD passages beyond the ADR's own authoring pass,
a missing accessibility label on the button, a stale-GameEventBus-cache
test bug, and a wrong test assumption (the button isn't reachable while
a modal is open — chrome renders behind modals by design).

Story: pet-room-screen-ui-007 (follow-up)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants