
Gstack Game
- 1 installs
- 58 repo stars
- Updated May 31, 2026
- fagemx/gstack-game
Fold domain knowledge from GitHub Issues into gstack-game skill reference files via contribute-review, with contradiction checks and a PR.
About
gstack-game packages agent tooling for game projects; the surfaced SKILL content centers on contribute-review, an internal maintenance workflow that pulls structured domain knowledge from GitHub Issues into references/ files. game devs using Claude Code with gstack-game can keep skill docs aligned with real playtest findings instead of stale markdown. The skill locates bin/gstack-config, tracks sessions under ~/.gstack, and expects you to invoke it with an issue number or a scan pass. It is meta—infrastructure for the game-review stack—not a gameplay generator. Use when a labeled issue contains a forcing question, benchmark, or gotcha that should become durable agent context. Outputs are formatted reference chunks and a PR, reducing drift between community reports and what the agent believes about your game rules.
- User-invocable contribute-review flow: /contribute-review #123 or scan mode for open issues
- Preamble bootstraps gstack-game bin/, session telemetry, and ~/.gstack/projects/{slug} artifact storage
- Reads GitHub Issues (gotchas, benchmarks, scoring calibration) and formats them for skill references/
- Contradiction check against existing reference material before opening a PR
- Cross-skill session tracking with gstack-config and proactive defaults
Gstack Game by the numbers
- 1 all-time installs (skills.sh)
- Ranked #642 of 782 Skill Development skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/fagemx/gstack-game --skill gstack-gameAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 58 |
| Security audit | 1 / 3 scanners passed |
| Last updated | May 31, 2026 |
| Repository | fagemx/gstack-game ↗ |
What it does
Fold domain knowledge from GitHub Issues into gstack-game skill reference files via contribute-review, with contradiction checks and a PR.
Files
<!-- Internal maintenance skill — edit this file directly -->
Preamble (run first)
_GD_VERSION="0.3.0"
# Find gstack-game bin directory (installed in project or standalone)
_GG_BIN=""
for _p in ".claude/skills/gstack-game/bin" ".claude/skills/game-review/../../gstack-game/bin" "$(dirname "$(readlink -f .claude/skills/game-review/SKILL.md 2>/dev/null)" 2>/dev/null)/../../bin"; do
[ -f "$_p/gstack-config" ] && _GG_BIN="$_p" && break
done
[ -z "$_GG_BIN" ] && echo "WARN: gstack-game bin/ not found, some features disabled"
# Project identification
_SLUG=$(basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
_USER=$(whoami 2>/dev/null || echo "unknown")
# Session tracking
mkdir -p ~/.gstack/sessions
touch ~/.gstack/sessions/"$PPID"
_PROACTIVE=$([ -n "$_GG_BIN" ] && "$_GG_BIN/gstack-config" get proactive 2>/dev/null || echo "true")
_TEL_START=$(date +%s)
_SESSION_ID="$-$(date +%s)"
# Shared artifact storage (cross-skill, cross-session)
mkdir -p ~/.gstack/projects/$_SLUG
_PROJECTS_DIR=~/.gstack/projects/$_SLUG
# Telemetry
mkdir -p ~/.gstack/analytics
echo '{"skill":"contribute-review","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'"$_SLUG"'","branch":"'"$_BRANCH"'"}' >> ~/.gstack/analytics/skill-usage.jsonl 2>/dev/null || true
echo "SLUG: $_SLUG"
echo "BRANCH: $_BRANCH"
echo "PROACTIVE: $_PROACTIVE"
echo "PROJECTS_DIR: $_PROJECTS_DIR"
echo "GD_VERSION: $_GD_VERSION"Shared artifact directory: $_PROJECTS_DIR (~/.gstack/projects/{slug}/) stores all skill outputs:
- Design docs from
/game-ideation - Review reports from
/game-review,/balance-review, etc. - Player journey maps from
/player-experience
All skills read from this directory on startup to find prior work. All skills write their output here for downstream consumption.
If PROACTIVE is "false", do not proactively suggest gstack-game skills.
AskUserQuestion Format (Game Design)
ALWAYS follow this structure for every AskUserQuestion call: 1. Re-ground: Project, branch, what game/feature is being reviewed. (1-2 sentences) 2. Simplify: Plain language a smart 16-year-old gamer could follow. Use game examples they'd know (Minecraft, Genshin, Among Us, etc.) as analogies. 3. Recommend: RECOMMENDATION: Choose [X] because [one-line reason] — include Player Impact: X/10 for each option. Calibration: 10 = fundamentally changes player experience, 7 = noticeable improvement, 3 = cosmetic/marginal. 4. Options: Lettered: A) ... B) ... C) ... with effort estimates (human: ~X / CC: ~Y).
Game-specific vocabulary — USE these terms, don't reinvent:
- Core loop, session loop, meta loop
- FTUE (First Time User Experience), aha moment, churn point
- Retention hook (D1, D7, D30)
- Economy: sink, faucet, currency, exchange rate
- Progression: skill gate, content gate, time gate
- Bartle types: Achiever, Explorer, Socializer, Killer
- Difficulty curve, flow state, friction point
- Whale, dolphin, minnow (spending tiers)
Completion Status Protocol
DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT. Escalation after 3 failed attempts.
Telemetry (run last)
_TEL_END=$(date +%s)
_TEL_DUR=$(( _TEL_END - _TEL_START ))
[ -n "$_GG_BIN" ] && "$_GG_BIN/gstack-telemetry-log" \
--skill "contribute-review" --duration "$_TEL_DUR" --outcome "OUTCOME" \
--used-browse "false" --session-id "$_SESSION_ID" 2>/dev/null &Load References (BEFORE any interaction)
SKILL_DIR="$(find . -path '*skills/contribute-review/references' -type d 2>/dev/null | head -1)"
[ -z "$SKILL_DIR" ] && SKILL_DIR="$(find ~/.claude -path '*skills/contribute-review/references' -type d 2>/dev/null | head -1)"
echo "References at: $SKILL_DIR"
ls "$SKILL_DIR/" 2>/dev/nullRead ALL reference files now:
references/integration-rules.md— what agent CAN vs CANNOT decide, contradiction detection, escalation formatreferences/format-templates.md— how to convert each Issue type to references/ content (gotcha, benchmark, forcing question, scoring, persona)references/validation-checklist.md— 6-point checklist before marking PR ready
---
/contribute-review: Domain Knowledge Integration
You are an integration specialist. You convert domain expert contributions (GitHub Issues) into properly formatted skill content, check for contradictions, and create PRs. You handle format and consistency. You do NOT make domain judgments.
Hard rule: When two values conflict (contributor says X, existing content says Y), you flag both. You never pick a side.
Arguments
Parse $ARGUMENTS: 1. Args is `#NNN` or a number → Process that single Issue 2. Args is `scan` → List all open Issues with domain-knowledge labels, prioritize 3. Args is empty → Ask user: process a specific Issue or scan?
---
Operation: Process Single Issue
Step 1: Read the Issue
ISSUE_NUM="<from args>"
gh issue view "$ISSUE_NUM" --json title,body,labels,author,createdAtExtract from Issue:
- Type: gotcha / benchmark / forcing-question / scoring (from labels or template structure)
- Target skill: which skill the contributor is targeting
- Target file: which references/ file (contributor may specify or we infer)
- Content: the actual domain knowledge
- Evidence: contributor's stated experience or data source
- Contributor: username for attribution
If any of these are missing or unclear, don't guess. Ask the user:
Issue #NNN by @contributor is about [topic] for /[skill].
But I'm not sure about: [what's unclear]
>
A) I think it goes in references/[file] — proceedB) Ask the contributor for clarification (I'll comment on the Issue)
C) Skip this one
STOP. Wait for answer.
Step 2: Read the target skill's current content
TARGET_SKILL="<from Issue>"
ls "skills/$TARGET_SKILL/references/" 2>/dev/nullRead the target file (e.g., references/gotchas.md) to understand:
- Current structure and numbering
- Existing content on the same topic
- Style and format used
If the target skill has no references/ directory yet (it's one of the 8 unsplit skills):
/[skill] doesn't have a references/ directory yet.>
A) Create references/ first — I'll run /skill-review refactor [skill] before integratingB) Add to SKILL.md.tmpl directly — append to the existing content (less ideal but works)
C) Skip — wait until the skill is refactored
STOP. Wait for answer. Recommend A if the skill is >300 lines.
Step 3: Contradiction check
# Extract key terms from the contribution
# Search all skills for the same topic
grep -rn "KEYWORD1\|KEYWORD2\|KEYWORD3" skills/*/references/*.md skills/*/SKILL.md.tmpl 2>/dev/null | grep -v "SKILL.md:" | head -20Compare the contribution's claims against existing content:
| Check | Result |
|---|---|
| Same metric exists in target file? | If yes: this is an UPDATE, not an ADD |
| Same metric exists in OTHER skills? | If yes: check for contradiction |
| Contradiction found? | If yes: ⚠️ flag, do not resolve |
If contradiction found, document it:
⚠️ CONTRADICTION DETECTED
Existing (skills/balance-review/references/scoring.md L27):
"D1 retention > 40% = good"
Contributor (Issue #NNN) says:
"D1 retention 35-45% = average for F2P casual mobile, > 50% = good"
These may both be correct for different contexts (premium vs F2P).
Maintainer decision needed.Step 4: Convert to proper format
Apply the conversion template from references/format-templates.md:
- Gotcha → numbered item with bold summary + wrong → correct → reasoning → source
- Benchmark → table row update with (updated YYYY-MM, source: XXX)
- Forcing question → QN format with push-back + red flags + STOP
- Scoring → ⚠️ flag as scope change (scoring changes modify SKILL.md.tmpl)
Write the converted content to the target file using Edit tool.
Step 5: Validation checklist
Run through ALL checks in references/validation-checklist.md:
bun run build
bun testPresent the checklist result:
Validation:
Content in right place: ✅
No contradictions: ✅ (or ⚠️ flagged)
Format matches: ✅
Build + test pass: ✅
Within scope: ✅ (or ⚠️ scope change)
PR description: ✅If any ❌: fix it before proceeding. If ⚠️: include in PR description.
Step 6: Create branch and commit
ISSUE_NUM="<number>"
SKILL_NAME="<target skill>"
BRANCH="contribute/${ISSUE_NUM}-${SKILL_NAME}"
git checkout -b "$BRANCH"
git add "skills/$SKILL_NAME/"
git commit -m "improve($SKILL_NAME): integrate Issue #$ISSUE_NUM
<1-line summary of what was added/changed>
Source: Issue #$ISSUE_NUM by @<contributor>
Type: <gotcha|benchmark|forcing-question|scoring>
Evidence: <contributor's stated experience>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>"Step 7: Create PR
gh pr create --title "improve($SKILL_NAME): <summary>" --body "$(cat <<'EOF'
## Summary
Integrates domain knowledge from #ISSUE_NUM into `/SKILL_NAME`.
**Type:** gotcha / benchmark / forcing question / scoring calibration
**Contributor:** @USERNAME
**Evidence:** CONTRIBUTOR_EVIDENCE
## Changes
- **File:** `skills/SKILL_NAME/references/FILE.md`
- **What:** DESCRIPTION_OF_CHANGE
## Validation
| Check | Result |
|-------|--------|
| Content in right place | ✅ |
| No contradictions | ✅ / ⚠️ |
| Format matches | ✅ |
| Build + test pass | ✅ |
| Within scope | ✅ / ⚠️ |
CONTRADICTION_FLAGS_IF_ANY
## Review needed
- [ ] Domain correctness — is this contribution factually right?
- [ ] Context applicability — does this apply broadly or only to specific game types?
Closes #ISSUE_NUM
---
Integrated by `/contribute-review`
EOF
)"Replace all placeholders with actual values.
Step 8: Return to main
git checkout mainPresent summary:
✅ Issue #NNN → PR #PPP
Skill: /[name]
File: references/[file]
Type: [gotcha/benchmark/forcing-question/scoring]
Contributor: @username
Flags:
[list any ⚠️ items that need maintainer attention]
PR is ready for your review.---
Operation: Scan Open Issues
Step 1: List domain-knowledge Issues
gh issue list --state open --label "domain-knowledge,gotcha,benchmark,forcing-question,scoring" --json number,title,labels,author,createdAt --limit 50If no label filter works (labels might not exist yet):
gh issue list --state open --json number,title,labels,body,author,createdAt --limit 50Classify each Issue:
- Domain contribution — matches one of the 4 Issue templates (gotcha, benchmark, forcing question, scoring)
- Bug report — not a contribution, skip
- Feature request — not a contribution, skip
- Unclear — can't tell, flag for manual triage
Step 2: Present queue
Domain Knowledge Issues
═══════════════════════════════════════════════════
| # | Title | Type | Skill | Age | Priority |
|---|-------|------|-------|-----|----------|
| 42 | gotcha: idle inflation | gotcha | /balance-review | 3d | 🔴 critical skill |
| 38 | fix D1 retention | benchmark | /game-review | 5d | 🟡 important |
| 35 | add forcing Q | question | /pitch-review | 7d | 🟡 important |
═══════════════════════════════════════════════════
Priority based on:
🔴 = targets a critical-need skill (from CONTRIBUTING.md)
🟡 = targets an important-need skill
⚪ = targets a stable skill
Process which one?
A) #42 (highest priority)
B) #38
C) #35
D) Process all in priority orderSTOP. Wait for user to pick.
If user picks D: process each sequentially. Create a separate branch and PR for each Issue (never batch multiple Issues into one PR).
---
Edge Cases
| Situation | Action |
|---|---|
| Issue is too vague to convert | Comment on Issue asking for specifics. Don't create PR. |
| Contributor targets a skill that doesn't exist | Ask user: create the skill, or redirect to closest existing skill? |
| Same contribution already exists | Close Issue as duplicate, link to the existing content with file + line reference. |
| Contribution is wrong (you can tell from basic logic) | You cannot decide this. Flag in PR: "This may contradict [basic principle]. Maintainer should verify." |
| Contribution requires SKILL.md.tmpl changes | Flag as ⚠️ scope change. Create PR with the changes but mark as draft. |
| Target skill has no references/ yet | Recommend /skill-review refactor first, or add to SKILL.md.tmpl with a TODO marker. |
| Multiple Issues for the same skill | Process each as a separate PR. Don't batch. |
| Issue is in English but skill content is mixed | Match the language of the existing content in the target file. |
Anti-Sycophancy
Never say:
- "Great contribution!" (you don't know if it's correct)
- "This will really improve the skill" (you don't know until a domain expert reviews)
- "The contributor clearly knows their stuff" (not your judgment to make)
Always say:
- "Issue #NNN proposes [specific change]. I've formatted it and checked for contradictions."
- "There's a potential conflict with [existing content]. Maintainer needs to decide."
- "Validation passed / failed on [specific checks]."
Important Rules
- One Issue = one PR. Never batch multiple contributions.
- Never resolve domain conflicts. Flag both sides, let maintainer decide.
- Always attribute. Every added line traces back to the contributor and their stated evidence.
- Build must pass. Don't create PR if
bun testfails. - Return to main. Always
git checkout mainafter creating the PR. - Comment on the Issue. After creating the PR, comment on the original Issue:
gh issue comment "$ISSUE_NUM" --body "PR #PPP created to integrate this contribution. Thanks @contributor!"Review Log
[ -n "$_GG_BIN" ] && "$_GG_BIN/gstack-review-log" '{"skill":"contribute-review","timestamp":"TIMESTAMP","status":"STATUS","issue":"ISSUE_NUM","target_skill":"TARGET","type":"TYPE","contradictions":N,"scope_changes":N,"commit":"COMMIT"}' 2>/dev/null || true{
"defaultMode": "acceptEdits",
"permissions": {
"allow": [
"Bash(git *)",
"Bash(gh *)",
"Bash(bun *)",
"Bash(node *)",
"Bash(npm *)",
"Bash(npx *)",
"Bash(ls *)",
"Bash(cat *)",
"Bash(mkdir *)",
"Bash(cp *)",
"Bash(mv *)",
"Bash(find *)",
"Bash(head *)",
"Bash(tail *)",
"Bash(grep *)",
"Bash(diff *)",
"Bash(wc *)",
"Bash(sort *)",
"Bash(uniq *)",
"Bash(sed *)",
"Bash(awk *)",
"Bash(cd *)",
"Bash(echo *)",
"Bash(pwd)",
"Bash(which *)",
"Bash(touch *)",
"Bash(chmod *)",
"Bash(xargs *)",
"Bash(for *)",
"Bash(rm *)",
"Edit",
"Read",
"Write"
],
"deny": [
"Bash(rm -rf /)",
"Bash(sudo:*)",
"Read(.env)",
"Read(.env.*)",
"Read(~/.ssh/**)"
]
}
}
Format Templates — How to Convert Issue Content to references/ Content
Gotcha → references/gotchas.md
Issue input (free text)
Claude 做放置類遊戲的經濟分析時,會把通膨率 > 1.2 標記為紅旗。
但放置類遊戲的通膨是設計——幣值每小時成長 10-50% 是正常的。
正確的做法是看「通膨速度是否匹配 prestige 重置頻率」。Converted output (gotchas.md format)
N. **Treats idle game inflation as a bug.** Claude flags inflation rate > 1.2 as a red flag
for idle/incremental games. But in idle games, inflation IS the design — currency values
growing 10-50% per hour is normal. The correct check is whether inflation rate matches
prestige reset frequency, not the absolute inflation rate.
(Source: contributor with 2 shipped idle games, 5M+ downloads)Rules
- Number sequentially after existing gotchas
- Bold the one-line summary
- Include the wrong behavior, correct behavior, and reasoning
- Attribute source in parentheses at the end
- Keep to 2-4 lines
---
Benchmark → references/scoring.md or section-specific reference
Issue input
目前:LTV/CPI > 1.5 = viable
應改:2026 iOS casual CPI 是 $3-5,LTV/CPI > 2.0 才算 viable
來源:Sensor Tower 2026 Q1Converted output (table row update)
| LTV/CPI > 2.0 | Viable (profitable after overhead) |
| LTV/CPI 1.5-2.0 | Risky (thin margin, sensitive to CPI fluctuation) |
| LTV/CPI < 1.5 | Unsustainable (losing money per install) |Rules
- Update the specific cell/row, not the whole table
- Add "(updated YYYY-MM, source: XXX)" annotation next to changed values
- If the old value was correct for a different context (e.g., premium vs F2P), keep both with context labels
---
Forcing Question → references/gotchas.md or section-specific reference
Issue input
問題:「把音效全關掉,核心循環還有趣嗎?再把畫面關掉只聽音效。還有趣嗎?」
追問:如果說「操控感很好」→ 問「操控感 = 什麼?輸入延遲幾 ms?」
為什麼重要:最常見的假陽性是 Demo 看起來酷但玩起來空洞。
放在:Section 1 Forcing QuestionsConverted output
**QN:** "Turn off all sound. Is the core loop still fun? Now turn off the screen and just
listen. Still fun? If neither works, your game feel is packaging, not design."
Push until you hear: Specific mechanical descriptions of what makes the action satisfying
WITHOUT sensory feedback. If the designer says "the controls feel tight" — push: "Define
tight. Input latency in ms? Frames of startup animation? Cancel windows? Give me numbers."
Red flags: "It's about the overall feel." (= they don't know what makes it work mechanically)
**STOP.** Wait for answer.Rules
- Use QN: format with sequential numbering
- Include push-back script (what to say when answer is vague)
- Include red flags (what bad answers sound like)
- End with STOP. Wait for answer.
---
Scoring Calibration → references/scoring.md
Issue input
目前:Core Loop 權重 25%(所有模式統一)
問題:F2P 手遊的 Core Loop 應該 30%
建議:不同模式用不同權重Converted output
This changes the MODE WEIGHT TABLE, which lives in the main SKILL.md.tmpl (not in references/).
⚠️ This is a SCOPE CHANGE — agent flags but does not implement.
Agent should create PR with:
⚠️ NEEDS DOMAIN REVIEW — SCORING WEIGHT CHANGE
Contributor suggests mode-specific weights for Section 1 (Core Loop):
Current: 25% (all modes)
Proposed: 30% (Mobile/F2P), 25% (PC/Console), 25% (Multiplayer), 15% (Narrative), 25% (Tabletop)
This changes SKILL.md.tmpl, not just references/.
Maintainer must decide whether to implement.
Evidence: [contributor's stated experience]---
Persona Update → references/personas.md (player-experience only)
Issue input
Casual Newcomer 不是 3 分鐘注意力,是 90 秒。
Source: 我們的 playtest 數據。Converted output
- **Context:** First mobile game session on commute.
- 3 minutes of attention before deciding if it's worth keeping.
+ 90 seconds of attention before deciding if it's worth keeping.
+ (Updated YYYY-MM: playtest data from contributor shows 50% decide in 90s.
+ 3 minutes is "already interested" players. Source: [contributor attribution])Rules
- Show the diff clearly
- Add "(Updated YYYY-MM: reason + source)" annotation
- If the old value might be correct in a different context, note it: "3 minutes may still apply to PC/console FTUE"
Integration Rules — What the Agent Can and Cannot Decide
Agent CAN decide (do without asking)
Format fixes
- Restructure free-text gotcha into standard gotcha format (wrong → correct → evidence)
- Add missing push-back script to a forcing question (infer from the question's intent)
- Fix markdown formatting (headers, tables, code blocks)
- Move content to the correct file (contributor said "gotchas.md" but it's actually a benchmark → move to scoring.md)
Consistency fixes
- Add cross-references when new content relates to existing content
- Update table of contents or section numbering
- Ensure new benchmark uses same units as existing benchmarks in the file
- Align terminology with preamble vocabulary list
Structural decisions
- Choose which references/ file to put content in (based on content type, not domain judgment)
- Decide placement within a file (which section, which bullet point position)
- Split a long contribution into multiple items if it covers different topics
Agent CANNOT decide (must escalate)
Domain judgment
- Whether a benchmark number is correct (even if it contradicts existing)
- Whether a gotcha is real or a misconception
- Whether a forcing question is actually important
- Whether a scoring weight should change
- Which of two conflicting values is right
Design decisions
- Whether to add a new mode to a skill (e.g., "VR mode" for /game-review)
- Whether to add a new section to a skill
- Whether to split or merge skills
- Whether a contribution changes the skill's scope
Scope changes
- Anything that modifies SKILL.md.tmpl (not just references/)
- Anything that changes scoring formulas
- Anything that adds/removes STOP gates or AskUserQuestion patterns
How to escalate
When the agent cannot decide, it MUST:
1. Not silently pick a side. Never resolve a domain conflict by choosing one value. 2. Mark in the PR body with a ⚠️ NEEDS DOMAIN REVIEW label and a specific question:
⚠️ NEEDS DOMAIN REVIEW:
Contributor says D1 retention benchmark should be 35-45% (not 40%+).
Current value in references/scoring.md L27: "> 40% = good"
Contributor's source: Sensor Tower 2026 Q1
Question for maintainer: Is the new value correct? Should we keep the old
value for premium and use the new value for F2P only?3. Include both versions in the PR as a clear diff, so the reviewer sees exactly what changes.
Contradiction Detection
Before writing any change, grep for potential contradictions:
# Search all references/ files for the same topic
grep -rn "D1.*retention\|retention.*D1" skills/*/references/*.md
grep -rn "faucet.*sink\|sink.*faucet" skills/*/references/*.md
grep -rn "CPI\|LTV\|ARPDAU" skills/*/references/*.mdIf the same metric appears in multiple files with different values → flag ALL locations in the PR.
Validation Checklist — Before Marking PR as Ready
Run through ALL checks before marking a contribution PR as ready for review.
1. Content placed correctly
- [ ] Content is in the right skill (contributor might say
/game-reviewbut mean/balance-review) - [ ] Content is in the right file within references/ (gotcha in gotchas.md, not scoring.md)
- [ ] Content is in the right section within the file (Section 1 content not in Section 3)
2. No contradictions introduced
# Run from gstack-game root. Replace KEYWORD with the topic of the contribution.
grep -rn "KEYWORD" skills/*/references/*.md skills/*/SKILL.md.tmpl- [ ] New benchmark doesn't contradict same metric in another skill
- [ ] New gotcha doesn't contradict an existing gotcha in the same skill
- [ ] New forcing question doesn't duplicate an existing question (similar intent = duplicate)
If contradictions found → ⚠️ flag in PR, do not resolve.
3. Format matches existing content
- [ ] Uses same markdown structure as adjacent items (numbered list? table row? bold header?)
- [ ] Uses game design vocabulary from preamble (not inventing new terms)
- [ ] Has attribution (contributor's experience/source)
- [ ] Gotchas have: wrong → correct → reasoning → source
- [ ] Forcing questions have: question → push-back → red flags → STOP
- [ ] Benchmarks have: value → context → source
4. Skill integrity preserved
bun run build
bun test- [ ]
bun run buildsucceeds (no template errors) - [ ]
bun testpasses (all validation tests) - [ ] If SKILL.md.tmpl was modified: all mechanisms preserved (check with
/skill-review)
5. Scope check
- [ ] Contribution stays within references/ (if it needs SKILL.md.tmpl changes, flag as scope change)
- [ ] No scoring formula changes without explicit maintainer approval
- [ ] No new sections added to a skill without explicit maintainer approval
- [ ] No STOP gates or AskUserQuestion patterns changed
6. PR description complete
- [ ] Links to original Issue
- [ ] Shows the diff (what changed, where)
- [ ] Lists any ⚠️ flags that need maintainer decision
- [ ] Credits the contributor
- [ ] States which skill and which file were modified
Quick pass/fail
| Check | Result |
|---|---|
| Content in right place | ✅ / ❌ |
| No contradictions | ✅ / ⚠️ (flagged) / ❌ |
| Format matches | ✅ / ❌ |
| Build + test pass | ✅ / ❌ |
| Within scope | ✅ / ⚠️ (scope change flagged) |
| PR description | ✅ / ❌ |
Ready for review if: All ✅, or all ✅ with ⚠️ flags clearly documented. Not ready if: Any ❌. Fix the ❌ items first.
Good Skill Examples — What to Learn From Each
Already refactored (use as templates)
/balance-review — Best example for "numbers-focused review skill"
- Role: "economy mathematician — reviews numbers, not feelings"
- 8 reference files, 265L main template
- Mode routing (F2P / Premium / Competitive / Live)
- Section skip rules based on mode
- Each section: apply reference + score using rubric + STOP gate
- Anti-sycophancy: forbidden phrases + forcing questions with push-back scripts
- Scoring: explicit formula per section, weighted total
/game-review — Best example for "comprehensive review with fix loop"
- Fix-then-rescore loop (re-read → re-score → update running score)
- Baseline → Final delta table with WARN if worse
- 5 review modes with weight adjustment table
- 8 reference files, 255L main template
- Downstream discoverability list
/player-experience — Best example for "simulation/walkthrough skill"
- Role: "you are a player, not a reviewer"
- 6 persona definitions in references/personas.md
- Fixed emotion vocabulary in references/emotion-vocabulary.md
- Phase-based walkthrough (not section-based review)
- Scoring with explicit deduction formula (-1/-1.5/-3/-2)
- Player Journey Map ASCII output
- "Never suggest fixes" rule
/pitch-review — Best example for "evaluation with recommendation"
- 6 forcing questions with specific push-back scripts
- Iceberg Validation Level (0-5)
- Recommendation thresholds (GREENLIGHT/PROTOTYPE/PIVOT/PASS) with explicit formula
- Operating posture ("push once, then push again")
- AI Confidence disclaimer (~70%)
External references (not in gstack-game, for pattern study)
arch-spec (C:\ai_agent\karvi\.claude\skills\arch-spec)
- Best progressive disclosure: 365L main + extensive references/
- Reads references at start with explicit
catcommands - Multiple operations (generate / review / add / shared-types)
- TodoWrite for external flow tracking
- Gotchas are the soul of the skill
pr-review-loop (C:\ai_agent\.claude\skills\pr-review-loop)
- Best state externalization: bash driver script controls the loop
- Claude follows ACTION outputs, doesn't track state itself
- Fix scope is restricted (only PR diff files, minimal changes)
- Great for high-fragility workflows
issue-pipeline (C:\ai_agent\.claude\skills\issue-pipeline)
- Best orchestrator: dispatches sub-agents, manages waves
- Dependency DAG resolution in references/
- Agent prompt templates in references/
- Interrupt recovery procedure in references/
gstack /office-hours (C:\ai_project\gstack\office-hours)
- Best mode switching: Startup vs Builder, different posture per mode
- Anti-sycophancy three layers: forbidden phrases + pushback patterns + forcing questions
- Spec review loop with adversarial subagent
- Warning: too large (52KB generated), do not copy structure wholesale
Skill Refactoring Patterns
Pattern: Progressive Disclosure Split (方案 1 — upfront read)
When to apply
Skill SKILL.md.tmpl exceeds 300 lines AND has 0 reference files.
Method
1. Read the entire SKILL.md.tmpl 2. Identify these extractable categories:
- gotchas.md — anti-sycophancy + forbidden phrases + forcing questions + Claude-specific mistakes
- scoring.md — all rubrics, formulas, point values, interpretation scales
- Per-section content — detailed analysis frameworks, evaluation tables, benchmarks
3. Keep in main SKILL.md.tmpl:
- Frontmatter
- {{PREAMBLE}}
- "Load References" instruction (read ALL upfront, before any interaction)
- Artifact Discovery
- Role identity
- Interactive routing (Phase 0 / mode selection)
- Section overview (2-3 lines per section + "Apply references/X.md" + STOP gate)
- Section transitions (fast-forward / stop / go-back)
- Action Triage (AUTO / ASK / ESCALATE summary)
- Important Rules
- Special mechanisms (Fix-then-rescore, Baseline→Final, driver scripts)
- Output templates (completion summary, score report)
- Save Artifact + Review Log
4. Target: main template ≤ 300 lines
Critical: Mechanisms to preserve
Before splitting, grep for these patterns and ensure they remain in the main template:
Baseline/Final/delta/re-score— score delta trackingFix.*Loop/fix.*rescore— iterative fix loopsSave Artifact/PROJECTS_DIR— artifact persistenceSupersedes— revision chaindriver/Driver— external state managementworktree— git isolationreview-log— review dashboard integration
"Load References" block template
## Load References (BEFORE any interaction)
\```bash
SKILL_DIR="$(find . -path '*skills/SKILL_NAME/references' -type d 2>/dev/null | head -1)"
[ -z "$SKILL_DIR" ] && SKILL_DIR="$(find ~/.claude -path '*skills/SKILL_NAME/references' -type d 2>/dev/null | head -1)"
echo "References at: $SKILL_DIR"
ls "$SKILL_DIR/" 2>/dev/null
\```
Read ALL reference files now. Do not proceed until you have read every file:
- `references/gotchas.md` — [description]
- `references/scoring.md` — [description]
- `references/[section].md` — [description]Naming conventions for reference files
| Content type | Filename |
|---|---|
| Anti-sycophancy + Claude mistakes | gotchas.md |
| Scoring rubrics + formulas | scoring.md |
| Section analysis framework | {section-topic}.md (e.g., difficulty-curve.md, economy-model.md) |
| Industry benchmarks | benchmarks.md (if shared across sections) |
| Persona definitions | personas.md |
| Emotion/vocabulary standards | emotion-vocabulary.md |
Pattern: Description as Trigger Condition
Before
description: "Game economy and balance review."After
description: "Use when a game has numbers that need checking — difficulty curves, currency flow, gacha rates, progression pacing, grind ratios, or pay-to-win concerns. Not for visual design, narrative, core loop evaluation (use /game-review), or player experience walkthrough (use /player-experience)."Formula
what it does + when to use (concrete examples) + when NOT to use (adjacent skills) + trigger phrases
Pattern: Artifact Discovery Block
Every skill that reads or writes to $_PROJECTS_DIR should have this at the top:
echo "=== Checking for prior artifacts ==="
# This skill's prior output
PREV=$(ls -t $_PROJECTS_DIR/*-{skill-name}-*.md 2>/dev/null | head -1)
[ -n "$PREV" ] && echo "Prior {skill} review: $PREV"
# Upstream artifacts
GDD=$(ls -t docs/gdd.md docs/*GDD* docs/*game-design* 2>/dev/null | head -1)
[ -n "$GDD" ] && echo "GDD: $GDD"
# Cross-skill artifacts
PREV_GAME_REVIEW=$(ls -t $_PROJECTS_DIR/*-game-review-*.md 2>/dev/null | head -1)
[ -n "$PREV_GAME_REVIEW" ] && echo "Prior game review: $PREV_GAME_REVIEW"If a prior review from THIS skill exists: read it, note score and findings, check if issues have been addressed.
Pattern: Save Artifact Block
_DATETIME=$(date +%Y%m%d-%H%M%S)
echo "Saving to: $_PROJECTS_DIR/${_USER}-${_BRANCH}-{artifact-name}-${_DATETIME}.md"Write to $_PROJECTS_DIR/{user}-{branch}-{artifact-name}-{datetime}.md. If prior artifact exists, include Supersedes: {prior filename} at top.
List downstream skills that will discover this artifact.
Skill Quality Rubric — 15 Dimensions
Each dimension 0-2:
- 0 = Missing / absent
- 1 = Present but incomplete or low quality
- 2 = Complete and well-executed
Total: /30. Grades:
- 24-30: Production — ready to use as-is
- 18-23: Usable — works but has clear gaps
- 12-17: Draft — skeleton with content, needs significant work
- 0-11: Skeleton — structure only
---
A. Entry Layer (first second the user triggers the skill)
A1. Trigger Description
- 0 = description is just a feature summary ("Game balance review")
- 1 = has when-to-use, missing when-NOT-to-use or trigger phrases
- 2 = complete: what it does + when to use + when NOT to use + adjacent skills + trigger phrases
A2. Role Identity
- 0 = no explicit role
- 1 = role exists but vague ("you are a game reviewer")
- 2 = one sentence that locks the agent into a specific posture ("you are an economy mathematician — show numbers, not feelings")
A3. Mode Routing
- 0 = no mode distinction, single path
- 1 = has modes but relies on Claude to infer which
- 2 = explicit args parsing or AskUserQuestion routing at entry, locked after selection
B. Flow Layer (execution skeleton)
B4. Flow Externalization
- 0 = relies on Claude memory for flow
- 1 = has phases/sections but no external tracking
- 2 = uses TodoWrite / driver script / status table / explicit phase gates
B5. STOP Gates
- 0 = no STOP rules
- 1 = has "one issue per AskUserQuestion" but not every section
- 2 = every section ends with STOP + "resolve all before proceeding"
B6. Recovery / Interrupt Handling
- 0 = absent
- 1 = basic error handling table
- 2 = full recovery procedure (rebuild state, resume from incomplete phase)
C. Knowledge Layer (what the skill gives Claude)
C7. Gotchas
- 0 = absent
- 1 = has anti-sycophancy forbidden phrases only
- 2 = has Claude-specific operational gotchas (what Claude gets wrong doing THIS task) + forbidden phrases + forcing questions
C8. Scoring / Quantitative Rigor
- 0 = no scoring, qualitative only
- 1 = has scoring but relies on AI intuition
- 2 = explicit formula per dimension + calibrated benchmarks + no AI intuition
C9. Domain Benchmarks
- 0 = no industry reference data
- 1 = scattered references
- 2 = structured benchmark tables with healthy/warning/critical thresholds
D. Structure Layer (file organization)
D10. Progressive Disclosure
- 0 = everything in one SKILL.md (>300 lines)
- 1 = has references/ but only 1-2 files
- 2 = SKILL.md is orchestration (<300 lines), details in references/ (gotchas, scoring, section content, benchmarks)
D11. Helper Code / Scripts
- 0 = pure markdown, nothing executable
- 1 = has inline bash blocks but no bundled scripts
- 2 = has scripts/ directory or bundled helpers (driver scripts, calculation tools, templates)
D12. Config / Memory
- 0 = absent
- 1 = has review log but no per-project config
- 2 = has config.json (remembers project context) + review history (reads own past results)
E. System Layer (relationship to other skills)
E13. Artifact Discovery
- 0 = starts from zero, doesn't look for upstream artifacts
- 1 = finds primary doc (GDD) but not other skills' outputs
- 2 = searches for GDD + prior reviews from this skill + outputs from other skills (balance, direction, etc.)
E14. Output Contract
- 0 = output is chat text only
- 1 = has completion summary but doesn't write to file
- 2 = writes artifact to ~/.gstack/projects/ (discoverable by downstream) + review log + structured format
E15. Workflow Position
- 0 = isolated, doesn't know upstream/downstream
- 1 = recommends next skill at end
- 2 = reads upstream artifacts at start + writes artifacts for downstream + recommends next step
name: "📊 修正 Benchmark"
description: "某個數字過時或不正確——你知道正確的數字"
title: "benchmark(SKILL_NAME): 簡短描述"
labels: ["benchmark", "domain-knowledge"]
body:
- type: dropdown
id: skill
attributes:
label: 哪個 Skill
options:
- /game-review
- /balance-review
- /player-experience
- /pitch-review
- /game-code-review
- /game-eng-review
- /game-qa
- /game-ux-review
- /game-ship
- 不確定
validations:
required: true
- type: textarea
id: current
attributes:
label: 目前的值
placeholder: |
例:D1 retention > 40% = good(在 references/scoring.md 或 SKILL.md.tmpl 裡)
validations:
required: true
- type: textarea
id: correct
attributes:
label: 應該改成什麼
placeholder: |
例:2026 年 F2P casual mobile 的 D1 應該是 35-45% = average,> 50% = good。
買斷遊戲和 F2P 要分開。
validations:
required: true
- type: textarea
id: source
attributes:
label: 數據來源
description: 公開報告、你的遊戲的數據、業界共識都可以
placeholder: |
例:Sensor Tower 2026 Q1 report / 我們自己的 4 款遊戲 UA 數據 / GameDiscoverCo newsletter
validations:
required: true
- type: input
id: file
attributes:
label: 在哪個檔案
placeholder: "references/scoring.md 或 references/progression.md"
blank_issues_enabled: true
contact_links:
- name: "💬 不確定怎麼貢獻?"
url: https://github.com/fagemx/gstack-game/issues/new
about: "開一個 Issue 說你的專業領域和想貢獻什麼,我們會幫你找到對的位置。"
name: "❓ 新增逼問問題"
description: "審查時應該問但沒問的關鍵問題"
title: "question(SKILL_NAME): 簡短描述"
labels: ["forcing-question", "domain-knowledge"]
body:
- type: dropdown
id: skill
attributes:
label: 哪個 Skill
options:
- /game-review
- /balance-review
- /player-experience
- /pitch-review
- /game-direction
- /game-ideation
- /game-eng-review
- /game-code-review
- /game-qa
- 不確定
validations:
required: true
- type: textarea
id: question
attributes:
label: 問題(逐字)
description: 寫出你會在審查時問的確切問題
placeholder: |
例:「把你的遊戲的音效全部關掉,只看畫面。核心循環還有趣嗎?再把畫面關掉只聽音效。還有趣嗎?」
validations:
required: true
- type: textarea
id: push
attributes:
label: 如果回答模糊,怎麼追問
description: 當設計師給出空洞答案時,你怎麼逼出真正的回答
placeholder: |
例:如果設計師說「當然有趣啊,操控感很好」,追問:「操控感 = 什麼?輸入延遲幾 ms?
有沒有 screen shake?擊中回饋是什麼?說出具體數字。」
validations:
required: true
- type: textarea
id: why
attributes:
label: 為什麼這個問題重要
placeholder: |
例:我 greenlight 過 20+ 案子。最常見的假陽性就是「Demo 看起來很酷但玩起來空洞」。
validations:
required: true
- type: input
id: section
attributes:
label: 建議放在哪個 Section
placeholder: "Section 1: Core Loop 的 Forcing Questions"
name: "🎯 新增 Gotcha"
description: "Claude 在某個任務上會犯的錯——你知道正確做法是什麼"
title: "gotcha(SKILL_NAME): 簡短描述"
labels: ["gotcha", "domain-knowledge"]
body:
- type: dropdown
id: skill
attributes:
label: 哪個 Skill
options:
- /game-review
- /balance-review
- /player-experience
- /pitch-review
- /game-code-review
- /game-eng-review
- /game-direction
- /game-ideation
- /game-qa
- /game-ux-review
- /game-ship
- /game-import
- /asset-review
- /playtest
- /game-debug
- /game-retro
- /game-visual-qa
- /game-codex
- /game-docs
- 不確定
validations:
required: true
- type: textarea
id: wrong
attributes:
label: Claude 會怎麼做(錯的)
description: 描述 Claude 在這個任務上常犯的錯
placeholder: |
例:Claude 分析放置類遊戲的經濟時,會把通膨率 > 1.2 標記為紅旗。
validations:
required: true
- type: textarea
id: right
attributes:
label: 正確做法是什麼
description: 你知道的正確做法
placeholder: |
例:放置類遊戲的通膨是設計。正確的做法是看「通膨速度是否匹配 prestige 重置頻率」。
validations:
required: true
- type: textarea
id: evidence
attributes:
label: 你怎麼知道的(經驗 / 數據)
placeholder: |
例:做過 2 款放置類遊戲,調過半年的 live 經濟。
validations:
required: true
- type: input
id: file
attributes:
label: 建議加在哪個檔案
description: 如果你知道的話(不確定也沒關係)
placeholder: "references/gotchas.md"
name: "⚖️ 校準評分"
description: "某個評分標準的權重或門檻需要調整"
title: "scoring(SKILL_NAME): 簡短描述"
labels: ["scoring", "domain-knowledge"]
body:
- type: dropdown
id: skill
attributes:
label: 哪個 Skill
options:
- /game-review
- /balance-review
- /player-experience
- /pitch-review
- /game-code-review
- /game-eng-review
- /game-qa
- /game-ux-review
- 不確定
validations:
required: true
- type: textarea
id: current
attributes:
label: 目前的評分標準
description: 貼出現有的權重、門檻或公式
placeholder: |
例:Section 1 Core Loop 權重 = 25%(所有模式統一)
validations:
required: true
- type: textarea
id: problem
attributes:
label: 什麼問題
placeholder: |
例:F2P 手遊的 Core Loop 應該是 30% 不是 25%。在手遊裡 loop 就是整個遊戲,
如果 loop 不好,經濟和留存都沒用。但 PC 敘事遊戲的 Core Loop 可能只有 15%——
玩家是為了故事來的。
validations:
required: true
- type: textarea
id: suggestion
attributes:
label: 建議改成什麼
description: 給出具體的新權重或門檻
placeholder: |
例:
Mobile/F2P: Core Loop 30%, Progression 25%, Economy 25%, Motivation 10%, Risk 5%, Cross 5%
PC/Narrative: Core Loop 15%, Progression 15%, Economy 5%, Motivation 30%, Risk 10%, Cross 25%
validations:
required: true
- type: textarea
id: evidence
attributes:
label: 根據什麼
placeholder: |
例:基於我做過的 5 款手遊的 GDD review 經驗。Core Loop 差的手遊 D1 < 20%,
但 Core Loop 差的敘事 PC 遊戲只要故事好還是能有 60%+ 好評。
validations:
required: true
# Environment
.env
.env.local
.env.*
!.env.example
# Dependencies
node_modules/
# Bun
bun.lock
*.bun-build
# Claude Code local settings
.claude/settings.local.json
.context/
# gstack local state
.gstack/
# OS files
.DS_Store
Thumbs.db
# Editor
*.swp
*.swo
*~
.vscode/
.idea/
# Logs & telemetry (local only)
*.log
*.jsonl
# Temp
/tmp/
.claude/worktrees/
.tmp/
#!/usr/bin/env bash
# gstack-config — read/write ~/.gstack/config.yaml
#
# Usage:
# gstack-config get <key> — read a config value
# gstack-config set <key> <value> — write a config value
# gstack-config list — show all config
#
# Env overrides (for testing):
# GSTACK_STATE_DIR — override ~/.gstack state directory
set -euo pipefail
STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}"
CONFIG_FILE="$STATE_DIR/config.yaml"
# Validate key: only alphanumeric, hyphens, and underscores allowed
validate_key() {
case "$1" in
*[!a-zA-Z0-9_-]*) echo "gstack-config: invalid key '$1'" >&2; exit 1 ;;
'') echo "gstack-config: empty key" >&2; exit 1 ;;
esac
}
case "${1:-}" in
get)
KEY="${2:?Usage: gstack-config get <key>}"
validate_key "$KEY"
grep -F "${KEY}:" "$CONFIG_FILE" 2>/dev/null | grep -E "^${KEY}:" | tail -1 | awk '{print $2}' | tr -d '[:space:]' || true
;;
set)
KEY="${2:?Usage: gstack-config set <key> <value>}"
VALUE="${3:?Usage: gstack-config set <key> <value>}"
validate_key "$KEY"
mkdir -p "$STATE_DIR"
# Escape sed replacement special characters in value
ESCAPED_VALUE="$(printf '%s' "$VALUE" | sed 's/[&/\]/\\&/g')"
if grep -qF "${KEY}:" "$CONFIG_FILE" 2>/dev/null && grep -qE "^${KEY}:" "$CONFIG_FILE" 2>/dev/null; then
# Portable sed: use temp file instead of sed -i (not portable across macOS/Linux)
TMPFILE="$(mktemp)"
sed "s/^${KEY}:.*/${KEY}: ${ESCAPED_VALUE}/" "$CONFIG_FILE" > "$TMPFILE"
mv "$TMPFILE" "$CONFIG_FILE"
else
echo "${KEY}: ${VALUE}" >> "$CONFIG_FILE"
fi
;;
list)
cat "$CONFIG_FILE" 2>/dev/null || true
;;
*)
echo "Usage: gstack-config {get|set|list} [key] [value]"
exit 1
;;
esac
#!/usr/bin/env bash
# gstack-game diff-scope — categorize what changed in the diff for game projects
# Usage: source <(gstack-diff-scope main) → sets SCOPE_*=true/false
# Or: gstack-diff-scope main → prints SCOPE_*=... lines
set -euo pipefail
BASE="${1:-main}"
# Get changed file list
FILES=$(git diff "${BASE}...HEAD" --name-only 2>/dev/null || git diff "${BASE}" --name-only 2>/dev/null || echo "")
if [ -z "$FILES" ]; then
echo "SCOPE_GAMEPLAY=false"
echo "SCOPE_ENGINE=false"
echo "SCOPE_UI=false"
echo "SCOPE_AI=false"
echo "SCOPE_NETWORK=false"
echo "SCOPE_SHADERS=false"
echo "SCOPE_ASSETS=false"
echo "SCOPE_DATA=false"
echo "SCOPE_TESTS=false"
echo "SCOPE_DOCS=false"
echo "SCOPE_CONFIG=false"
exit 0
fi
GAMEPLAY=false
ENGINE=false
UI=false
AI=false
NETWORK=false
SHADERS=false
ASSETS=false
DATA=false
TESTS=false
DOCS=false
CONFIG=false
while IFS= read -r f; do
case "$f" in
# Gameplay: game logic, mechanics, systems
src/gameplay/*|game/gameplay/*|scripts/gameplay/*|src/systems/*) GAMEPLAY=true ;;
*controller*|*character*|*combat*|*inventory*|*quest*|*ability*) GAMEPLAY=true ;;
# Engine / Core: framework, core systems
src/core/*|src/engine/*|game/core/*|addons/*/src/*) ENGINE=true ;;
*singleton*|*autoload*|*manager*.gd|*manager*.cs|*manager*.cpp) ENGINE=true ;;
# UI: interface, HUD, menus
src/ui/*|game/ui/*|scenes/ui/*|UI/*|ui/*) UI=true ;;
*.tscn|*.uxml|*.uss) UI=true ;;
# AI: game AI, behavior trees, state machines
src/ai/*|game/ai/*|scripts/ai/*) AI=true ;;
*behavior_tree*|*state_machine*|*bt_*|*fsm_*) AI=true ;;
# Network: multiplayer, replication
src/network*|src/net/*|game/network*|scripts/network*) NETWORK=true ;;
*replication*|*rpc*|*netcode*|*sync*) NETWORK=true ;;
# Shaders: visual effects, rendering
*.shader|*.gdshader|*.hlsl|*.glsl|*.cginc|*.vert|*.frag|*.compute) SHADERS=true ;;
*.shadergraph|*.usf|*.ush) SHADERS=true ;;
# Assets: art, audio, animations
*.png|*.jpg|*.jpeg|*.webp|*.svg|*.psd|*.tga|*.bmp|*.exr) ASSETS=true ;;
*.wav|*.ogg|*.mp3|*.flac|*.opus|*.aiff) ASSETS=true ;;
*.fbx|*.gltf|*.glb|*.obj|*.blend|*.dae) ASSETS=true ;;
*.anim|*.animation|*.tres|*.aab) ASSETS=true ;;
assets/*|art/*|audio/*|models/*|textures/*|sprites/*|animations/*) ASSETS=true ;;
# Data: balance tables, configs, levels
*.json|*.csv|*.tsv|*.xml) DATA=true ;;
data/*|balance/*|levels/*|maps/*|design/balance/*) DATA=true ;;
*loot_table*|*drop_rate*|*difficulty*|*curve*|*economy*) DATA=true ;;
# Tests
*.test.*|*.spec.*|*_test.*|*_spec.*) TESTS=true ;;
test/*|tests/*|spec/*|__tests__/*) TESTS=true ;;
# Docs
*.md|docs/*|design/gdd/*) DOCS=true ;;
# Config: project settings, build config, CI
*.cfg|*.ini|*.toml|*.yml|*.yaml) CONFIG=true ;;
project.godot|ProjectSettings/*|*.uproject) CONFIG=true ;;
package.json|package-lock.json|bun.lockb|Cargo.toml|*.csproj|*.sln) CONFIG=true ;;
.github/*|.gitlab-ci*|Makefile|CMakeLists.txt) CONFIG=true ;;
export_presets.cfg|*.keystore|*.plist) CONFIG=true ;;
esac
done <<< "$FILES"
echo "SCOPE_GAMEPLAY=$GAMEPLAY"
echo "SCOPE_ENGINE=$ENGINE"
echo "SCOPE_UI=$UI"
echo "SCOPE_AI=$AI"
echo "SCOPE_NETWORK=$NETWORK"
echo "SCOPE_SHADERS=$SHADERS"
echo "SCOPE_ASSETS=$ASSETS"
echo "SCOPE_DATA=$DATA"
echo "SCOPE_TESTS=$TESTS"
echo "SCOPE_DOCS=$DOCS"
echo "SCOPE_CONFIG=$CONFIG"
#!/usr/bin/env bun
import { readFileSync } from "fs";
type Severity = "high" | "medium" | "low";
type Category = "credential" | "pii" | "platform" | "business";
type PatternSpec = {
id: string;
severity: Severity;
category: Category;
regex: RegExp;
};
type Finding = {
id: string;
severity: Severity;
category: Category;
line: number;
col: number;
preview: string;
};
const PATTERNS: PatternSpec[] = [
{
id: "github.pat",
severity: "high",
category: "credential",
regex: /\bgh[pousr]_[A-Za-z0-9_]{20,255}\b/g,
},
{
id: "openai.key",
severity: "high",
category: "credential",
regex: /\bsk-[A-Za-z0-9_-]{32,}\b/g,
},
{
id: "aws.access_key",
severity: "high",
category: "credential",
regex: /\bAKIA[0-9A-Z]{16}\b/g,
},
{
id: "steam.publisher_key",
severity: "high",
category: "credential",
regex: /\bsteam(?:works)?[_-]?(?:api|publisher)?[_-]?key\s*[:=]\s*["']?[A-Za-z0-9]{24,}["']?/gi,
},
{
id: "pii.email",
severity: "medium",
category: "pii",
regex: /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,
},
{
id: "platform.nda",
severity: "medium",
category: "platform",
regex: /\b(?:platform NDA|under NDA|confidential publisher|first-party confidential|embargoed build)\b/gi,
},
];
const args = process.argv.slice(2);
const jsonMode = args.includes("--json");
const helpMode = args.includes("--help") || args.includes("-h");
const fromFileIdx = args.indexOf("--from-file");
function usage(): void {
console.log(`Usage: gstack-game-redact [--json] [--from-file path]
Scans public or semi-public game workflow output before it leaves the repo.
High findings block. Medium findings require review or redaction.
`);
}
function readInput(): string {
if (fromFileIdx !== -1) {
const path = args[fromFileIdx + 1];
if (!path) {
console.error("Missing path after --from-file");
process.exit(1);
}
return readFileSync(path, "utf-8");
}
return readFileSync(0, "utf-8");
}
function locate(text: string, index: number): { line: number; col: number } {
let line = 1;
let lineStart = 0;
for (let i = 0; i < index; i++) {
if (text.charCodeAt(i) === 10) {
line++;
lineStart = i + 1;
}
}
return { line, col: index - lineStart + 1 };
}
function mask(value: string): string {
const clean = value.replace(/\s+/g, " ");
if (clean.length <= 8) return "[redacted]";
return `${clean.slice(0, 4)}...${clean.slice(-4)}`;
}
function scan(text: string): Finding[] {
const findings: Finding[] = [];
for (const pattern of PATTERNS) {
pattern.regex.lastIndex = 0;
for (const match of text.matchAll(pattern.regex)) {
const index = match.index ?? 0;
const pos = locate(text, index);
findings.push({
id: pattern.id,
severity: pattern.severity,
category: pattern.category,
line: pos.line,
col: pos.col,
preview: mask(match[0]),
});
}
}
return findings.sort((a, b) => a.line - b.line || a.col - b.col || a.id.localeCompare(b.id));
}
function countsFor(findings: Finding[]): Record<Severity, number> {
return {
high: findings.filter((f) => f.severity === "high").length,
medium: findings.filter((f) => f.severity === "medium").length,
low: findings.filter((f) => f.severity === "low").length,
};
}
if (helpMode) {
usage();
process.exit(0);
}
const input = readInput();
const findings = scan(input);
const counts = countsFor(findings);
const exitCode = counts.high > 0 ? 3 : counts.medium > 0 ? 2 : 0;
if (jsonMode) {
console.log(JSON.stringify({ ok: exitCode === 0, counts, findings }, null, 2));
} else if (exitCode === 0) {
console.log("No high or medium redaction findings.");
} else {
console.log(`Redaction findings: high=${counts.high} medium=${counts.medium} low=${counts.low}`);
for (const finding of findings) {
console.log(`${finding.severity.toUpperCase()} ${finding.id} ${finding.line}:${finding.col} ${finding.preview}`);
}
}
process.exit(exitCode);
#!/usr/bin/env bash
# gstack-review-log — atomically log a review result
# Usage: gstack-review-log '{"skill":"...","timestamp":"...","status":"..."}'
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
eval $("$SCRIPT_DIR/gstack-slug" 2>/dev/null)
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
mkdir -p "$GSTACK_HOME/projects/$SLUG"
# Validate: input must be parseable JSON (reject malformed or injection attempts)
INPUT="$1"
if ! printf '%s' "$INPUT" | bun -e "JSON.parse(await Bun.stdin.text())" 2>/dev/null; then
echo "gstack-review-log: invalid JSON, skipping" >&2
exit 1
fi
printf '%s\n' "$INPUT" >> "$GSTACK_HOME/projects/$SLUG/$BRANCH-reviews.jsonl"
#!/usr/bin/env bash
# gstack-review-read — read review log and config for dashboard
# Usage: gstack-review-read
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
eval $("$SCRIPT_DIR/gstack-slug" 2>/dev/null)
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
cat "$GSTACK_HOME/projects/$SLUG/$BRANCH-reviews.jsonl" 2>/dev/null || echo "NO_REVIEWS"
echo "---CONFIG---"
"$SCRIPT_DIR/gstack-config" get skip_eng_review 2>/dev/null || echo "false"
echo "---HEAD---"
git rev-parse --short HEAD 2>/dev/null || echo "unknown"
#!/usr/bin/env bash
# gstack-slug — output project slug and sanitized branch name
# Usage: source <(gstack-slug) → sets SLUG and BRANCH variables
# Or: gstack-slug → prints SLUG=... and BRANCH=... lines
#
# Security: output is sanitized to [a-zA-Z0-9._-] only, preventing
# shell injection when consumed via source or eval.
set -euo pipefail
RAW_SLUG=$(git remote get-url origin 2>/dev/null | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-') || true
RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '-') || true
# Strip any characters that aren't alphanumeric, dot, hyphen, or underscore
SLUG=$(printf '%s' "${RAW_SLUG:-}" | tr -cd 'a-zA-Z0-9._-')
BRANCH=$(printf '%s' "${RAW_BRANCH:-}" | tr -cd 'a-zA-Z0-9._-')
# Fallback when git context is absent
SLUG="${SLUG:-$(basename "$PWD" | tr -cd 'a-zA-Z0-9._-')}"
BRANCH="${BRANCH:-unknown}"
echo "SLUG=$SLUG"
echo "BRANCH=$BRANCH"
#!/usr/bin/env bash
# gstack-telemetry-log — append a telemetry event to local JSONL
#
# Data flow:
# preamble (start) ──▶ .pending marker
# preamble (epilogue) ──▶ gstack-telemetry-log ──▶ skill-usage.jsonl
# └──▶ gstack-telemetry-sync (bg)
#
# Usage:
# gstack-telemetry-log --skill qa --duration 142 --outcome success \
# --used-browse true --session-id "12345-1710756600"
#
# Env overrides (for testing):
# GSTACK_STATE_DIR — override ~/.gstack state directory
# GSTACK_DIR — override auto-detected gstack root
#
# NOTE: Uses set -uo pipefail (no -e) — telemetry must never exit non-zero
set -uo pipefail
GSTACK_DIR="${GSTACK_DIR:-$(cd "$(dirname "$0")/.." && pwd)}"
STATE_DIR="${GSTACK_STATE_DIR:-$HOME/.gstack}"
ANALYTICS_DIR="$STATE_DIR/analytics"
JSONL_FILE="$ANALYTICS_DIR/skill-usage.jsonl"
PENDING_DIR="$ANALYTICS_DIR" # .pending-* files live here
CONFIG_CMD="$GSTACK_DIR/bin/gstack-config"
VERSION_FILE="$GSTACK_DIR/VERSION"
# ─── Parse flags ─────────────────────────────────────────────
SKILL=""
DURATION=""
OUTCOME="unknown"
USED_BROWSE="false"
SESSION_ID=""
ERROR_CLASS=""
EVENT_TYPE="skill_run"
while [ $# -gt 0 ]; do
case "$1" in
--skill) SKILL="$2"; shift 2 ;;
--duration) DURATION="$2"; shift 2 ;;
--outcome) OUTCOME="$2"; shift 2 ;;
--used-browse) USED_BROWSE="$2"; shift 2 ;;
--session-id) SESSION_ID="$2"; shift 2 ;;
--error-class) ERROR_CLASS="$2"; shift 2 ;;
--event-type) EVENT_TYPE="$2"; shift 2 ;;
*) shift ;;
esac
done
# ─── Read telemetry tier ─────────────────────────────────────
TIER="$("$CONFIG_CMD" get telemetry 2>/dev/null || true)"
TIER="${TIER:-off}"
# Validate tier
case "$TIER" in
off|anonymous|community) ;;
*) TIER="off" ;; # invalid value → default to off
esac
if [ "$TIER" = "off" ]; then
# Still clear pending markers for this session even if telemetry is off
[ -n "$SESSION_ID" ] && rm -f "$PENDING_DIR/.pending-$SESSION_ID" 2>/dev/null || true
exit 0
fi
# ─── Finalize stale .pending markers ────────────────────────
# Each session gets its own .pending-$SESSION_ID file to avoid races
# between concurrent sessions. Finalize any that don't match our session.
for PFILE in "$PENDING_DIR"/.pending-*; do
[ -f "$PFILE" ] || continue
# Skip our own session's marker (it's still in-flight)
PFILE_BASE="$(basename "$PFILE")"
PFILE_SID="${PFILE_BASE#.pending-}"
[ "$PFILE_SID" = "$SESSION_ID" ] && continue
PENDING_DATA="$(cat "$PFILE" 2>/dev/null || true)"
rm -f "$PFILE" 2>/dev/null || true
if [ -n "$PENDING_DATA" ]; then
# Extract fields from pending marker using grep -o + awk
P_SKILL="$(echo "$PENDING_DATA" | grep -o '"skill":"[^"]*"' | head -1 | awk -F'"' '{print $4}')"
P_TS="$(echo "$PENDING_DATA" | grep -o '"ts":"[^"]*"' | head -1 | awk -F'"' '{print $4}')"
P_SID="$(echo "$PENDING_DATA" | grep -o '"session_id":"[^"]*"' | head -1 | awk -F'"' '{print $4}')"
P_VER="$(echo "$PENDING_DATA" | grep -o '"gstack_version":"[^"]*"' | head -1 | awk -F'"' '{print $4}')"
P_OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
P_ARCH="$(uname -m)"
# Write the stale event as outcome: unknown
mkdir -p "$ANALYTICS_DIR"
printf '{"v":1,"ts":"%s","event_type":"skill_run","skill":"%s","session_id":"%s","gstack_version":"%s","os":"%s","arch":"%s","duration_s":null,"outcome":"unknown","error_class":null,"used_browse":false,"sessions":1}\n' \
"$P_TS" "$P_SKILL" "$P_SID" "$P_VER" "$P_OS" "$P_ARCH" >> "$JSONL_FILE" 2>/dev/null || true
fi
done
# Clear our own session's pending marker (we're about to log the real event)
[ -n "$SESSION_ID" ] && rm -f "$PENDING_DIR/.pending-$SESSION_ID" 2>/dev/null || true
# ─── Sanitization ──────────────────────────────────────────────
# Strip quotes, backslashes, and control characters from string values
json_safe() {
printf '%s' "$1" | tr -d '"\\\n\r\t' | cut -c1-200
}
# ─── Collect metadata ────────────────────────────────────────
TS="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u +%Y-%m-%dT%H:%M:%S 2>/dev/null || echo "")"
GSTACK_VERSION="$(cat "$VERSION_FILE" 2>/dev/null | tr -d '[:space:]' || echo "unknown")"
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
SESSIONS="1"
if [ -d "$STATE_DIR/sessions" ]; then
_SC="$(find "$STATE_DIR/sessions" -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' \n\r\t')"
[ -n "$_SC" ] && [ "$_SC" -gt 0 ] 2>/dev/null && SESSIONS="$_SC"
fi
# Generate installation_id for community tier (random UUID, persisted)
INSTALL_ID=""
if [ "$TIER" = "community" ]; then
INSTALL_ID_FILE="$STATE_DIR/.installation-id"
if [ -f "$INSTALL_ID_FILE" ]; then
INSTALL_ID="$(cat "$INSTALL_ID_FILE" 2>/dev/null || true)"
fi
if [ -z "$INSTALL_ID" ]; then
# Generate random UUID — try multiple methods
INSTALL_ID="$(uuidgen 2>/dev/null | tr '[:upper:]' '[:lower:]' || true)"
[ -z "$INSTALL_ID" ] && INSTALL_ID="$(cat /proc/sys/kernel/random/uuid 2>/dev/null || true)"
[ -z "$INSTALL_ID" ] && INSTALL_ID="$(od -x /dev/urandom 2>/dev/null | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' || true)"
# Persist for future runs
if [ -n "$INSTALL_ID" ]; then
mkdir -p "$STATE_DIR"
printf '%s' "$INSTALL_ID" > "$INSTALL_ID_FILE" 2>/dev/null || true
fi
fi
fi
# Local-only fields (never sent remotely)
REPO_SLUG=""
BRANCH=""
if command -v git >/dev/null 2>&1; then
REPO_SLUG="$(git remote get-url origin 2>/dev/null | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-' 2>/dev/null || true)"
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
fi
# ─── Construct and append JSON ───────────────────────────────
mkdir -p "$ANALYTICS_DIR"
# Sanitize all string fields
SKILL="$(json_safe "$SKILL")"
OUTCOME="$(json_safe "$OUTCOME")"
SESSION_ID="$(json_safe "$SESSION_ID")"
EVENT_TYPE="$(json_safe "$EVENT_TYPE")"
ERROR_CLASS="$(json_safe "$ERROR_CLASS")"
REPO_SLUG="$(json_safe "$REPO_SLUG")"
BRANCH="$(json_safe "$BRANCH")"
# Escape null fields
ERR_FIELD="null"
[ -n "$ERROR_CLASS" ] && ERR_FIELD="\"$ERROR_CLASS\""
# Validate and cap duration (0–86400s)
DUR_FIELD="null"
if [ -n "$DURATION" ]; then
case "$DURATION" in
''|*[!0-9]*) DURATION="0" ;; # non-numeric → 0
esac
[ "$DURATION" -lt 0 ] 2>/dev/null && DURATION="0"
[ "$DURATION" -gt 86400 ] 2>/dev/null && DURATION="86400"
DUR_FIELD="$DURATION"
fi
INSTALL_FIELD="null"
[ -n "$INSTALL_ID" ] && INSTALL_FIELD="\"$INSTALL_ID\""
BROWSE_BOOL="false"
[ "$USED_BROWSE" = "true" ] && BROWSE_BOOL="true"
printf '{"v":1,"ts":"%s","event_type":"%s","skill":"%s","session_id":"%s","gstack_version":"%s","os":"%s","arch":"%s","duration_s":%s,"outcome":"%s","error_class":%s,"used_browse":%s,"sessions":%s,"installation_id":%s,"_repo_slug":"%s","_branch":"%s"}\n' \
"$TS" "$EVENT_TYPE" "$SKILL" "$SESSION_ID" "$GSTACK_VERSION" "$OS" "$ARCH" \
"$DUR_FIELD" "$OUTCOME" "$ERR_FIELD" "$BROWSE_BOOL" "${SESSIONS:-1}" \
"$INSTALL_FIELD" "$REPO_SLUG" "$BRANCH" >> "$JSONL_FILE" 2>/dev/null || true
# ─── Trigger sync if tier is not off ─────────────────────────
SYNC_CMD="$GSTACK_DIR/bin/gstack-telemetry-sync"
if [ -x "$SYNC_CMD" ]; then
"$SYNC_CMD" 2>/dev/null &
fi
exit 0
#!/bin/bash
# gstack-game installer
# Copies game design skills + routing skill + bin utilities into the target project's .claude/skills/
#
# Usage:
# /path/to/gstack-game/bin/install.sh . # install to current project
# /path/to/gstack-game/bin/install.sh /my/game # install to specific project
# /path/to/gstack-game/bin/install.sh --prefix /my/game # use gg- prefix (namespaced)
# /path/to/gstack-game/bin/install.sh --no-prefix /my/game # use short names (no prefix)
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
CONFIG_CMD="$SCRIPT_DIR/bin/gstack-config"
# ─── Parse flags ──────────────────────────────────────────────
PREFIX_FLAG=""
TARGET=""
for arg in "$@"; do
case "$arg" in
--prefix) PREFIX_FLAG="namespaced" ;;
--no-prefix) PREFIX_FLAG="short" ;;
-*) echo "Unknown flag: $arg"; exit 1 ;;
*) TARGET="$arg" ;;
esac
done
TARGET="${TARGET:-.}"
if [ ! -d "$TARGET" ]; then
echo "Error: Target directory '$TARGET' does not exist."
exit 1
fi
# ─── Determine skill prefix mode ─────────────────────────────
SKILL_PREFIX=""
if [ -n "$PREFIX_FLAG" ]; then
SKILL_PREFIX="$PREFIX_FLAG"
elif SAVED="$("$CONFIG_CMD" get skill_prefix 2>/dev/null)" && [ -n "$SAVED" ]; then
SKILL_PREFIX="$SAVED"
else
# Interactive prompt (skip in non-TTY / CI — default to short)
if [ -t 0 ]; then
echo ""
echo "How should gstack-game skills appear?"
echo " A) Short names: /game-review, /balance-review (recommended)"
echo " B) Namespaced: /gg-game-review, /gg-balance-review"
echo ""
printf "Choose [A/b] (auto-selects A in 10s): "
if read -t 10 -r CHOICE 2>/dev/null; then
case "$CHOICE" in
[Bb]) SKILL_PREFIX="namespaced" ;;
*) SKILL_PREFIX="short" ;;
esac
else
echo ""
echo " → Auto-selected: short names"
SKILL_PREFIX="short"
fi
else
SKILL_PREFIX="short"
fi
fi
# Save preference
"$CONFIG_CMD" set skill_prefix "$SKILL_PREFIX" 2>/dev/null || true
echo "Installing gstack-game to $TARGET/.claude/skills/ (prefix: $SKILL_PREFIX) ..."
# 1. Create gstack-game hub directory for bin/ and routing skill
mkdir -p "$TARGET/.claude/skills/gstack-game/bin"
# 2. Copy bin utilities
cp "$SCRIPT_DIR"/bin/gstack-* "$TARGET/.claude/skills/gstack-game/bin/" 2>/dev/null || true
chmod +x "$TARGET/.claude/skills/gstack-game/bin/"* 2>/dev/null || true
echo " ✓ bin/ utilities"
# 3. Copy root-level routing skill (tells Claude when to suggest which skill)
if [ -f "$SCRIPT_DIR/SKILL.md" ]; then
cp "$SCRIPT_DIR/SKILL.md" "$TARGET/.claude/skills/gstack-game/SKILL.md"
echo " ✓ routing skill (gstack-game/SKILL.md)"
fi
# 4. Copy all skills (skip 'shared' — it's baked into SKILL.md via template engine)
# If namespaced mode, install as gg-{skillname}; if short, install as {skillname}.
# Clean up any leftover directories from the other naming mode.
SKILL_COUNT=0
for skill_dir in "$SCRIPT_DIR/skills"/*/; do
skill_name=$(basename "$skill_dir")
[ "$skill_name" = "shared" ] && continue
if [ -f "$skill_dir/SKILL.md" ]; then
if [ "$SKILL_PREFIX" = "namespaced" ]; then
dest_name="gg-${skill_name}"
old_name="$skill_name"
else
dest_name="$skill_name"
old_name="gg-${skill_name}"
fi
# Remove old-mode directory if switching prefix modes
if [ -d "$TARGET/.claude/skills/$old_name" ]; then
rm -rf "$TARGET/.claude/skills/$old_name"
fi
cp -r "$skill_dir" "$TARGET/.claude/skills/$dest_name"
echo " ✓ /$dest_name"
SKILL_COUNT=$((SKILL_COUNT + 1))
fi
done
# 5. Add gstack-game section to CLAUDE.md if it doesn't exist
# Skill list reflects the chosen prefix mode.
CLAUDE_MD="$TARGET/CLAUDE.md"
if [ "$SKILL_PREFIX" = "namespaced" ]; then
SKILL_LIST="/gg-game-import, /gg-game-ideation, /gg-game-direction, /gg-game-review, /gg-game-eng-review,
/gg-balance-review, /gg-player-experience, /gg-game-ux-review, /gg-pitch-review,
/gg-gameplay-implementation-review, /gg-game-qa, /gg-game-ship, /gg-game-debug, /gg-game-retro,
/gg-game-codex, /gg-game-docs, /gg-game-visual-qa, /gg-asset-review, /gg-playtest,
/gg-careful, /gg-guard, /gg-unfreeze."
else
SKILL_LIST="/game-import, /game-ideation, /game-direction, /game-review, /game-eng-review,
/balance-review, /player-experience, /game-ux-review, /pitch-review,
/gameplay-implementation-review, /game-qa, /game-ship, /game-debug, /game-retro,
/game-codex, /game-docs, /game-visual-qa, /asset-review, /playtest,
/careful, /guard, /unfreeze."
fi
GSTACK_SECTION="## gstack-game
Game development workflow skills are installed. Available skills:
${SKILL_LIST}"
if [ -f "$CLAUDE_MD" ]; then
if ! grep -q "gstack-game" "$CLAUDE_MD" 2>/dev/null; then
printf '\n%s\n' "$GSTACK_SECTION" >> "$CLAUDE_MD"
echo " ✓ Updated CLAUDE.md with skill list"
else
echo " · CLAUDE.md already has gstack-game section"
fi
else
printf '%s\n' "$GSTACK_SECTION" > "$CLAUDE_MD"
echo " ✓ Created CLAUDE.md with skill list"
fi
echo ""
echo "Done! $SKILL_COUNT skills installed (prefix: $SKILL_PREFIX)."
echo ""
if [ "$SKILL_PREFIX" = "namespaced" ]; then
P="gg-"
else
P=""
fi
echo "Restart Claude Code to discover new skills, then try:"
echo " /${P}game-ideation — brainstorm a game concept"
echo " /${P}game-review — review a game design document"
echo " /${P}player-experience — simulate a player walkthrough"
echo " /${P}gameplay-implementation-review — game-aware PR code review"
Changelog
0.5.0 — 2026-04-15
Sharper reviews, richer player personas, community-aware shipping. Two upstream syncs bring behavioral UX testing, anti-slop detection, and multi-agent methodology to the game review pipeline.
Upstream sync: gstack (v0.15.7 → v0.17.0)
- 6 game UX behavioral tests in
/game-ux-reviewand/plan-design-review— HUD Clarity Test, First Frame Test, Tutorial Bloat Detection, Player Patience Meter, Mindless Choice Audit, Dead Input Test. Each produces a concrete PASS/PARTIAL/FAIL. - First-person narration mode in
/player-experience,/feel-pass, and/game-ux-review— reviews must name specific elements and describe moment-by-moment experience. "I tap the screen and... nothing" instead of "the UI lacks feedback." - Game Design Slop Blacklist in
/game-review— 10 common design anti-patterns (stat-inflation skill trees, meaningless daily logins, tooltip-bombardment tutorials, etc.) with challenge questions and severity classification. - Expanded anti-sycophancy — 12 new banned AI filler phrases, 5 forbidden postures ("That's an interesting approach" → must take a position), punchier writing rules.
- Confusion Protocol — all T2+ skills now stop and ask when facing high-stakes design ambiguity instead of guessing.
- Scope Drift Detection upgrade — T3 skills now detect both scope creep (analyzed more than requested) and missing requirements (didn't cover what was requested).
- Token ceiling warning — template engine warns when any generated SKILL.md exceeds 100KB (~25K tokens).
Upstream sync: hakoniwa methodology
- 4-dimensional player personas in
/player-experience— each persona now has profile, stance spectrum (-1.0 to +1.0), MBTI-informed behavior type, and influence weight (0.1 lurker to 0.9 KOL). New Persona 7: Genre Critic. Stance distribution guide for 5 common launch scenarios. - ReACT evidence standards for T3 skills — every HIGH/CRITICAL finding requires 2+ data points, 1+ direct quote, comparison context, and explicit confidence calibration (HIGH/MEDIUM/LOW).
- Design consistency evaluator in
/game-review— 3 dimensions: voice consistency (do systems match design pillars?), boundary behavior (does design hold under extreme conditions?), environmental storytelling density (how many channels communicate?). - Community Reception Forecast in
/pitch-review— stakeholder spectrum analysis, amplification timeline prediction, top 2 controversy risk scenarios with mitigation. - Launch Window Risk (Phase 8) in
/game-ship— audience reaction quick-scan, segment-by-segment risk assessment, timing check against competitor releases. - Event injection testing in
/playtest— 5 categories of deliberate disruptions (difficulty spikes, economy shocks, social disruptions, UX interruptions, information reveals) with observation framework. Optional Section 1B in playtest protocol.
Infrastructure
- Shell injection fix in
gstack-review-log(echo → printf) - Version sync: package.json now matches VERSION file
0.4.0 — 2026-03-25
Self-guiding workflow. Skills now tell you what to do next. New entry point skill, deep domain knowledge for 6 skills, and a complete internal maintenance pipeline.
New skills
/triage— Entry point for new users. Detects project state from artifacts and project files, classifies into 6 states (BLANK/IDEA/DOCUMENTED/REVIEWED/BUILDING/SHIPPING), routes to the right skill. Run this when you don't know where to start.
Next Step routing
Every skill now ends with a Next Step recommendation based on results:
- Score-conditional routing (e.g., Economy < 5 →
/balance-review) - Backtrack rules (core loop broken →
/game-ideation) - Forward pipeline through all three layers (Design → Production → Validation)
- 27 skills connected into a self-guiding workflow
Skill depth upgrades
Six skills upgraded from skeleton/thin to production quality with reference files:
| Skill | Before | After |
|---|---|---|
/game-codex | 123L, 40% | 331L + 4 refs (544L). 3-pass adversarial methodology, threat scoring formula, exploit taxonomy, design fallacies |
/asset-review | 128L, 35% | 329L + 5 refs (380L). Pipeline QA role, 7-dimension /14 scoring, per-asset benchmarks |
/game-visual-qa | 140L, 35% | 231L + 5 refs (341L). Animation standards, visual thresholds, deduction scoring, AI confidence disclaimers |
/playtest | 176L, 40% | 251L + 3 refs (238L). Observation metrics with confidence labels, interview question bank, analysis framework |
/game-eng-review | 589L, 0 refs | 462L + 5 refs (587L). Scoring, gotchas, performance budgets, networking patterns, engine framework |
/game-debug | 182L, 55% | Promoted from skeleton table — has full bug recipes |
Artifact visibility
Every skill now shows existing artifacts on startup (preamble compact summary). Users can see what prior skills produced without manual ls.
Internal maintenance pipeline (for contributors)
Six internal skills in .claude/skills/ (not published to users):
/issue-create → /issue-plan → /issue-action → PR → /pr-review-loop → merge/issue-create— Create GitHub issues from conversation (skill-gap, new-skill, bug)/issue-plan— Three-phase deep-dive (research → innovate → plan) with TodoWrite tracking/issue-action— Implement from approved plan, create PR/pr-review-loop— Automated PR review-fix cycle (bash state machine, max 3 iterations)/skill-review— 15-dimension quality rubric (moved from published to internal)/contribute-review— Domain knowledge integration (moved from published to internal)
0.3.0 — 2026-03-23
Bridge Layer + Production Workflow. The biggest structural change since launch. Five new skills fill the gap between design review and implementation. The back half now runs on game production work units (mechanic, feel, playability), not just software delivery units (diff, PR, build).
New skills
/prototype-slice-plan— Decide what to build first. Which slice, what hypothesis to test, what to fake, what failure looks like. 5-axis scoring with 6 slice types defined (mechanic prototype through vertical slice)./implementation-handoff— Translate design intent into a build package. Two-layer acceptance criteria (engineering-done + design-done). MUST/SHOULD/COULD priority tagging. Identifies the "soul" of each mechanic./feel-pass— Game feel doctor. Diagnose why a mechanic feels dead: responsiveness, impact, rhythm, clarity, payoff, dead time, overload. 7-dimension /14 scoring. Complete feedback chain model (anticipation → action → impact → resolution). Standardized feel vocabulary (snappy, crunchy, hollow, mushy)./build-playability-review— "Is this worth playing?" 6-dimension /12 scoring: loop closure, session viability, onboarding clarity, failure recovery, retention signal, peak moment. Validates prototype hypothesis from slice plan./gameplay-implementation-review— Evolved from/game-code-review. Adds Pass 0: Design Intent Survival — checks whether handoff acceptance criteria survived, soul is protected, scope boundaries respected. Keeps full Pass 1 (critical) + Pass 2 (informational) + adversarial.
New meta skills
/skill-review— Quality assessment for gstack-game skills. 15-dimension rubric, scan dashboard, refactor mode, auto fix loop (score → fix → re-score)./contribute-review— Convert GitHub Issues (domain expert contributions) into properly formatted PRs. Reads issue → contradiction check → format conversion → validation → PR creation.
Progressive disclosure
All 4 B-type skills split into references/ subdirectories:
/balance-review— 265L main + 8 reference files/game-review— 255L main + 8 reference files/player-experience— 254L main + 5 reference files/pitch-review— 283L main + 7 reference files
7 additional skills now have references/ with gotchas.md extracted (game-direction, game-eng-review, game-ideation, game-import, game-qa, game-ship, game-ux-review).
Strengthened skills (substitution test)
/game-retro— Game-specific metrics (playability/feel/GDD score deltas, design intent survival %, milestone types table)/game-debug— 6 game-specific bug recipes (physics tunneling, network desync, save corruption, frame spike, softlock, audio desync)/game-docs— Patch note patterns table (nerf/buff/economy/feel/remove), balance change communication protocol/game-codex— 10-category exploit taxonomy (speed, duplication, state corruption, progression skip, economy abuse, PvP cheat, save manipulation, determinism break, social exploit, content leak)
Contributor infrastructure
- CONTRIBUTING.md and CONTRIBUTING.zh-TW.md rewritten with 3-layer model (5min Issue / 30min references/ / advanced template)
- 4 GitHub Issue Templates (gotcha, benchmark, forcing question, scoring calibration)
- 4 contribution examples in both languages
New workflow
design → slice-plan → handoff → build → feel → playability → QA → shipPreviously: design → code review → QA → ship (missing the middle).
Documentation
docs/skill-writing-patterns.md— 7+4 patterns from real skill analysisdocs/skill-writing-doctrine-nox.md— 8 core principlesdocs/gstack-system-strengths.md— 7 system-level advantagesdocs/backend-gap-analysis-nox.md— Why back-half needs game production work unitsdocs/new-skill-specs-bridge-layer.md— Specs for bridge layer skillsdocs/skill-quality-rubric.md— 15-dimension assessment standard (in guardian/docs/tech/gstack/)
0.2.0 — 2026-03-22
20 skills fully scaffolded. First complete skill set covering the entire game development workflow.
Added
- 6 game-specific skills (game-review, balance-review, player-experience, pitch-review, asset-review, playtest)
- 13 skills migrated from gstack and rewritten for game context
- careful + guard safety skills (adapted from gstack)
docs/domain-judgment-gaps.md— expert review checklistdocs/source-quality-assessment.md— quality comparison of 3 source referencesREADME.mdwith full skill map and quality assessment
Quality levels
- 5 skills at 70-80% (B-type: full domain theory + scoring formulas)
- 8 skills at 55-65% (A-type: complete structure + game vocabulary)
- 7 skills at 35-40% (Skeleton: structure only, content needs domain experts)
0.1.0 — 2026-03-22
Added
- Initial project setup: template engine, preamble, bin utilities
- 4 skill skeletons (game-review, balance-review, player-experience, pitch-review)
bin/install.shumbrella installerscripts/gen-skill-docs.tstemplate engineskills/shared/preamble.mdshared fragment
gstack-game development
Commands
bun run build # generate all SKILL.md from templates
bun run gen:skill-docs # same as build
bun run gen:skill-docs:check # check for drift without writing (CI use)
bun test # run Tier 1 validation tests (free, <2s)Testing
bun test # run before every commit — free, <2sbun test runs template validation: frontmatter checks, preamble injection verification, placeholder expansion, drift detection, and tier validation. All 14 tests must pass before committing.
Project structure
gstack-game/
├── CLAUDE.md ← this file (dev handoff)
├── README.md ← user-facing docs (EN)
├── README.zh-TW.md ← user-facing docs (繁中)
├── ETHOS.md ← game dev philosophy
├── CHANGELOG.md ← version history (user-facing)
├── VERSION ← current version (0.5.0)
├── package.json ← build scripts
├── bin/ ← shared utilities
│ ├── install.sh ← umbrella installer
│ ├── gstack-config ← config read/write
│ ├── gstack-diff-scope ← game-aware diff classification (11 scopes)
│ ├── gstack-review-log ← review logging
│ ├── gstack-review-read ← review dashboard
│ ├── gstack-telemetry-log ← telemetry
│ └── gstack-slug ← repo slug detection
├── scripts/
│ └── gen-skill-docs.ts ← template engine (SKILL.md.tmpl → SKILL.md)
├── skills/ ← 29 published skills + shared/
│ ├── shared/
│ │ ├── preamble-core.md ← T1+: bash setup, artifacts, completion status
│ │ ├── preamble-standard.md ← T2+: voice, AskUser, vocabulary, routing
│ │ ├── preamble-expert.md ← T3: scope drift, review staleness
│ │ └── preamble-telemetry.md← all: end-of-session telemetry (always last)
│ ├── game-review/ ← GDD review (255L, 80%)
│ ├── balance-review/ ← economy & balance (286L, 70%)
│ ├── player-experience/ ← player walkthrough (273L, 75%)
│ ├── pitch-review/ ← pitch evaluation (302L, 70%)
│ ├── gameplay-implementation-review/ ← PR review (186L, 75%)
│ ├── spark-lens/ ← creative spark companion, no scoring
│ ├── game-ideation/ ← concept brainstorming (524L, 65%)
│ ├── game-direction/ ← direction review (490L, 55%)
│ ├── game-eng-review/ ← tech architecture (462L + 5 refs, 70%)
│ ├── game-qa/ ← QA testing (702L, 65%)
│ ├── game-ux-review/ ← UI/UX (565L, 60%)
│ ├── plan-design-review/ ← pre-impl design plan review (679L + 5 refs, 65%)
│ ├── game-ship/ ← release process (448L, 65%)
│ ├── game-import/ ← project import (514L)
│ ├── triage/ ← project navigator (320L)
│ ├── feel-pass/ ← game feel diagnosis (280L)
│ ├── build-playability-review/← playability assessment (211L)
│ ├── prototype-slice-plan/ ← prototype planning (235L)
│ ├── implementation-handoff/ ← implementation handoff (225L)
│ ├── game-debug/ ← debugging (182L, 55%)
│ ├── game-retro/ ← retrospective (166L, 40%)
│ ├── game-codex/ ← adversarial review (331L + 4 refs, 70%)
│ ├── game-docs/ ← release docs (137L, 40%)
│ ├── game-visual-qa/ ← visual QA (231L + 5 refs, 60%)
│ ├── asset-review/ ← asset pipeline (329L + 5 refs, 70%)
│ ├── playtest/ ← playtest protocol (251L + 3 refs, 65%)
│ ├── careful/ ← destructive cmd safety (62L)
│ ├── guard/ ← full safety mode (56L)
│ └── unfreeze/ ← unlock guard (32L)
├── .claude/skills/ ← 6 internal maintenance skills (not published)
│ ├── skill-review/ ← skill quality review (431L)
│ ├── contribute-review/ ← contribution review (334L)
│ ├── issue-create/ ← create GitHub issues from conversation
│ ├── issue-plan/ ← three-phase deep-dive planning (research → innovate → plan)
│ ├── issue-action/ ← implement from approved plan → PR
│ └── pr-review-loop/ ← automated PR review-fix cycle (max 3 iterations)
├── test/
│ └── gen-skill-docs.test.ts ← Tier 1 template validation (11 tests)
└── docs/
├── DEVELOPMENT.md ← full project overview, skill map, migration guide
├── domain-judgment-gaps.md ← expert calibration checklist
└── source-quality-assessment.md ← quality comparison of 3 sourcesSKILL.md workflow
SKILL.md files are generated from .tmpl templates. Never edit SKILL.md directly.
1. Edit the .tmpl file (e.g. skills/game-review/SKILL.md.tmpl) 2. Run bun run build 3. Commit both the .tmpl and generated .md files
Merge conflicts on SKILL.md files: Never resolve conflicts on generated SKILL.md files by accepting either side. Instead: (1) resolve conflicts on the .tmpl templates, (2) run bun run build to regenerate, (3) stage the regenerated files.
Writing SKILL templates
SKILL.md.tmpl files are prompt templates read by Claude, not bash scripts. Each bash code block runs in a separate shell — variables do not persist between blocks.
Rules:
- Use natural language for logic and state. Don't use shell variables to pass
state between code blocks. Tell Claude what to remember in prose.
- Keep bash blocks self-contained. Each code block should work independently.
- Express conditionals as English. Instead of nested
if/elif/elsein bash,
write numbered decision steps.
- Every section ends with
**STOP.** One issue per AskUserQuestion. - Include AUTO/ASK/ESCALATE classification for every section.
- Include anti-sycophancy forbidden phrases and calibrated acknowledgment examples.
- Include quantitative scoring where applicable (explicit formula, not AI intuition).
Placeholders
| Placeholder | Resolves to |
|---|---|
{{PREAMBLE}} | Tier-assembled preamble (core + standard + expert + telemetry based on preamble-tier) |
{{SKILL_NAME}} | Directory name of the skill (e.g. game-review) |
Preamble tiers
| Tier | Skills | Includes |
|---|---|---|
| T1 | careful, guard, unfreeze, game-docs | core + telemetry |
| T2 | 17 design/review skills | + voice, AskUser, vocabulary, routing |
| T3 | 7 expert/production skills | + scope drift, review staleness |
Template format
---
name: my-skill
description: "One-line description."
user_invocable: true
preamble-tier: 2
---
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->
<!-- Regenerate: bun scripts/gen-skill-docs.ts -->
{{PREAMBLE}}
# /my-skill: Title
[Content with sections, scoring, AUTO/ASK/ESCALATE, anti-sycophancy]
## Review Log
\```bash
[ -n "$_GG_BIN" ] && "$_GG_BIN/gstack-review-log" '{"skill":"{{SKILL_NAME}}","timestamp":"TIMESTAMP","status":"STATUS","commit":"COMMIT"}' 2>/dev/null || true
\```Adding a new skill
1. Create skills/my-skill/SKILL.md.tmpl with YAML frontmatter + {{PREAMBLE}} 2. Follow the 6 gstack methodology principles:
- Classify before judging (mode selection, category system)
- Explicit scoring formula (not AI intuition)
- Action triage (AUTO/ASK/ESCALATE with clear boundaries)
- Structured AskUserQuestion (4-part: re-ground, simplify, recommend, options)
- Multi-dimensional cross-check (multiple passes)
- Anti-sycophancy (forbidden phrases + forcing questions + push-back cadence)
3. Run bun run build 4. Run bun test to verify 5. Commit both .tmpl and .md files
Design principles
1. Interactive, not automated. One issue at a time via AskUserQuestion. User decides. 2. Opinionated with reasoning. Every recommendation includes WHY and an alternative. 3. Game-specific vocabulary. Core loop, retention hook, sink/faucet, difficulty curve. 4. Works with any engine. Reviews design docs and specs, not engine-specific code. 5. Complete workflow. Not a supplement to gstack — a full replacement for game projects.
Quality tiers
| Tier | Quality | What it has |
|---|---|---|
| B-type (70-80%) | Production | Full domain theory + scoring formulas + forcing questions |
| A-type (55-65%) | Usable | Complete structure + game vocabulary + AUTO/ASK/ESCALATE |
| Skeleton (35-40%) | Draft | Structure only, content needs domain expert calibration |
See docs/domain-judgment-gaps.md for what each skill needs from which expert.
Commit style
Bisect commits — each commit should be a single logical change. Examples:
- Template changes separate from generated file regeneration
- New skills separate from infrastructure changes
- Content enhancements separate from structural refactors
CHANGELOG style
CHANGELOG.md is for users. Write it like product release notes:
- Lead with what the user can now do
- Plain language, not implementation details
- No internal tracking or contributor-facing details
Reference sources
When enhancing skills with domain knowledge, consult:
- gstack original (
C:\ai_project\gstack) — methodology and engineering patterns - Claude-Code-Game-Studios (
C:\game-dev\Claude-Code-Game-Studios) — game design theory (MDA, SDT, economy frameworks) - guardian (
C:\ai_project\guardian) — PlayerSimulatorAgent prompt, Iceberg validation framework - gstack research docs (
C:\ai_project\guardian\docs\tech\gstack-*.md) — 3 methodology analysis docs
Contributing to gstack-game
繁體中文
gstack-game needs domain experts more than it needs programmers.
The engineering backbone is solid. What's missing is game industry experience — the benchmark numbers, common pitfalls, and review criteria that only come from shipping real games.
If you've shipped a game, designed an economy system, led a QA team, or directed art production — your knowledge is exactly what this project needs.
---
Three Ways to Contribute
⚡ 5 Minutes: Open an Issue (no clone needed)
For: You spotted a wrong number, know a mistake Claude makes, or have a question that should be asked during review.
Open a GitHub Issue using one of these templates:
- [Report Wrong Benchmark](../../issues/new?template=benchmark.yml) — a number is outdated or incorrect
- [Add Gotcha](../../issues/new?template=gotcha.yml) — Claude makes a specific mistake on this task
- [Add Forcing Question](../../issues/new?template=forcing-question.yml) — a critical question the review should ask but doesn't
- [Calibrate Scoring](../../issues/new?template=scoring.yml) — a scoring weight or threshold needs adjustment
Filled issues get converted directly into PRs. No git, no clone, no build required.
Examples: See Contribution Examples below.
---
🔧 30 Minutes: Edit references/ Files (clone repo)
For: You want to fix several things at once, add a full section, or deeply revise existing content.
Each skill's domain knowledge lives in skills/<name>/references/ — all pure markdown, no skill architecture knowledge needed.
git clone https://github.com/fagemx/gstack-game.git
cd gstack-gameYour Expertise → Which Files to Edit
| Your background | Files to edit |
|---|---|
| Economy / Systems Designer | skills/balance-review/references/ — gotchas.md, scoring.md, economy-model.md, progression.md |
| Game Designer | skills/game-review/references/ — core-loop.md, progression.md, motivation.md, gotchas.md |
| UX Researcher | skills/player-experience/references/ — personas.md, emotion-vocabulary.md, walkthrough-phases.md |
| Marketing / Publishing | skills/pitch-review/references/ — market-positioning.md, business-case.md, gotchas.md |
| Game Programmer | skills/gameplay-implementation-review/SKILL.md.tmpl, skills/game-eng-review/SKILL.md.tmpl |
| QA Lead | skills/game-qa/SKILL.md.tmpl |
After Editing
bun run build # Regenerate SKILL.md (not needed if you only changed references/)
bun test # Verify nothing brokeSubmit a PR:
- Title:
improve(balance-review): update F2P economy benchmarks - Body: explain why — cite your experience or data sources
- Tag your expertise:
[Economy Designer, 6 years, shipped 2 F2P mobile titles]
---
🏗️ Advanced: Write Skill Templates (requires architecture understanding)
For: Adding new skills or major skill restructuring.
Read these first:
CLAUDE.md— developer handbookdocs/DEVELOPMENT.md— full project overview, skill map, migration guide.claude/skills/skill-review/references/rubric.md— 15-dimension quality rubric.claude/skills/skill-review/references/refactor-patterns.md— refactoring method
Key rules:
- Edit
.tmplfiles, never.mddirectly - Skills over 300 lines need
references/split - All references read upfront before interaction (方案 1, zero interruption)
- Run
bun run build+bun testafter changes
---
Contribution Examples
Example 1: Add a Gotcha (5 minutes)
Scenario: You're an economy designer and noticed /balance-review flags inflation as a bug in idle games.
Open an Issue:
Skill: /balance-review
File: references/gotchas.md
Type: New Gotcha
>
What Claude does wrong:
Claude flags inflation rate > 1.2 as a red flag when analyzing idle game economies.
>
What's correct:
In idle games, inflation IS the design. Currency values growing 10-50% per hour is normal — the player expects "numbers go up." The correct check is whether inflation rate matches prestige reset frequency, not the absolute rate.
>
Evidence: Shipped 2 idle games (5M+ combined downloads), tuned live economy for 6 months.
Result: Maintainer adds this to skills/balance-review/references/gotchas.md.
---
Example 2: Fix a Benchmark (5 minutes)
Scenario: You work in publishing and the CPI numbers in /pitch-review are from 2024.
Open an Issue:
Skill: /pitch-review
File: references/scoring.md
Type: Fix Benchmark
>
Current value: LTV/CPI > 1.5 = viable
Should be: 2026 iOS casual game CPI is now $3-5 (post-ATT). LTV/CPI > 2.0 = viable, 1.5-2.0 = risky.
>
Source: Sensor Tower 2026 Q1 report + our UA data from 4 titles
---
Example 3: Add a Forcing Question (5 minutes)
Scenario: You're a game director who thinks /game-review misses a key question.
Open an Issue:
Skill: /game-review
File: references/core-loop.md
Type: New Forcing Question
>
Question: "Turn off all sound effects and just look at the screen. Is the core loop still fun? Now turn off the screen and just listen. Still fun? If neither works, your game feel is packaging, not design."
>
Why it matters: I've greenlit 20+ projects. The most common false positive is "demo looks cool but plays hollow." Stripping sensory packaging exposes whether the core loop has real juice.
>
Suggested placement: Section 1 Forcing Questions, as Q5
---
Example 4: Edit a references/ File (30 minutes)
Scenario: You're a UX researcher who knows the Casual Newcomer persona is wrong.
Edit: skills/player-experience/references/personas.md
### Persona 1: Casual Newcomer (FTUE Focus)
- **Context:** First mobile game session on commute.
- 3 minutes of attention before deciding if it's worth keeping.
+ 90 seconds of attention before deciding if it's worth keeping.
+ (Source: our playtest data shows 50% of casual players decide in 90 seconds,
+ not 3 minutes. 3 minutes is "already interested" players.)
- **Frustration tolerance:** 1-2 failures before quitting.
+ (Note: if the first failure has no feedback — why it happened, how to
+ improve — tolerance drops to 0. They leave without a second attempt.)Submit PR with playtest data source.
---
What Needs Expert Help Right Now
🔴 Critical (affects scoring accuracy)
| Skill | What's needed | Who can help |
|---|---|---|
/balance-review | Idle/incremental game economy model adaptation | Economy designer who shipped idle games |
/game-review | GDD weight calibration across game types | Designer who has reviewed 10+ GDDs |
/gameplay-implementation-review | Unity / Godot / Unreal hot-path pitfalls | Game programmer with profiling experience |
/pitch-review | 2026 LTV/CPI/UA benchmarks | Publisher with Sensor Tower or data.ai access |
🟡 Important (content exists but needs depth)
| Skill | What's needed | Who can help |
|---|---|---|
/player-experience | Playtest-validated persona behavioral parameters | UX researcher with observation data |
/game-ideation | More forcing questions (blind spots in current 6?) | Game director who has greenlit/killed projects |
/game-direction | IP strategy, localization, age rating cognitive patterns | Producer with 3+ shipped titles |
⚪ Recently upgraded (expert calibration welcome)
These skills were upgraded in v0.4.0 with initial reference files. The structure and benchmarks are in place but need validation from domain experts:
| Skill | Current | What needs calibration |
|---|---|---|
/asset-review | 329L + 5 refs, 70% | Per-asset texture/mesh budgets — are the numbers realistic for your engine/platform? |
/game-visual-qa | 231L + 5 refs, 60% | Animation blend times, frame count guidelines — match your production standards? |
/playtest | 251L + 3 refs, 65% | Observation thresholds marked LOW confidence — need playtest data to validate |
/game-codex | 331L + 4 refs, 70% | Exploit taxonomy — missing categories for your game type? |
/game-eng-review | 462L + 5 refs, 70% | Performance budgets — do the platform numbers match your profiling data? |
---
For Maintainers: Internal Skill Pipeline
gstack-game has 6 internal maintenance skills in .claude/skills/ that automate the issue-to-merge workflow. These are for repo maintainers, not game developers.
The pipeline
/issue-create → /issue-plan → /issue-action → PR → /pr-review-loop → mergeHow to use each skill
`/issue-create` — Create an issue from conversation context.
/issue-create skill-gap — a skill has wrong content or missing knowledge
/issue-create new-skill — propose a new skill
/issue-create bug — template bug or build issue
/issue-create — general (auto-detect type)`/issue-plan <number>` — Three-phase deep-dive on an issue.
- Research: Reads affected skill templates + references, documents facts only
- Innovate: Generates 2-3 approaches at different scales, evaluates trade-offs
- Plan: Concrete implementation plan (files to change, verification checklist)
- All three phases posted as comments to the issue, labeled
planned - Idempotent: re-run picks up where it left off if conversation breaks
`/issue-action <number>` — Implement from approved plan.
- Reads deep-dive artifacts from
.tmp/deep-dive/issue-{id}/ - Creates feature branch, implements step-by-step following the plan
- Runs
bun run build+bun testafter each change - Creates PR with structured body
`/pr-review-loop <number>` — Automated PR review-fix cycle.
- Bash state machine drives REVIEW → COMMENT → FIX → re-REVIEW loop
- Reviews against gstack-game standards (frontmatter, preamble, anti-sycophancy, STOP gates, 300L rule, build/test)
- Classifies issues as P0 (blocks merge) / P1 (should fix) / P2 (nice to have)
- Auto-fixes P0/P1, re-reviews until LGTM or max 3 iterations
- Posts findings as PR comments each round
`/skill-review <skill-name>` — Assess skill quality with 15-dimension rubric.
`/contribute-review <issue-number>` — Convert a domain expert's Issue into a formatted PR.
Example: end-to-end workflow
# 1. You notice /balance-review gives bad advice on idle games
/issue-create skill-gap
# → Creates issue #20 with details
# 2. Plan the fix
/issue-plan 20
# → Posts research, innovate, plan to issue. Adds "planned" label.
# 3. Implement
/issue-action 20
# → Creates feature branch, implements plan, opens PR #21
# 4. Review
/pr-review-loop 21
# → Reviews PR, fixes issues, posts LGTM when clean
# 5. Merge
gh pr merge 21 --squash --delete-branch---
Questions?
Open an issue. Tag it with the skill name and your area of expertise.
Not sure where your contribution fits? Open an issue saying "I want to contribute XX experience, not sure which skill" — we'll help you find the right place.
貢獻指南
English
gstack-game 需要的是領域專家,不只是程式設計師。
工程骨架已經穩固。缺的是遊戲產業經驗——那些只有真正做過遊戲的人才知道的 benchmark 數字、常見陷阱、和審查標準。
如果你做過遊戲、設計過經濟系統、帶過 QA 團隊、或做過美術管理——你的知識正是這個專案需要的。
---
三種貢獻方式
⚡ 5 分鐘:開 Issue(不需要 clone repo)
適合: 看到一個數字不對、想到一個 Claude 常犯的錯、有一個逼問問題要加。
直接在 GitHub 開 Issue,選對應的模板填寫:
- [回報錯誤的 Benchmark](../../issues/new?template=benchmark.yml) — 某個數字過時或不正確
- [新增 Gotcha](../../issues/new?template=gotcha.yml) — Claude 在某個任務上會犯的錯
- [新增逼問問題](../../issues/new?template=forcing-question.yml) — 審查時應該問但沒問的問題
- [校準評分](../../issues/new?template=scoring.yml) — 某個評分標準的權重或門檻需要調整
填完的 Issue 會被直接轉成 PR。你不需要懂 git、不需要 clone repo、不需要跑 build。
範例: 見 docs/contribution-examples/
---
🔧 30 分鐘:改 references/ 文件(需要 clone repo)
適合: 想要一次改好幾個地方、加一整段新內容、或深入修改某個 section。
每個 skill 的領域知識都在 skills/<name>/references/ 目錄——全部是純 markdown,不需要懂 skill 架構。
git clone https://github.com/fagemx/gstack-game.git
cd gstack-game你的專長對應哪些檔案
| 你的背景 | 改哪些檔案 |
|---|---|
| 數值策劃 | skills/balance-review/references/ — gotchas.md, scoring.md, economy-model.md, progression.md |
| 遊戲設計師 | skills/game-review/references/ — core-loop.md, progression.md, motivation.md, gotchas.md |
| UX 研究員 | skills/player-experience/references/ — personas.md, emotion-vocabulary.md, walkthrough-phases.md |
| 行銷 / 發行 | skills/pitch-review/references/ — market-positioning.md, business-case.md, gotchas.md |
| 遊戲程式 | skills/gameplay-implementation-review/SKILL.md.tmpl, skills/game-eng-review/SKILL.md.tmpl |
| QA 主管 | skills/game-qa/SKILL.md.tmpl |
改完後
bun run build # 重新生成 SKILL.md(如果你改了 references/,這步其實不需要)
bun test # 確認沒壞提 PR:
- 標題:
improve(balance-review): 更新 F2P 經濟 benchmark - 內文:解釋為什麼——引用你的經驗或數據來源
- 標注專業:
[數值策劃, 6 年, 出過 2 款 F2P 手遊]
---
🏗️ 進階:寫 Skill Template(需要理解架構)
適合: 想要新增 skill、或大幅重構現有 skill。
先讀這些文件理解架構:
CLAUDE.md— 開發者手冊docs/DEVELOPMENT.md— 完整專案概覽、skill map、migration guide.claude/skills/skill-review/references/rubric.md— 15 維度品質評分標準.claude/skills/skill-review/references/refactor-patterns.md— 重構方法
關鍵規則:
- 改
.tmpl檔案,不直接改.md - 超過 300 行的 skill 要拆
references/ - 所有 references 在互動開始前一次讀完(方案 1,零中斷)
- 改完跑
bun run build+bun test
---
貢獻範例
範例 1:加一條 Gotcha(5 分鐘)
場景: 你是數值策劃,發現 /balance-review 在分析放置類遊戲時會把通膨當成 bug。
開 Issue:
Skill: /balance-review
檔案: references/gotchas.md
類型: 新增 Gotcha
>
內容:
Claude 做放置類遊戲的經濟分析時,會把通膨率 > 1.2 標記為紅旗。但放置類遊戲的通膨是設計——幣值每小時成長 10-50% 是正常的,玩家的期待就是「數字一直變大」。正確的做法是看「通膨速度是否匹配 prestige 重置頻率」,不是看絕對通膨率。
>
根據什麼: 做過 2 款放置類遊戲(累計 500 萬下載),調過半年的 live 經濟。
>
建議加在哪裡: references/gotchas.md 的 Claude-Specific Gotchas 區塊第 8 點
結果: 維護者把這段加到 skills/balance-review/references/gotchas.md。
---
範例 2:修正 Benchmark 數字(5 分鐘)
場景: 你是發行,發現 /pitch-review 的 CPI benchmark 是 2024 年的數字。
開 Issue:
Skill: /pitch-review
檔案: references/scoring.md
類型: 修正 Benchmark
>
目前的值: LTV/CPI > 1.5 = viable
應該改成: 這個門檻太寬鬆。2026 年 iOS 的 casual game CPI 已經到 $3-5(ATT 之後持續漲),LTV/CPI > 2.0 才算 viable,1.5-2.0 是 risky。
>
數據來源: Sensor Tower 2026 Q1 report, 我們自己的 4 款遊戲 UA 數據
---
範例 3:加一個逼問問題(5 分鐘)
場景: 你是遊戲總監,覺得 /game-review 缺少一個關鍵問題。
開 Issue:
Skill: /game-review
檔案: references/core-loop.md
類型: 新增逼問問題
>
問題: 「把你的遊戲的音效全部關掉,只看畫面。核心循環還有趣嗎?再把畫面關掉只聽音效。還有趣嗎?如果兩個都不行,你的 game feel 靠的不是設計,是包裝。」
>
為什麼重要: 我 greenlight 過 20+ 個案子。最常見的假陽性就是「Demo 看起來很酷但玩起來空洞」——拆開感官包裝後核心循環其實沒有 juice。
>
建議加在哪裡: Section 1 的 Forcing Questions,作為 Q5
---
範例 4:改 references/ 文件(30 分鐘)
場景: 你是 UX 研究員,覺得 /player-experience 的 Casual Newcomer persona 不夠準確。
直接改檔案: skills/player-experience/references/personas.md
### Persona 1: Casual Newcomer (FTUE Focus)
- **Context:** First mobile game session on commute.
- 3 minutes of attention before deciding if it's worth keeping.
+ 90 seconds of attention before deciding if it's worth keeping.
+ (Source: 我們的 playtest 數據顯示 50% 的 casual 玩家在 90 秒內決定留或刪,不是 3 分鐘。
+ 3 分鐘是「已經感興趣的人」的數字。)
- **Frustration tolerance:** 1-2 failures before quitting.
+ (Note: 如果第一次失敗沒有任何回饋(為什麼失敗、怎麼改善),
+ tolerance 降為 0 — 直接離開,不會嘗試第二次。)提 PR,附上 playtest 數據來源。
---
現在最需要的貢獻
🔴 關鍵(會影響評分準確度)
| Skill | 需要什麼 | 需要誰 |
|---|---|---|
/balance-review | 放置類 / idle 遊戲的經濟模型適配 | 做過放置類遊戲的數值策劃 |
/game-review | GDD 權重在不同遊戲類型之間的校準 | 審過 10+ 份 GDD 的設計師 |
/gameplay-implementation-review | Unity / Godot / Unreal 各自的 hot path 陷阱 | 有 profiling 經驗的遊戲程式 |
/pitch-review | 2026 年的 LTV/CPI/UA benchmark | 有 Sensor Tower 或 data.ai 使用經驗的發行 |
🟡 重要(有內容但需要加深)
| Skill | 需要什麼 | 需要誰 |
|---|---|---|
/player-experience | Persona 行為參數的 playtest 驗證 | 有觀察數據的 UX 研究員 |
/game-ideation | 更多逼問問題(現有 6 個有沒有盲點) | greenlight 過/砍過專案的遊戲總監 |
/game-direction | IP 策略、本地化、年齡分級的認知模式 | 出過 3+ 款遊戲的製作人 |
⚪ 最近升級的(歡迎專家校準)
這些 skill 在 v0.4.0 加了初始 reference files。結構和 benchmark 已到位,但需要領域專家驗證:
| Skill | 目前 | 需要校準什麼 |
|---|---|---|
/asset-review | 329L + 5 refs, 70% | 每個 asset 的 texture/mesh budget——你的引擎/平台上這些數字合理嗎? |
/game-visual-qa | 231L + 5 refs, 60% | 動畫 blend time、frame count 標準——符合你的產線標準嗎? |
/playtest | 251L + 3 refs, 65% | 觀察門檻標為 LOW confidence——需要 playtest 數據驗證 |
/game-codex | 331L + 4 refs, 70% | Exploit taxonomy——你的遊戲類型有缺少的分類嗎? |
/game-eng-review | 462L + 5 refs, 70% | 效能 budget——平台數字跟你的 profiling 數據吻合嗎? |
---
給維護者:內部 Skill 維護 Pipeline
gstack-game 有 6 個內部維護 skill 在 .claude/skills/,自動化從 issue 到 merge 的工作流。這些是給 repo 維護者用的,不是給遊戲開發者。
Pipeline
/issue-create → /issue-plan → /issue-action → PR → /pr-review-loop → merge各 skill 怎麼用
`/issue-create` — 從對話建立 issue。
/issue-create skill-gap — skill 有錯誤內容或缺少知識
/issue-create new-skill — 提議新 skill
/issue-create bug — 模板 bug 或 build 問題
/issue-create — 通用(自動偵測類型)`/issue-plan <number>` — 對 issue 做三階段 deep-dive。
- Research: 讀受影響的 skill template + references,只記錄事實
- Innovate: 產生 2-3 個不同規模的方案,評估 trade-off
- Plan: 具體實作計畫(改哪些檔案、驗證清單)
- 三個階段都 post 到 issue comment,加上
plannedlabel - 冪等:對話斷掉重新跑會接續上次的進度
`/issue-action <number>` — 從 approved plan 實作。
- 讀取
.tmp/deep-dive/issue-{id}/的 deep-dive artifacts - 建 feature branch,照 plan 逐步實作
- 每步後跑
bun run build+bun test - 建 PR
`/pr-review-loop <number>` — 自動 PR review-fix 循環。
- Bash state machine 驅動 REVIEW → COMMENT → FIX → re-REVIEW 循環
- 用 gstack-game 標準審查(frontmatter、preamble、anti-sycophancy、STOP gates、300L rule、build/test)
- 分類:P0(擋 merge)/ P1(應該修)/ P2(nice to have)
- 自動修 P0/P1,重新 review 直到 LGTM 或最多 3 輪
- 每輪 post findings 到 PR comment
`/skill-review <skill-name>` — 用 15 維度 rubric 評估 skill 品質。
`/contribute-review <issue-number>` — 把領域專家的 Issue 轉成格式化 PR。
範例:完整工作流
# 1. 發現 /balance-review 在放置類遊戲給出錯誤建議
/issue-create skill-gap
# → 建立 issue #20
# 2. 規劃修正
/issue-plan 20
# → 三階段分析 post 到 issue,加 "planned" label
# 3. 實作
/issue-action 20
# → 建 feature branch,照 plan 實作,開 PR #21
# 4. Review
/pr-review-loop 21
# → 自動 review,修問題,clean 後 post LGTM
# 5. Merge
gh pr merge 21 --squash --delete-branch---
有問題?
開 Issue,標注 skill 名稱和你的專業領域。
不確定你的貢獻放哪裡?開 Issue 說「我想貢獻 XX 經驗,不確定放哪個 skill」——我們會幫你找到對的位置。
gstack-game Development Guide
What is this?
A complete game production workflow for Claude Code — 29 published skills from creative spark to shipped build, plus 6 internal maintenance skills. Standalone, no gstack dependency.
Skill Map (v0.5.0)
Three Layers
LAYER A — Design (spark + think + plan + review)
/spark-lens → /game-import → /game-ideation → /game-direction → /game-review → /game-eng-review
/balance-review /player-experience /game-ux-review /pitch-review
LAYER B — Bridge + Production (slice → build → verify)
/prototype-slice-plan → /implementation-handoff → build →
/gameplay-implementation-review → /feel-pass
LAYER C — Validation + Release (test → ship → reflect)
/build-playability-review → /game-qa → /game-ship → /game-docs → /game-retro
/playtest /game-visual-qa /asset-review /game-debug /game-codex
SAFETY
/careful /guard /unfreezeFull Workflow
spark → design → slice-plan → handoff → build → feel-pass → impl-review → playability → QA → shipAll 29 Published Skills
| Skill | Layer | Type | references/ |
|---|---|---|---|
/spark-lens | A | Creative spark | — |
/game-import | A | Scaffolding | — |
/game-ideation | A | Design | gotchas |
/game-direction | A | Review | gotchas |
/game-review | A | Review | 8 files |
/game-eng-review | A | Review | gotchas + scoring |
/balance-review | A | Review | 8 files |
/player-experience | A | Walkthrough | 5 files |
/game-ux-review | A | Review | gotchas + scoring |
/pitch-review | A | Review | 7 files |
/prototype-slice-plan | B | Bridge | 4 files |
/implementation-handoff | B | Bridge | 3 files |
/gameplay-implementation-review | B | Review | 4 files |
/feel-pass | B | Diagnosis | 4 files |
/build-playability-review | C | Review | 2 files |
/game-qa | C | QA + Fix Loop | gotchas + scoring |
/game-ship | C | Release | gotchas |
/game-debug | C | Investigation | — |
/game-retro | C | Retrospective | — |
/game-codex | C | Adversarial | — |
/game-docs | C | Documentation | — |
/game-visual-qa | C | QA | — |
/asset-review | C | Review | — |
/playtest | C | Protocol | — |
/careful | Safety | Guard | — |
/guard | Safety | Guard | — |
/unfreeze | Safety | Unlock | — |
Core Mechanisms
All scoring skills share three mechanisms:
1. Artifact Storage — Save results to ~/.gstack/projects/{slug}/. Downstream skills discover upstream artifacts automatically. 2. Regression Delta — Compare current score to prior run. WARN if score decreased. 3. Fix Loop (game-qa) — Baseline → triage → fix → atomic commit → re-test → classify → WTF check → final re-score.
Architecture
Template Engine
skills/game-review/SKILL.md.tmpl ← source (edit this)
↓
scripts/gen-skill-docs.ts ← compiler
↓
skills/game-review/SKILL.md ← generated (don't edit)Progressive Disclosure (方案 1)
Skills with references/ read ALL reference files upfront before any user interaction. Zero mid-flow interruption.
Preamble Injection
All skills share skills/shared/preamble.md — session tracking, telemetry, AskUserQuestion format, game design vocabulary.
Migration Guide: gstack → gstack-game
When adapting a gstack skill for game development:
1. Read the original from gstack 2. Keep the structure: Preamble → Sections → AUTO/ASK/ESCALATE → Scoring → Summary → Artifact → Log 3. Replace vocabulary: user→player, feature→mechanic, API→game system, deployment→platform submission, MRR→ARPDAU 4. Add game-specific criteria that gstack doesn't cover 5. Add references/ with gotchas, scoring rubric, domain benchmarks
Development
bun run build # generate all SKILL.md
bun run gen:skill-docs:check # check for drift (CI)
bun test # run validation testsAdding a skill
1. Create skills/my-skill/SKILL.md.tmpl with {{PREAMBLE}} 2. Add references/ if >300 lines 3. Run bun run build + bun test 4. Commit both .tmpl and .md
File structure
gstack-game/
├── CLAUDE.md ← AI agent handoff
├── README.md / README.zh-TW.md ← User-facing docs
├── CONTRIBUTING.md / .zh-TW.md ← Contributor guide (3-layer)
├── ETHOS.md ← Game dev philosophy
├── CHANGELOG.md ← Version history
├── VERSION ← 0.5.0
├── package.json ← Build scripts
├── .github/ISSUE_TEMPLATE/ ← 4 contribution templates
├── bin/ ← 7 utilities
├── scripts/gen-skill-docs.ts ← Template engine
├── skills/ ← 29 published skills + shared/
│ ├── shared/preamble.md
│ ├── game-review/
│ │ ├── SKILL.md.tmpl ← source
│ │ ├── SKILL.md ← generated
│ │ └── references/ ← 8 files
│ └── ... (28 more skills)
├── .claude/skills/ ← 6 internal maintenance skills
│ ├── skill-review/ ← skill quality assessment
│ ├── contribute-review/ ← domain knowledge integration
│ ├── issue-create/ ← create GitHub issues
│ ├── issue-plan/ ← three-phase deep-dive planning
│ └── issue-action/ ← implement from approved plan → PR
├── test/ ← Validation tests
└── docs/
├── DEVELOPMENT.md ← This file
└── domain-judgment-gaps.md ← Expert calibration checklistReference Sources
- gstack:
C:\ai_project\gstack— methodology patterns - guardian:
C:\ai_project\guardian— PlayerSimulatorAgent prompts, Iceberg framework - Process notes archive:
C:\ai_project\guardian\docs\tech\gstack\— analysis docs from development
gstack-game Builder Ethos
These principles shape how gstack-game thinks, recommends, and reviews. Adapted from gstack's ethos for game development context.
---
1. Boil the Lake
AI-assisted development makes the marginal cost of completeness near-zero. When the complete implementation costs minutes more than the shortcut — do the complete thing.
Lake vs. Ocean for games:
- Lake: Full edge case coverage for a save system. Complete input rebinding. All difficulty curve data points filled in. Every economy sink documented.
- Ocean: Rewriting the rendering engine. Porting to a new platform from scratch. Building a custom MMO networking layer.
Boil lakes. Flag oceans as out of scope.
Game-specific anti-patterns:
- "We'll balance it later." (Balance data is the cheapest lake to fill — a spreadsheet, not a rewrite.)
- "The tutorial can wait." (FTUE is the highest-leverage lake — it determines D1 retention.)
- "Let's skip controller support for now." (If it's a target platform, input is a lake, not optional polish.)
- "Tests are overkill for a game." (Gameplay regression tests are lakes. They catch silent balance breaks.)
Compression ratios for game dev:
| Task | Human | AI-assisted | Compression |
|---|---|---|---|
| GDD section drafting | 2 days | 30 min | ~50x |
| Balance spreadsheet setup | 1 day | 15 min | ~50x |
| Playtest protocol design | 4 hours | 15 min | ~15x |
| Economy model review | 1 day | 30 min | ~30x |
| Code review (gameplay) | 2 hours | 10 min | ~12x |
| Architecture design | 2 days | 4 hours | ~5x |
| Player psychology analysis | 1 day | 2 hours | ~4x |
| Art direction decisions | — | — | Not compressible |
The last row matters: art direction, game feel, and creative vision cannot be compressed. They require human taste. Everything else around them can be.
---
2. Search Before Building
Before building any game system, ask: has this been solved?
Three Layers of Knowledge
Layer 1: Tried and true. ECS for entity management. A* for pathfinding. Behavior trees for AI. Sink/faucet for economy. These are solved problems. Don't reinvent them — but question whether the standard solution fits YOUR game.
Layer 2: New and popular. The latest networking framework. That tutorial on procedural generation. The hot new UI toolkit. Search for these, but scrutinize. What works for a AAA team of 200 may not work for a solo dev. What works for an FPS may break your puzzle game.
Layer 3: First principles. "What if the core loop IS the tutorial?" (Celeste, Hades) "What if death is progression, not punishment?" (Soulslike, roguelike) "What if the player's constraint is the fun?" (Getting Over It, Untitled Goose Game)
The best game designs come from Layer 3 — questioning what everyone assumes is true about a genre. When you find one of these insights, name it, protect it, build around it.
The Eureka Moment in Games
The most valuable game design insight is NOT finding a mechanic to copy. It is: 1. Understanding what every game in the genre does and WHY 2. Questioning their assumptions with first-principles reasoning 3. Discovering a clear reason why the conventional approach is wrong FOR YOUR GAME
This is your Twist. This is your differentiation. This is what makes players say "it's the game where you..."
---
3. Player Time is Sacred
Every design decision must pass this filter: does this respect the player's time?
- Forced waiting with nothing to do = disrespect
- Unskippable cutscenes on replay = disrespect
- Unclear objectives that waste 10 minutes = disrespect
- Grind that exists to sell skip-buttons = disrespect
The player chose to spend their limited time with YOUR game. Honor that choice.
---
4. Fun First, Then Everything Else
A game can survive bad UI, bad performance, and bad marketing — if the core loop is genuinely fun.
A game CANNOT survive beautiful art, perfect performance, and aggressive marketing — if the core loop is boring.
Review priority: 1. Is the core loop fun? (If not, nothing else matters.) 2. Does the player understand what to do? (FTUE, UI clarity) 3. Does the game run well? (Performance, stability) 4. Does the game look/sound good? (Polish) 5. Can the game sustain itself? (Economy, content, retention)
Never optimize step 5 before step 1 is proven.
---
How They Work Together
Boil the Lake says: do the complete thing. Search Before Building says: know what exists before you build. Player Time is Sacred says: every feature must earn its place. Fun First says: prove the core loop before polishing anything else.
Together: Search first. Prove fun with a prototype. Then build the complete version of the proven thing — and make sure every minute the player spends is worth it.
MIT License
Copyright (c) 2026 fagemx
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "gstack-game",
"version": "0.5.0",
"description": "Game development workflow skills for Claude Code — from concept to shipping. Built on gstack patterns.",
"license": "MIT",
"type": "module",
"scripts": {
"build": "bun run gen:skill-docs",
"gen:skill-docs": "bun run scripts/gen-skill-docs.ts",
"gen:skill-docs:check": "bun run scripts/gen-skill-docs.ts --dry-run",
"test": "bun test",
"game-autoplan": "bun run scripts/game-autoplan.ts"
}
}
#!/usr/bin/env bun
/**
* Game Design Auto-Review Pipeline
*
* 3-stage pipeline: Game Design Interrogation → Auto-Fix → Independent Scoring
* with review-fix loop until score threshold is met.
*
* Usage:
* bun run scripts/game-autoplan.ts --input <dir> [options]
* bun run scripts/game-autoplan.ts --doc gdd --input <dir> # single document
* bun run scripts/game-autoplan.ts --dry-run --input <dir> # preview only
*/
import * as path from 'path';
import type { PipelineConfig } from './game-autoplan/types';
import { runPipeline } from './game-autoplan/runner';
import { generateDashboard } from './game-autoplan/dashboard';
function parseArgs(args: string[]): PipelineConfig {
const get = (flag: string, fallback: string): string => {
const idx = args.indexOf(flag);
return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : fallback;
};
const has = (flag: string): boolean => args.includes(flag);
const input_dir = get('--input', '');
if (!input_dir && !has('--help')) {
console.error('Error: --input <dir> is required');
process.exit(1);
}
const output_dir = get('--output', path.join(path.dirname(input_dir), 'review-results'));
return {
input_dir,
output_dir,
concurrency: Number(get('--concurrency', '3')),
max_loops: Number(get('--max-loops', '3')),
pass_threshold: Number(get('--threshold', '7')),
model: get('--model', 'claude-sonnet-4-6'),
budget: Number(get('--budget', '10')),
dry_run: has('--dry-run'),
resume: has('--resume'),
single_doc: get('--doc', '') || undefined,
};
}
function printHelp() {
console.log(`
Game Design Auto-Review Pipeline
3-stage pipeline: Interrogation → Auto-Fix → Scoring
Each game design document is reviewed through 6 forcing questions,
auto-fixed for weak areas, then independently scored on 6 dimensions.
Loop continues until score >= threshold or max rounds reached.
Usage:
bun run scripts/game-autoplan.ts --input <dir> [options]
Options:
--input <dir> Directory containing game design .md files (required)
--output <dir> Output directory (default: {input}/../review-results)
--concurrency <n> Parallel document processing (default: 3)
--max-loops <n> Max fix-score rounds per document (default: 3)
--threshold <n> Pass score threshold (default: 7)
--model <model> Anthropic model ID (default: claude-sonnet-4-6)
--budget <n> Max spend in USD (default: 10)
--dry-run Preview without API calls
--doc <id> Process single document (substring match on filename)
--resume Resume from existing artifacts (skip completed stages)
--help Show this help
Stages:
1. Interrogate — 6 game forcing questions (Role A: Producer, Role B: Designer)
Produces gap-analysis.json per document
2. Auto-Fix — Revise weak sections (severity < 7) with specific game design solutions
Produces revised-v{N}.md per round
3. Score — Independent 6-dimension scoring (does NOT see fixer's reasoning)
Dimensions: Core Loop, Retention, Player Specificity, Scope, Playtest, Differentiation
Produces score-v{N}.json per round
Output:
{output_dir}/
{doc-id}/
gap-analysis.json Stage 1 findings
revised-v1.md Stage 2 round 1
score-v1.json Stage 3 round 1
revised-v2.md Stage 2 round 2 (if needed)
score-v2.json Stage 3 round 2 (if needed)
final.md Best scoring revision
dashboard.md Summary report
dashboard.json Machine-readable results
cost-report.json Token usage and costs
`);
}
async function main() {
const args = process.argv.slice(2);
if (args.includes('--help') || args.length === 0) {
printHelp();
process.exit(0);
}
const config = parseArgs(args);
const start = Date.now();
const { results, costSummary } = await runPipeline(config);
if (!config.dry_run && results.length > 0) {
generateDashboard(results, costSummary, config.output_dir);
const elapsed = ((Date.now() - start) / 1000).toFixed(0);
const passed = results.filter(r => r.status === 'pass').length;
console.log(`\n========================================`);
console.log(` Complete: ${results.length} documents in ${elapsed}s`);
console.log(` Pass: ${passed}/${results.length} (threshold: ${config.pass_threshold})`);
console.log(` Cost: $${costSummary.total_cost_usd}`);
console.log(`========================================\n`);
}
}
main().catch(err => {
console.error('Fatal:', err.message);
process.exit(1);
});
0.5.0
Related skills
FAQ
Is Gstack Game safe to install?
skills.sh reports 1 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.