Work mode: AFK — carry through to merge + deploy per acceptance criteria.
The first real-mechanic experiment (not a quiz wrapper): a corral in Woolly
Meadows where the child partitions 10 fluffballs between two pens any way
they like. Every non-empty split is accepted; the delight is discovering
distinct decompositions (6 + 4 = 10), not being judged. Session-local
only: no save changes, no journal, no variant reward, no question banks, no
generic activity framework, no new art assets.
Design context: meadow-isle.md §2 (ten-pen fences, number bonds) and the
reserved mini-game pocket concept. This module is deliberately not an
answer_form precedent — the first-class activity-form question in
meadow-isle.md stays open.
Touch set (exact)
shared/telemetry.ts — add minigame_session_ended event spec (below).
game/assets/shared/telemetry.ts — synced copy via npm run sync.
game/assets/src/world/flock-splits.ts — NEW pure rule module (no cc
imports): split canonicalization, move/submit rules, session state,
entry-critter placement.
game/assets/src/world/FlockSplitsScreen.ts — NEW screen (cocos).
game/assets/src/world/arc.ts — extend ArcCritter.kind union with
"minigame" (one line; nothing else changes).
game/assets/src/world/WorldScreen.ts — route bump/interact on
kind === "minigame" critters to actions.onMinigame(critter); combine
flockSplitsCrittersFor(regionId) into the existing critter render pass.
game/assets/src/GameApp.ts — Screen union + startMinigame /
endMinigame (ShopScreen pattern); emit telemetry once on teardown.
game/tests/flock-splits.test.ts — NEW pure tests.
docs/preview-smoke-check.md — add the mini-game smoke steps.
- New-file
.metas generated by the Cocos build, committed (existing
pattern).
shared/question-v2.ts, question banks, save-v2, persistence, worker
source: untouched.
Data / control flow
flockSplitsCrittersFor("meadow/woolly") returns one entry critter
(kind: "minigame", speciesId woolly/fluffball, walkable tile pinned
by test — suggested x=8, y=6 in the north pen interior).
- WorldScreen bump/interact →
WorldActions.onMinigame →
GameApp.startMinigame() mounts FlockSplitsScreen.
- Screen holds session state from the pure module:
{ staging: 10, pens: [0, 0], found: string[], rounds: 1, dupes: 0 }.
All mutations go through the pure functions; the screen only renders.
- Exit button or completion →
GameApp.endMinigame(result) → emit
minigame_session_ended once → destroy screen, world resumes in place.
UI states
- Playing: staging area with 10 fluffball placeholder nodes; two pen
zones. Tap a pen to arm it (highlighted); tap a sheep in staging to send
it to the armed pen; tap a sheep in a pen to return it to staging. Each
pen shows a live count numeral + ten-frame (paintCellGrid, existing
FigureView painter). A bilingual confirm button ("好了!/Done") submits.
- Split feedback (submit):
- staging not empty → gentle nudge ("还有羊在外面"), no state change;
- a pen is empty → gentle nudge ("两个围栏都要有羊哦");
- duplicate (canonical key already found, e.g. 4+6 after 6+4) → gentle
"这种分法找过了", dupes++, sheep stay put;
- accepted → the equation card shows (
6 + 4 = 10), sheep settle,
found records the key, next round resets pens to staging.
- Complete (3 distinct): the session's equation cards shown together,
celebratory bilingual line, Replay (resets found, rounds++) and
Exit buttons.
- No timer anywhere; failure states are impossible by construction.
Pure module API (contract for tests)
Work mode: AFK — carry through to merge + deploy per acceptance criteria.
The first real-mechanic experiment (not a quiz wrapper): a corral in Woolly
Meadows where the child partitions 10 fluffballs between two pens any way
they like. Every non-empty split is accepted; the delight is discovering
distinct decompositions (
6 + 4 = 10), not being judged. Session-localonly: no save changes, no journal, no variant reward, no question banks, no
generic activity framework, no new art assets.
Design context: meadow-isle.md §2 (ten-pen fences, number bonds) and the
reserved mini-game pocket concept. This module is deliberately not an
answer_formprecedent — the first-class activity-form question inmeadow-isle.md stays open.
Touch set (exact)
shared/telemetry.ts— addminigame_session_endedevent spec (below).game/assets/shared/telemetry.ts— synced copy vianpm run sync.game/assets/src/world/flock-splits.ts— NEW pure rule module (noccimports): split canonicalization, move/submit rules, session state,
entry-critter placement.
game/assets/src/world/FlockSplitsScreen.ts— NEW screen (cocos).game/assets/src/world/arc.ts— extendArcCritter.kindunion with"minigame"(one line; nothing else changes).game/assets/src/world/WorldScreen.ts— route bump/interact onkind === "minigame"critters toactions.onMinigame(critter); combineflockSplitsCrittersFor(regionId)into the existing critter render pass.game/assets/src/GameApp.ts— Screen union +startMinigame/endMinigame(ShopScreen pattern); emit telemetry once on teardown.game/tests/flock-splits.test.ts— NEW pure tests.docs/preview-smoke-check.md— add the mini-game smoke steps..metas generated by the Cocos build, committed (existingpattern).
shared/question-v2.ts, question banks, save-v2, persistence, workersource: untouched.
Data / control flow
flockSplitsCrittersFor("meadow/woolly")returns one entry critter(
kind: "minigame", speciesIdwoolly/fluffball, walkable tile pinnedby test — suggested x=8, y=6 in the north pen interior).
WorldActions.onMinigame→GameApp.startMinigame()mountsFlockSplitsScreen.{ staging: 10, pens: [0, 0], found: string[], rounds: 1, dupes: 0 }.All mutations go through the pure functions; the screen only renders.
GameApp.endMinigame(result)→ emitminigame_session_endedonce → destroy screen, world resumes in place.UI states
zones. Tap a pen to arm it (highlighted); tap a sheep in staging to send
it to the armed pen; tap a sheep in a pen to return it to staging. Each
pen shows a live count numeral + ten-frame (
paintCellGrid, existingFigureView painter). A bilingual confirm button ("好了!/Done") submits.
"这种分法找过了",
dupes++, sheep stay put;6 + 4 = 10), sheep settle,foundrecords the key, next round resets pens to staging.celebratory bilingual line, Replay (resets found,
rounds++) andExit buttons.
Pure module API (contract for tests)