| name | flame-harness-plan |
| description | Phase 2 โ write the game PRD in the project's default_language (core loop, mechanics, content metrics, win/lose, scope guard), map the lib/ structure, and assign app name, slug, and bundle id. |
| argument-hint | |
| allowed-tools | ["Agent","Read","Write","Edit","Bash"] |
flame-harness-plan
Phase 2 of the flutter-flame-harness pipeline. Reads the research spec and config.md, then
produces a comprehensive game PRD in the project's default_language, maps the lib/ directory structure, assigns the app
identity (app_name, app_slug, bundle_id), and advances the pipeline state to design.
All file schemas (config.md, state.md, pipeline-log.md) are defined in
docs/harness-protocol.md โ refer to that document as the single source of truth. Do not
redefine schemas here.
Input
1. Read docs/harness/config.md
Extract:
| Key | Use |
|---|
app_idea | Refined concept tagline written by the research phase |
app_name | Display name (may be blank โ set it here if so) |
app_slug | Kebab-case identifier (may be blank โ derive it here if so) |
bundle_id | App bundle ID (may be blank โ set it here) |
default_language | The user's conversation language (set by the orchestrator); the PRD and all copy are written in it |
If config.md does not exist, abort with:
flame-harness-plan: docs/harness/config.md not found โ run the orchestrator to bootstrap first.
2. Read the latest research spec
Find the most recent file matching docs/harness/specs/*-research.md (sort by filename
descending, take the first). If no spec file exists, abort with:
flame-harness-plan: no research spec found in docs/harness/specs/ โ run flame-harness-research first.
Extract from the spec:
- Chosen concept โ title, tagline, core mechanic, differentiator
- Monetisation hook โ AdMob integration point (interstitial / rewarded / banner)
- Clone-avoidance verdict โ confirm it is SAFE before proceeding
Identity assignment
Derive and assign the app identity before writing the PRD so that the PRD can reference the
final values.
app_name
Use the working title from the research spec as the display name. Capitalise each word. Example:
"space hop" โ "Space Hop".
app_slug
The app_slug is a kebab-case identifier derived from app_name:
- Lowercase the display name.
- Replace all spaces and special characters with hyphens.
- Strip leading/trailing hyphens and collapse consecutive hyphens to one.
- Example:
"Space Hop!" โ "space-hop".
The slug is used as the last segment of the bundle ID and as the directory name in CI/CD paths.
Do not use underscores โ kebab-case only.
bundle_id
The bundle id is part of the app's identity and is decided here, up front (the user sees it in
the PRD). Format โ reverse-DNS com.<company>.<appname>:
<company> = developer.company from config.md (no built-in default โ it comes from the user's
own credentials/store-metadata.md, collected at bootstrap; never a hard-coded company name).
<appname> = app_slug with all hyphens/underscores removed, lowercase (each segment must be
[a-z0-9]+; hyphens/underscores/uppercase are INVALID and break iOS/Android signing).
So bundle_id = com.<company>.<appname>. Examples: app_slug: space-hop โ
com.<company>.spacehop; app_slug: swing-line โ com.<company>.swingline (NOT
com.<company>.space-hop). State the chosen bundle_id explicitly in the PRD identity section. It must
be byte-identical on iOS and Android (docs/harness-protocol.md ยง1).
orientation
Decide the game's single locked orientation from the concept and record it in the PRD:
portrait (default โ most casual/one-hand games) or landscape (inherently wide play: side-scroll
platformers, twin-stick, landscape racers). The game ships locked to this one orientation (the
generator removes the other natively โ no rotate-on-launch).
Write to config.md
Use Edit to update config.md with the identity keys + orientation:
app_name: "<display name>"
app_slug: "<kebab-case-slug>"
bundle_id: "com.<company>.<id>"
orientation: portrait
Make targeted edits โ do not rewrite the entire file.
PRD content
Write the PRD entirely in default_language (the language the user is conversing in). Headings
and body in that language. The template below shows Korean headings as an example for a Korean
project โ translate the headings to default_language (e.g. English) when the project language is
not Korean. The only exceptions are:
- Code identifiers, file paths, class names, and technical terms that have no local equivalent.
- Section headings may include the English technical term in parentheses after the localized heading.
Use the following structure verbatim. A fresh Claude must be able to fill every section from the
research spec alone โ no guessing required.
PRD ๊ตฌ์กฐ (required sections)
# ๊ฒ์ ๊ธฐํ์ (PRD) โ <app_name>
> **๋ฒ์ :** 1.0
> **์์ฑ์ผ:** <YYYY-MM-DD>
> **์์ฑ์:** flame-harness-plan
> **๋ฒ๋ค ID:** com.<company>.<id> (slug์์ ํ์ดํยท์ธ๋์ค์ฝ์ด ์ ๊ฑฐ)
---
## 1. ์ฅ๋ฅด ๋ฐ ์ปจ์
(Genre & Concept)
- **์ฅ๋ฅด:** <e.g. ํ์ดํผ์บ์ฃผ์ผ ๋ฌ๋ / ํ์ ๋ํ์ค / ํผ์ฆ>
- **ํ ์ค ์ค๋ช
:** <tagline from research spec, translated to Korean>
- **ํต์ฌ ์ฐจ๋ณ์ :** <differentiator from research spec, in Korean>
- **๋์ ์ฐ๋ น:** <target age group>
---
## 2. ์ฝ์ด ๋ฃจํ (Core Loop)
ํ๋ ์ด์ด๊ฐ 10โ30์ด๋ง๋ค ๋ฐ๋ณตํ๋ ํต์ฌ ํ๋์ ๋จ๊ณ๋ณ๋ก ๊ธฐ์ ํ๋ค.
1. <๋จ๊ณ 1>
2. <๋จ๊ณ 2>
3. <๋จ๊ณ 3>
...
---
## 3. ๊ฒ์ ๋ฉ์นด๋ (Game Mechanics)
### 3.1 ์กฐ์ ๋ฐฉ๋ฒ (Controls)
| ํ๋ซํผ | ์กฐ์ | ๊ฒฐ๊ณผ |
|---|---|---|
| iOS/Android | <tap / swipe / hold> | <action> |
### 3.2 ํต์ฌ ๋ฉ์นด๋ (Core Mechanic)
<2-4 sentences describing the primary mechanic in Korean>
### 3.3 ๋ณด์กฐ ๋ฉ์นด๋ (Secondary Mechanics)
<Bullet list of 2-4 secondary mechanics>
---
## 4. ์ฝํ
์ธ ์งํ (Content Metrics)
| ํญ๋ชฉ | ๋ชฉํ๊ฐ |
|---|---|
| ๋ ๋ฒจ ์ | <number> |
| ์ ์ข
๋ฅ ์ | <number> |
| ์จ์ด๋ธ ์ (๋ ๋ฒจ๋น) | <number> |
| ์คํ
์ด์ง ํ
๋ง ์ | <number> |
| ์์ดํ
/ํ์์
์ข
๋ฅ ์ | <number> |
์ฝํ
์ธ ์์น๋ MVP ๊ธฐ์ค์ด๋ฉฐ, ์
๋ฐ์ดํธ๋ฅผ ํตํด ํ์ฅํ ์ ์๋ค.
---
## 5. ์งํ ๋ฐ ๊ฒฝ์ (Progression & Economy)
### 5.1 ์งํ ๊ตฌ์กฐ
<Describe how levels/stages unlock โ linear, world-map, infinite, etc.>
### 5.2 ์ ์ ๋ฐ ๋ณด์
- ๊ธฐ๋ณธ ์ ์ ๋จ์: <e.g. ์ฝ์ธ, ๋ณ, ํฌ์ธํธ>
- ๋ ๋ฒจ ํด๋ฆฌ์ด ๋ณด์: <description>
- ๊ด๊ณ ์์ฒญ ๋ณด์ (๋ฆฌ์๋ ์ ๋): <description โ maps to AdMob rewarded ad>
### 5.3 ์ ์ฅ ๋ฐ ์์์ฑ
- ๋ก์ปฌ ์ ์ฅ: `SharedPreferences` (์ ์, ์ต๊ณ ๊ธฐ๋ก, ์ค์ )
- ํด๋ผ์ฐ๋ ์ ์ฅ: ๋ฏธํฌํจ (์ค์ฝํ ์ธ โ ยง8 ์ฐธ์กฐ)
---
## 6. ์น๋ฆฌ ๋ฐ ํจ๋ฐฐ ์กฐ๊ฑด (Win / Lose Conditions)
### 6.1 ์น๋ฆฌ ์กฐ๊ฑด
<Describe what the player must achieve to win a level/session>
### 6.2 ํจ๋ฐฐ ์กฐ๊ฑด
<Describe what causes a game-over state>
### 6.3 ๊ฒ์ ์ค๋ฒ ํ๋ฉด
๊ฒ์ ์ค๋ฒ ํ๋ฉด์ ๋ค์์ ํ์ํ๋ค:
- ์ต์ข
์ ์
- ์ต๊ณ ๊ธฐ๋ก (๊ฐฑ์ ์ฌ๋ถ ํ์)
- ์ฌ์์ ๋ฒํผ
- ๋ฉ์ธ ๋ฉ๋ด ๋ฒํผ
- ๊ด๊ณ ์์ฒญ์ผ๋ก ๋ถํ ์ต์
(์ ํ, ๋ฆฌ์๋ ์ ๋)
---
## 7. App Store ์ปดํ๋ผ์ด์ธ์ค ์ฒดํฌ๋ฆฌ์คํธ
| ํญ๋ชฉ | ์ํ |
|---|---|
| ์ฑ ์ฌ์ฌ ์ง์นจ 4.3 ํด๋ก ํํผ ํ์ธ | SAFE (research spec ์ฐธ์กฐ) |
| ๊ฐ์ธ์ ๋ณด ์ฒ๋ฆฌ๋ฐฉ์นจ URL ํฌํจ | ํ์ (config.md `privacy` ํ๋) |
| ์ฐ๋ น ๋ฑ๊ธ ์ ํฉ์ฑ (4+) | ํ์ธ ํ์ |
| AdMob ๊ด๊ณ ๋ ์ด๋ธ ํ์ | ๊ด๊ณ ์์ฒญ ๋ฒํผ์ ๋ ์ด๋ธ ๋ช
์ |
| ์ธ์ฑ๊ตฌ๋งค ์์ (MVP) | ์ค์ฝํ ์ธ |
| ์์น ์ ๋ณด ๋ฏธ์ฌ์ฉ | ํด๋น ์์ |
| ์นด๋ฉ๋ผ/๋ง์ดํฌ ๋ฏธ์ฌ์ฉ | ํด๋น ์์ |
---
## 8. ์ค์ฝํ ๊ฐ๋ (Scope Guard)
๋ค์ ํญ๋ชฉ์ **MVP ์ค์ฝํ ์ธ**์ด๋ค. ๊ณํ, ์ค๊ณ, ๊ตฌํ ๋จ๊ณ์์ ์ด ํญ๋ชฉ๋ค์ ๊ตฌํํ์ง ์๋๋ค.
์ค์ฝํ ํ์ฅ์ด ํ์ํ ๊ฒฝ์ฐ PRD๋ฅผ ๊ฐ์ ํ ํ ์งํํ๋ค.
**์ค์ฝํ ์ธ ํญ๋ชฉ:**
- ์จ๋ผ์ธ ๋ฉํฐํ๋ ์ด์ด / ์์
๊ธฐ๋ฅ
- ํด๋ผ์ฐ๋ ์ ์ฅ / ๊ณ์ ์์คํ
(Google Play Games, Game Center)
- ์ธ์ฑ๊ตฌ๋งค (IAP) ๋ฐ ํ๋ฆฌ๋ฏธ์ ์ฝํ
์ธ
- ํธ์ ์๋ฆผ
- ์ปค์คํ
์บ๋ฆญํฐ / ์คํจ ์์คํ
- ๋งต ์๋ํฐ ๋๋ ์ฌ์ฉ์ ์์ฑ ์ฝํ
์ธ
- ๋ค๊ตญ์ด ์ง์ (ํ๊ตญ์ด + ์์ด ์ด์ธ์ ์ธ์ด)
- ํ๋ธ๋ฆฟ ์ ์ฉ ๋ ์ด์์
- ๋ฐฑ์๋ ์๋ฒ / API
---
lib/ structure map
The PRD must include a lib/ directory map section immediately after the scope guard. This map
is the authoritative directory structure that the design and generator phases will follow.
Append the following section to the PRD (translated headings are fine; the paths must be exact):
## 9. lib/ ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ
์๋ ๊ตฌ์กฐ๋ design ๋ฐ generator ๋จ๊ณ์์ ๊ทธ๋๋ก ๋ฐ๋ฅธ๋ค.
lib/
โโโ game/ # FlameGame ์๋ธํด๋์ค ๋ฐ ๊ฒ์ ์ง์
์
โ โโโ components/ # Flame Component ํด๋์ค (ํ๋ ์ด์ด, ์ , ์ฅ์ ๋ฌผ ๋ฑ)
โ โโโ systems/ # ๊ฒ์ ๋ก์ง ์์คํ
(์ถฉ๋, ์คํฐ, ์ ์ ๋ฑ)
โ โโโ data/ # ๋ ๋ฒจ ๋ฐ์ดํฐ, ์ ์คํฏ, ๊ฒ์ ์์ (game_config.dart ํฌํจ)
โโโ screens/ # Flutter ํ๋ฉด (๋ฉ์ธ ๋ฉ๋ด, ๊ฒ์ ์ค๋ฒ, ์ค์ ๋ฑ)
โโโ ui/ # HUD ์์ ฏ, ์ค๋ฒ๋ ์ด, ๊ณตํต UI ์ปดํฌ๋ํธ
โโโ l10n/ # ๋ก์ปฌ๋ผ์ด์ ์ด์
ARB ํ์ผ (ko.arb, en.arb)
> **๊ท์น:** ๊ฒ์ ๋ก์ง์ `game/` ์๋์๋ง ์์นํ๋ค. Flutter ์์ ฏ์ `screens/` ๋๋ `ui/`์
> ์์นํ๋ค. ๋งค์ง ๋๋ฒ๋ `game/data/game_config.dart`์ ์ง์คํ๋ค (contract.md ๊ธฐ์ค ยง4 ์ฐธ์กฐ).
Output
1. Write the PRD
Create docs/harness/plans/<YYYY-MM-DD>-prd.md (use today's UTC date).
If docs/harness/plans/ does not exist, create it before writing.
Write the full PRD in default_language using the structure defined in the PRD content section above,
filling every section from the research spec and config.md.
2. Update config.md
Apply the identity keys (app_name, app_slug, bundle_id) via Edit as described in
Identity assignment above.
3. Update state.md
Update docs/harness/state.md per the schema in docs/harness-protocol.md ยง2:
status: running
current_phase: plan
next_role: design
updated_at: "<ISO-8601 UTC now>"
Leave all other keys unchanged. Use Edit for a targeted update.
4. Append to pipeline-log.md
Append one row to docs/harness/pipeline-log.md per the schema in docs/harness-protocol.md ยง6:
| <ISO-8601 UTC now> | complete | plan | PRD written; app_slug: <slug>; bundle_id: com.<company>.<id> |
Error handling
- If the research spec is missing or empty, abort with a clear message and set
state.md to
status: paused, pause_reason: manual_action.
- If
config.md cannot be read, abort immediately (do not write partial output).
- If any required PRD section cannot be filled from the spec, write a clearly marked placeholder
(
<!-- TODO: ์์ฑ ํ์ -->) rather than omitting the section โ downstream validators grep for
section headings.