fix(bmgd): address PR review findings and enhance playtesting docs

## PR Review Fixes (F1-F20)

### Configuration & Naming
- F1: Changed user_skill_level to game_dev_experience in module.yaml
- F3: Renamed gametest/framework to gametest/test-framework

### Cleanup
- F2: Deleted 4 orphaned root-level template files
- F6: Removed duplicate code block in create-story/instructions.xml
- F9: Removed trailing empty line from qa-index.csv
- F20: Deleted orphaned docs/unnamed.jpg

### Installer Improvements
- F7: Simplified platform handler stubs (removed unused code)
- F8: Added return value checking for platform handlers
- F13: Added path traversal validation (isWithinProjectRoot)
- F18: Added type validation for config string values

### Agent Fixes
- F10: Added workflow-status and advanced-elicitation to game-solo-dev
- F12: Fixed "GOTO step 2a" → "GOTO step 2" references
- F14: Removed duplicate project-context.md from principles in 5 agents

### Workflow Updates
- F17: Added input_file_patterns to playtest-plan workflow

### Documentation
- F4-F5: Updated quick-start.md with 6 agents and fixed table
- Updated workflows-guide.md with test-framework reference

### Knowledge Base Updates (from earlier CodeRabbit comments)
- Updated unity-testing.md to Test Framework 1.6.0
- Fixed unreal-testing.md (MarkAsGarbage, UnrealEditor.exe)
- Added FVerifyPlayerMoved note to smoke-testing.md
- Fixed certification-testing.md table formatting

### Playtesting Documentation Enhancement
- Added "Playtesting by Game Type" section (7 genres)
- Added "Processing Feedback Effectively" section
- Expanded from ~138 to ~340 lines
This commit is contained in:
Scott Jennings 2025-12-16 22:06:52 -06:00
parent a9f24509ab
commit ab0f3d788c
32 changed files with 358 additions and 802 deletions

View File

@ -3,6 +3,18 @@ const path = require('node:path');
const chalk = require('chalk'); const chalk = require('chalk');
const platformCodes = require(path.join(__dirname, '../../../../tools/cli/lib/platform-codes')); const platformCodes = require(path.join(__dirname, '../../../../tools/cli/lib/platform-codes'));
/**
* Validate that a resolved path is within the project root (prevents path traversal)
* @param {string} resolvedPath - The fully resolved absolute path
* @param {string} projectRoot - The project root directory
* @returns {boolean} - True if path is within project root
*/
function isWithinProjectRoot(resolvedPath, projectRoot) {
const normalizedResolved = path.normalize(resolvedPath);
const normalizedRoot = path.normalize(projectRoot);
return normalizedResolved.startsWith(normalizedRoot + path.sep) || normalizedResolved === normalizedRoot;
}
/** /**
* BMGD Module Installer * BMGD Module Installer
* Standard module installer function that executes after IDE installations * Standard module installer function that executes after IDE installations
@ -21,10 +33,13 @@ async function install(options) {
logger.log(chalk.blue('🎮 Installing BMGD Module...')); logger.log(chalk.blue('🎮 Installing BMGD Module...'));
// Create planning artifacts directory (for GDDs, game briefs, architecture) // Create planning artifacts directory (for GDDs, game briefs, architecture)
if (config['planning_artifacts']) { if (config['planning_artifacts'] && typeof config['planning_artifacts'] === 'string') {
const planningConfig = config['planning_artifacts'].replace('{project-root}/', ''); // Strip project-root prefix variations
const planningConfig = config['planning_artifacts'].replace(/^\{project-root\}\/?/, '');
const planningPath = path.join(projectRoot, planningConfig); const planningPath = path.join(projectRoot, planningConfig);
if (!(await fs.pathExists(planningPath))) { if (!isWithinProjectRoot(planningPath, projectRoot)) {
logger.warn(chalk.yellow(`Warning: planning_artifacts path escapes project root, skipping: ${planningConfig}`));
} else if (!(await fs.pathExists(planningPath))) {
logger.log(chalk.yellow(`Creating game planning artifacts directory: ${planningConfig}`)); logger.log(chalk.yellow(`Creating game planning artifacts directory: ${planningConfig}`));
await fs.ensureDir(planningPath); await fs.ensureDir(planningPath);
} }
@ -33,20 +48,26 @@ async function install(options) {
// Create implementation artifacts directory (sprint status, stories, reviews) // Create implementation artifacts directory (sprint status, stories, reviews)
// Check both implementation_artifacts and sprint_artifacts for compatibility // Check both implementation_artifacts and sprint_artifacts for compatibility
const implConfig = config['implementation_artifacts'] || config['sprint_artifacts']; const implConfig = config['implementation_artifacts'] || config['sprint_artifacts'];
if (implConfig) { if (implConfig && typeof implConfig === 'string') {
const implConfigClean = implConfig.replace('{project-root}/', ''); // Strip project-root prefix variations
const implConfigClean = implConfig.replace(/^\{project-root\}\/?/, '');
const implPath = path.join(projectRoot, implConfigClean); const implPath = path.join(projectRoot, implConfigClean);
if (!(await fs.pathExists(implPath))) { if (!isWithinProjectRoot(implPath, projectRoot)) {
logger.warn(chalk.yellow(`Warning: implementation_artifacts path escapes project root, skipping: ${implConfigClean}`));
} else if (!(await fs.pathExists(implPath))) {
logger.log(chalk.yellow(`Creating implementation artifacts directory: ${implConfigClean}`)); logger.log(chalk.yellow(`Creating implementation artifacts directory: ${implConfigClean}`));
await fs.ensureDir(implPath); await fs.ensureDir(implPath);
} }
} }
// Create project knowledge directory // Create project knowledge directory
if (config['project_knowledge']) { if (config['project_knowledge'] && typeof config['project_knowledge'] === 'string') {
const knowledgeConfig = config['project_knowledge'].replace('{project-root}/', ''); // Strip project-root prefix variations
const knowledgeConfig = config['project_knowledge'].replace(/^\{project-root\}\/?/, '');
const knowledgePath = path.join(projectRoot, knowledgeConfig); const knowledgePath = path.join(projectRoot, knowledgeConfig);
if (!(await fs.pathExists(knowledgePath))) { if (!isWithinProjectRoot(knowledgePath, projectRoot)) {
logger.warn(chalk.yellow(`Warning: project_knowledge path escapes project root, skipping: ${knowledgeConfig}`));
} else if (!(await fs.pathExists(knowledgePath))) {
logger.log(chalk.yellow(`Creating project knowledge directory: ${knowledgeConfig}`)); logger.log(chalk.yellow(`Creating project knowledge directory: ${knowledgeConfig}`));
await fs.ensureDir(knowledgePath); await fs.ensureDir(knowledgePath);
} }
@ -117,12 +138,15 @@ async function configureForIDE(ide, projectRoot, config, logger) {
const platformHandler = require(platformSpecificPath); const platformHandler = require(platformSpecificPath);
if (typeof platformHandler.install === 'function') { if (typeof platformHandler.install === 'function') {
await platformHandler.install({ const success = await platformHandler.install({
projectRoot, projectRoot,
config, config,
logger, logger,
platformInfo: platformCodes.getPlatform(ide), platformInfo: platformCodes.getPlatform(ide),
}); });
if (!success) {
logger.warn(chalk.yellow(` Warning: BMGD platform handler for ${platformName} returned failure`));
}
} }
} else { } else {
// No platform-specific handler for this IDE // No platform-specific handler for this IDE

View File

@ -1,5 +1,3 @@
const chalk = require('chalk');
/** /**
* BMGD Platform-specific installer for Claude Code * BMGD Platform-specific installer for Claude Code
* *
@ -10,26 +8,16 @@ const chalk = require('chalk');
* @param {Object} options.platformInfo - Platform metadata from global config * @param {Object} options.platformInfo - Platform metadata from global config
* @returns {Promise<boolean>} - Success status * @returns {Promise<boolean>} - Success status
*/ */
async function install(options) { async function install() {
const { logger, platformInfo } = options; // TODO: Add Claude Code specific BMGD configurations here
// projectRoot and config available for future use // For example:
// - Game-specific slash commands
// - Agent party configurations for game dev team
// - Workflow integrations for Unity/Unreal/Godot
// - Game testing framework integrations
try { // Currently a stub - no platform-specific configuration needed yet
const platformName = platformInfo ? platformInfo.name : 'Claude Code'; return true;
logger.log(chalk.cyan(` BMGD-${platformName} Specifics installed`));
// Add Claude Code specific BMGD configurations here
// For example:
// - Game-specific slash commands
// - Agent party configurations for game dev team
// - Workflow integrations for Unity/Unreal/Godot
// - Game testing framework integrations
return true;
} catch (error) {
logger.error(chalk.red(`Error installing BMGD Claude Code specifics: ${error.message}`));
return false;
}
} }
module.exports = { install }; module.exports = { install };

View File

@ -1,5 +1,3 @@
const chalk = require('chalk');
/** /**
* BMGD Platform-specific installer for Windsurf * BMGD Platform-specific installer for Windsurf
* *
@ -10,21 +8,11 @@ const chalk = require('chalk');
* @param {Object} options.platformInfo - Platform metadata from global config * @param {Object} options.platformInfo - Platform metadata from global config
* @returns {Promise<boolean>} - Success status * @returns {Promise<boolean>} - Success status
*/ */
async function install(options) { async function install() {
const { logger, platformInfo } = options; // TODO: Add Windsurf specific BMGD configurations here
// projectRoot and config available for future use
try { // Currently a stub - no platform-specific configuration needed yet
const platformName = platformInfo ? platformInfo.name : 'Windsurf'; return true;
logger.log(chalk.cyan(` BMGD-${platformName} Specifics installed`));
// Add Windsurf specific BMGD configurations here
return true;
} catch (error) {
logger.error(chalk.red(`Error installing BMGD Windsurf specifics: ${error.message}`));
return false;
}
} }
module.exports = { install }; module.exports = { install };

View File

@ -18,7 +18,6 @@ agent:
- Hours of planning save weeks of refactoring hell - Hours of planning save weeks of refactoring hell
- Every system must handle the hot path at 60fps - Every system must handle the hot path at 60fps
- Avoid "Not Invented Here" syndrome, always check if work has been done before - Avoid "Not Invented Here" syndrome, always check if work has been done before
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`" - "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"

View File

@ -16,7 +16,6 @@ agent:
- Design what players want to FEEL, not what they say they want - Design what players want to FEEL, not what they say they want
- Prototype fast - one hour of playtesting beats ten hours of discussion - Prototype fast - one hour of playtesting beats ten hours of discussion
- Every mechanic must serve the core fantasy - Every mechanic must serve the core fantasy
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`" - "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"

View File

@ -17,7 +17,6 @@ agent:
- Write code designers can iterate without fear - Write code designers can iterate without fear
- Ship early, ship often, iterate on player feedback - Ship early, ship often, iterate on player feedback
- Red-green-refactor: tests first, implementation second - Red-green-refactor: tests first, implementation second
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`" - "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"

View File

@ -18,7 +18,6 @@ agent:
- Every shipped bug is a process failure, not a people failure - Every shipped bug is a process failure, not a people failure
- Flaky tests are worse than no tests - they erode trust - Flaky tests are worse than no tests - they erode trust
- Profile before optimize, test before ship - Profile before optimize, test before ship
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Consult {project-root}/_bmad/bmgd/gametest/qa-index.csv to select knowledge fragments under knowledge/ and load only the files needed for the current task" - "Consult {project-root}/_bmad/bmgd/gametest/qa-index.csv to select knowledge fragments under knowledge/ and load only the files needed for the current task"
@ -32,7 +31,7 @@ agent:
description: Get workflow status or check current project state description: Get workflow status or check current project state
- trigger: test-framework - trigger: test-framework
workflow: "{project-root}/_bmad/bmgd/workflows/gametest/framework/workflow.yaml" workflow: "{project-root}/_bmad/bmgd/workflows/gametest/test-framework/workflow.yaml"
description: Initialize game test framework (Unity/Unreal/Godot) description: Initialize game test framework (Unity/Unreal/Godot)
- trigger: test-design - trigger: test-design

View File

@ -17,12 +17,11 @@ agent:
- Clean separation between design and implementation - Clean separation between design and implementation
- Keep the team moving through each phase - Keep the team moving through each phase
- Stories are single source of truth for implementation - Stories are single source of truth for implementation
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`" - "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
- "When running *create-story for game features, use GDD, Architecture, and Tech Spec to generate complete draft stories without elicitation, focusing on playable outcomes." - "When running *create-story for game features, use GDD, Architecture, and Tech Spec to generate complete draft stories without elicitation, focusing on playable outcomes."
- "Always run as *yolo when creating stories - generate complete drafts from existing documentation" - "Generate complete story drafts from existing documentation without additional elicitation"
menu: menu:
- trigger: workflow-status - trigger: workflow-status

View File

@ -17,12 +17,15 @@ agent:
- A playable build beats a perfect design doc. Ship early, playtest often. - A playable build beats a perfect design doc. Ship early, playtest often.
- 60fps is non-negotiable. Performance is a feature. - 60fps is non-negotiable. Performance is a feature.
- The core loop must be fun before anything else matters. - The core loop must be fun before anything else matters.
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`
critical_actions: critical_actions:
- "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`" - "Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md`"
menu: menu:
- trigger: workflow-status
workflow: "{project-root}/_bmad/bmgd/workflows/workflow-status/workflow.yaml"
description: Get workflow status or check current project state
- trigger: quick-prototype - trigger: quick-prototype
workflow: "{project-root}/_bmad/bmgd/workflows/bmgd-quick-flow/quick-prototype/workflow.yaml" workflow: "{project-root}/_bmad/bmgd/workflows/bmgd-quick-flow/quick-prototype/workflow.yaml"
description: Rapid prototype to test if the mechanic is fun (Start here for new ideas) description: Rapid prototype to test if the mechanic is fun (Start here for new ideas)
@ -40,9 +43,14 @@ agent:
description: Review code quality (use fresh context for best results) description: Review code quality (use fresh context for best results)
- trigger: test-framework - trigger: test-framework
workflow: "{project-root}/_bmad/bmgd/workflows/gametest/framework/workflow.yaml" workflow: "{project-root}/_bmad/bmgd/workflows/gametest/test-framework/workflow.yaml"
description: Set up automated testing for your game engine description: Set up automated testing for your game engine
- trigger: party-mode - trigger: party-mode
exec: "{project-root}/_bmad/core/workflows/party-mode/workflow.md" exec: "{project-root}/_bmad/core/workflows/party-mode/workflow.md"
description: Bring in other experts when specialized backup is needed description: Bring in other experts when specialized backup is needed
- trigger: advanced-elicitation
exec: "{project-root}/_bmad/core/tasks/advanced-elicitation.xml"
description: Advanced elicitation techniques to challenge the LLM to get better results
web-only: true

View File

@ -76,11 +76,11 @@ BMGD follows four game development phases:
**Workflows:** **Workflows:**
- `sprint-planning` - Plan and track sprints - `sprint-planning` - Plan and track sprints
- `create-story-draft` - Create implementable stories - `sprint-status` - View progress and get recommendations
- `create-story` - Create implementable stories
- `dev-story` - Implement stories - `dev-story` - Implement stories
- `code-review` - Quality assurance - `code-review` - Quality assurance
- `story-done` - Complete stories - `retrospective` - Learn and improve after epics
- `epic-retrospective` - Learn and improve
**Output:** Working game code **Output:** Working game code
@ -154,7 +154,7 @@ Agent: [Sets up sprint tracking and epic management]
## Choosing Your Agent ## Choosing Your Agent
BMGD provides four specialized agents: BMGD provides six specialized agents:
| Agent | Icon | When to Use | | Agent | Icon | When to Use |
| --------------------- | ---- | ----------------------------------------- | | --------------------- | ---- | ----------------------------------------- |
@ -162,6 +162,8 @@ BMGD provides four specialized agents:
| **Game Architect** | 🏛️ | Architecture, technical decisions | | **Game Architect** | 🏛️ | Architecture, technical decisions |
| **Game Developer** | 🕹️ | Implementation, code reviews | | **Game Developer** | 🕹️ | Implementation, code reviews |
| **Game Scrum Master** | 🎯 | Sprint planning, story management | | **Game Scrum Master** | 🎯 | Sprint planning, story management |
| **Game QA** | 🧪 | Test framework, test design, automation |
| **Game Solo Dev** | 🎮 | Quick prototyping, indie development |
### Typical Flow ### Typical Flow
@ -191,13 +193,12 @@ BMGD provides four specialized agents:
### Phase 4: Production ### Phase 4: Production
- `sprint-planning` - Plan sprints - `sprint-planning` - Plan sprints
- `epic-tech-context` - Create Epic Tech Spec - `sprint-status` - View progress and recommendations
- `create-story` - Create story - `create-story` - Create story
- `story-context` - Generate story context
- `dev-story` - Implement story - `dev-story` - Implement story
- `code-review` - Review code - `code-review` - Review code
- `story-done` - Complete story - `retrospective` - Team retrospective
- `epic-retrospective` - Team retrospective - `correct-course` - Handle sprint changes
### Quick-Flow (Fast-Track) ### Quick-Flow (Fast-Track)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

View File

@ -439,20 +439,19 @@ Deep exploration techniques to challenge assumptions and surface hidden requirem
--- ---
## Workflow Inheritance ## Standalone BMGD Workflows
BMGD Phase 4 workflows use a `workflow-install` pattern to inherit from BMM: BMGD Phase 4 workflows are standalone implementations tailored for game development:
```yaml ```yaml
workflow: '{project-root}/_bmad/bmgd/workflows/4-production/dev-story/workflow.yaml' workflow: '{project-root}/_bmad/bmgd/workflows/4-production/dev-story/workflow.yaml'
workflow-install: '{project-root}/_bmad/bmgd/workflows/4-production/dev-story/workflow.yaml'
``` ```
This means: This means:
1. Core workflow logic comes from BMM 1. BMGD workflows are self-contained with game-specific logic
2. BMGD overrides provide game-specific templates and checklists 2. Game-focused templates, checklists, and instructions
3. Updates to BMM flow automatically to BMGD 3. No dependency on BMM workflow files
--- ---

View File

@ -131,11 +131,11 @@ REQUIREMENT: Save Data Portability (PS4→PS5)
### Xbox (XR) ### Xbox (XR)
| Requirement | Description | Priority | | Requirement | Description | Priority |
| ----------- | ----------------------------- | ----------- | --- | | ----------- | ----------------------------- | ----------- |
| XR-015 | Title timeout handling | Critical | | XR-015 | Title timeout handling | Critical |
| XR-045 | User sign-out handling | Critical | | XR-045 | User sign-out handling | Critical |
| XR-067 | Active user requirement | Critical | | XR-067 | Active user requirement | Critical |
| XR-074 | Quick Resume support | Series X | S | | XR-074 | Quick Resume support | Series X/S |
| XR-115 | Xbox Accessibility Guidelines | Recommended | | XR-115 | Xbox Accessibility Guidelines | Recommended |
### Nintendo Switch ### Nintendo Switch

View File

@ -88,6 +88,253 @@ Before each playtest session, define:
- Menu navigation patterns - Menu navigation patterns
- Control scheme preferences - Control scheme preferences
## Playtesting by Game Type
Different genres require different playtesting approaches and focus areas.
### Action/Platformer Games
**Focus Areas:**
- Control responsiveness and "game feel"
- Difficulty curve across levels
- Checkpoint placement and frustration points
- Visual clarity during fast-paced action
**Key Questions:**
- Does the character feel good to control?
- Are deaths feeling fair or cheap?
- Is the player learning organically or hitting walls?
### RPG/Story Games
**Focus Areas:**
- Narrative pacing and engagement
- Quest clarity and tracking
- Character/dialogue believability
- Progression and reward timing
**Key Questions:**
- Do players understand their current objective?
- Are choices feeling meaningful?
- Is the story holding attention or being skipped?
### Puzzle Games
**Focus Areas:**
- Solution discoverability
- "Aha moment" timing
- Hint system effectiveness
- Difficulty progression
**Key Questions:**
- Are players solving puzzles the intended way?
- How long before frustration sets in?
- Do solutions feel satisfying or arbitrary?
### Multiplayer/Competitive Games
**Focus Areas:**
- Balance across characters/builds/strategies
- Meta development and dominant strategies
- Social dynamics and toxicity vectors
- Matchmaking feel
**Key Questions:**
- Are there "must-pick" or "never-pick" options?
- Do losing players understand why they lost?
- Is the skill ceiling high enough for mastery?
### Survival/Sandbox Games
**Focus Areas:**
- Early game onboarding and survival
- Goal clarity vs. freedom balance
- Resource economy and pacing
- Emergent gameplay moments
**Key Questions:**
- Do players know what to do first?
- Is the loop engaging beyond the first hour?
- Are players creating their own goals?
### Mobile/Casual Games
**Focus Areas:**
- Session length appropriateness
- One-hand playability (if applicable)
- Interruption handling (calls, notifications)
- Monetization friction points
**Key Questions:**
- Can players play in 2-minute sessions?
- Is the core loop immediately understandable?
- Where do players churn?
### Horror Games
**Focus Areas:**
- Tension and release pacing
- Scare effectiveness and desensitization
- Safe space placement
- Audio/visual atmosphere
**Key Questions:**
- When do players feel safe vs. threatened?
- Are scares landing or becoming predictable?
- Is anxiety sustainable or exhausting?
## Processing Feedback Effectively
Raw feedback is noise. Processed feedback is signal.
### The Feedback Processing Pipeline
```
Raw Feedback → Categorize → Pattern Match → Root Cause → Prioritize → Action
```
### Step 1: Categorize Feedback
Sort all feedback into buckets:
| Category | Examples |
| ------------- | ---------------------------------- |
| **Bugs** | Crashes, glitches, broken features |
| **Usability** | Confusing UI, unclear objectives |
| **Balance** | Too hard, too easy, unfair |
| **Feel** | Controls, pacing, satisfaction |
| **Content** | Wants more of X, dislikes Y |
| **Polish** | Audio, visuals, juice |
### Step 2: Pattern Matching
Individual feedback is anecdotal. Patterns are data.
**Threshold Guidelines:**
- 1 person mentions it → Note it
- 3+ people mention it → Investigate
- 50%+ mention it → Priority issue
**Watch for:**
- Same complaint, different words
- Same area, different complaints (signals deeper issue)
- Contradictory feedback (may indicate preference split)
### Step 3: Root Cause Analysis
Players report symptoms, not diseases.
**Example:**
- **Symptom:** "The boss is too hard"
- **Possible Root Causes:**
- Boss mechanics unclear
- Player didn't learn required skill earlier
- Checkpoint too far from boss
- Health/damage tuning off
- Boss pattern has no safe windows
**Ask "Why?" five times** to get to root cause.
### Step 4: Separate Fact from Opinion
| Fact (Actionable) | Opinion (Context) |
| --------------------------------- | ----------------------- |
| "I died 12 times on level 3" | "Level 3 is too hard" |
| "I didn't use the shield ability" | "The shield is useless" |
| "I quit after 20 minutes" | "The game is boring" |
**Facts tell you WHAT happened. Opinions tell you how they FELT about it.**
Both matter, but facts drive solutions.
### Step 5: The Feedback Matrix
Plot issues on impact vs. effort:
```
High Impact
Quick │ Major
Wins │ Projects
─────────────┼─────────────
Fill │ Reconsider
Time │
Low Impact
Low Effort ──────── High Effort
```
### Step 6: Validate Before Acting
Before making changes based on feedback:
1. **Reproduce** - Can you see the issue yourself?
2. **Quantify** - How many players affected?
3. **Contextualize** - Is this your target audience?
4. **Test solutions** - Will the fix create new problems?
### Handling Contradictory Feedback
When Player A wants X and Player B wants the opposite:
1. **Check sample size** - Is it really split or just 2 loud voices?
2. **Segment audiences** - Are these different player types?
3. **Find the underlying need** - Both may want the same thing differently
4. **Consider options** - Difficulty settings, toggles, multiple paths
5. **Make a decision** - You can't please everyone; know your target
### Feedback Red Flags
**Dismiss or investigate carefully:**
- "Make it like [other game]" - They want a feeling, not a clone
- "Add multiplayer" - Feature creep disguised as feedback
- "I would have bought it if..." - Hypothetical customers aren't real
- Feedback from non-target audience - Know who you're building for
**Take seriously:**
- Confusion about core mechanics
- Consistent drop-off at same point
- "I wanted to like it but..."
- Silent quitting (no feedback, just gone)
### Documentation Best Practices
**For each playtest session, record:**
- Date and build version
- Tester demographics/experience
- Session length
- Key observations (timestamped if recorded)
- Quantitative survey results
- Top 3 issues identified
- Actions taken as result
**Maintain a living document** that tracks:
- Issue → First reported → Times reported → Status → Resolution
- This prevents re-discovering the same issues
## Common Playtesting Pitfalls ## Common Playtesting Pitfalls
### Leading Questions ### Leading Questions

View File

@ -125,6 +125,8 @@ TEST: Settings Persist
```csharp ```csharp
using System.Collections; using System.Collections;
using NUnit.Framework; using NUnit.Framework;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.TestTools; using UnityEngine.TestTools;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
@ -256,6 +258,7 @@ bool FPlayerMovementTest::RunTest(const FString& Parameters)
// Wait for physics // Wait for physics
ADD_LATENT_AUTOMATION_COMMAND(FWaitForSeconds(0.5f)); ADD_LATENT_AUTOMATION_COMMAND(FWaitForSeconds(0.5f));
// Note: FVerifyPlayerMoved is a custom latent command - implement to verify player position changed
ADD_LATENT_AUTOMATION_COMMAND(FVerifyPlayerMoved(StartPos)); ADD_LATENT_AUTOMATION_COMMAND(FVerifyPlayerMoved(StartPos));
return true; return true;

View File

@ -12,7 +12,7 @@ Unity provides a built-in Test Framework based on NUnit for writing and running
// manifest.json - usually pre-installed // manifest.json - usually pre-installed
{ {
"dependencies": { "dependencies": {
"com.unity.test-framework": "1.1.33" "com.unity.test-framework": "1.6.0"
} }
} }
``` ```

View File

@ -312,7 +312,7 @@ bool FMemoryLeakTest::RunTest(const FString& Parameters)
{ {
UObject* Obj = NewObject<UMyObject>(); UObject* Obj = NewObject<UMyObject>();
// ... use object // ... use object
Obj->MarkPendingKill(); Obj->MarkAsGarbage(); // UE5 API (was MarkPendingKill in UE4)
} }
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS); CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
@ -331,16 +331,18 @@ bool FMemoryLeakTest::RunTest(const FString& Parameters)
### Command Line ### Command Line
```bash ```bash
# Run all tests # Run all tests (UE5)
UE4Editor.exe MyGame -ExecCmds="Automation RunTests Now" -unattended -nopause UnrealEditor.exe MyGame -ExecCmds="Automation RunTests Now" -unattended -nopause
# Run specific test # Run specific test
UE4Editor.exe MyGame -ExecCmds="Automation RunTests MyGame.Combat" -unattended UnrealEditor.exe MyGame -ExecCmds="Automation RunTests MyGame.Combat" -unattended
# Run with report # Run with report
UE4Editor.exe MyGame \ UnrealEditor.exe MyGame \
-ExecCmds="Automation RunTests Now; Automation ReportResults" \ -ExecCmds="Automation RunTests Now; Automation ReportResults" \
-ReportOutputPath=TestResults.xml -ReportOutputPath=TestResults.xml
# Note: For UE4, use UE4Editor.exe instead of UnrealEditor.exe
``` ```
### GitHub Actions ### GitHub Actions
@ -351,7 +353,8 @@ test:
steps: steps:
- name: Run Tests - name: Run Tests
run: | run: |
& "$env:UE_ROOT/Engine/Binaries/Win64/UE4Editor-Cmd.exe" ` # UE5: UnrealEditor-Cmd.exe, UE4: UE4Editor-Cmd.exe
& "$env:UE_ROOT/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" `
"${{ github.workspace }}/MyGame.uproject" ` "${{ github.workspace }}/MyGame.uproject" `
-ExecCmds="Automation RunTests Now" ` -ExecCmds="Automation RunTests Now" `
-unattended -nopause -nullrhi -unattended -nopause -nullrhi

View File

@ -14,4 +14,4 @@ input-testing,Input Testing,"Controller, keyboard, and touch input validation","
localization-testing,Localization Testing,"Text, audio, and cultural validation for international releases","localization,i18n,text",knowledge/localization-testing.md localization-testing,Localization Testing,"Text, audio, and cultural validation for international releases","localization,i18n,text",knowledge/localization-testing.md
certification-testing,Platform Certification,"Console TRC/XR requirements and certification testing","certification,console,trc,xr",knowledge/certification-testing.md certification-testing,Platform Certification,"Console TRC/XR requirements and certification testing","certification,console,trc,xr",knowledge/certification-testing.md
smoke-testing,Smoke Testing,"Critical path validation for build verification","smoke-tests,bvt,ci",knowledge/smoke-testing.md smoke-testing,Smoke Testing,"Critical path validation for build verification","smoke-tests,bvt,ci",knowledge/smoke-testing.md
test-priorities,Test Priorities Matrix,"P0-P3 criteria, coverage targets, execution ordering for games","prioritization,risk,coverage",knowledge/test-priorities.md test-priorities,Test Priorities Matrix,"P0-P3 criteria, coverage targets, execution ordering for games","prioritization,risk,coverage",knowledge/test-priorities.md
1 id name description tags fragment_file
14 localization-testing Localization Testing Text, audio, and cultural validation for international releases localization,i18n,text knowledge/localization-testing.md
15 certification-testing Platform Certification Console TRC/XR requirements and certification testing certification,console,trc,xr knowledge/certification-testing.md
16 smoke-testing Smoke Testing Critical path validation for build verification smoke-tests,bvt,ci knowledge/smoke-testing.md
17 test-priorities Test Priorities Matrix P0-P3 criteria, coverage targets, execution ordering for games prioritization,risk,coverage knowledge/test-priorities.md

View File

@ -15,7 +15,7 @@ project_name:
default: "{directory_name}" default: "{directory_name}"
result: "{value}" result: "{value}"
user_skill_level: game_dev_experience:
prompt: prompt:
- "What is your game development experience level?" - "What is your game development experience level?"
- "This affects how agents explain concepts in chat." - "This affects how agents explain concepts in chat."

View File

@ -16,7 +16,7 @@ workflows:
- game-brief - game-brief
- gdd - gdd
- narrative - narrative
- create-architecture - game-architecture
- sprint-planning - sprint-planning
- sprint-status - sprint-status
- create-story - create-story

View File

@ -1,205 +0,0 @@
# Game Brief: {{game_name}}
**Date:** {{date}}
**Author:** {{user_name}}
**Status:** Draft for GDD Development
---
## Executive Summary
{{executive_summary}}
---
## Game Vision
### Core Concept
{{core_concept}}
### Elevator Pitch
{{elevator_pitch}}
### Vision Statement
{{vision_statement}}
---
## Target Market
### Primary Audience
{{primary_audience}}
### Secondary Audience
{{secondary_audience}}
### Market Context
{{market_context}}
---
## Game Fundamentals
### Core Gameplay Pillars
{{core_gameplay_pillars}}
### Primary Mechanics
{{primary_mechanics}}
### Player Experience Goals
{{player_experience_goals}}
---
## Scope and Constraints
### Target Platforms
{{target_platforms}}
### Development Timeline
{{development_timeline}}
### Budget Considerations
{{budget_considerations}}
### Team Resources
{{team_resources}}
### Technical Constraints
{{technical_constraints}}
---
## Reference Framework
### Inspiration Games
{{inspiration_games}}
### Competitive Analysis
{{competitive_analysis}}
### Key Differentiators
{{key_differentiators}}
---
## Content Framework
### World and Setting
{{world_setting}}
### Narrative Approach
{{narrative_approach}}
### Content Volume
{{content_volume}}
---
## Art and Audio Direction
### Visual Style
{{visual_style}}
### Audio Style
{{audio_style}}
### Production Approach
{{production_approach}}
---
## Risk Assessment
### Key Risks
{{key_risks}}
### Technical Challenges
{{technical_challenges}}
### Market Risks
{{market_risks}}
### Mitigation Strategies
{{mitigation_strategies}}
---
## Success Criteria
### MVP Definition
{{mvp_definition}}
### Success Metrics
{{success_metrics}}
### Launch Goals
{{launch_goals}}
---
## Next Steps
### Immediate Actions
{{immediate_actions}}
### Research Needs
{{research_needs}}
### Open Questions
{{open_questions}}
---
## Appendices
### A. Research Summary
{{research_summary}}
### B. Stakeholder Input
{{stakeholder_input}}
### C. References
{{references}}
---
_This Game Brief serves as the foundational input for Game Design Document (GDD) creation._
_Next Steps: Use the `workflow gdd` command to create detailed game design documentation._

View File

@ -1,153 +0,0 @@
# {{game_name}} - Game Design Document
**Author:** {{user_name}}
**Game Type:** {{game_type}}
**Target Platform(s):** {{platforms}}
---
## Executive Summary
### Core Concept
{{description}}
### Target Audience
{{target_audience}}
### Unique Selling Points (USPs)
{{unique_selling_points}}
---
## Goals and Context
### Project Goals
{{goals}}
### Background and Rationale
{{context}}
---
## Core Gameplay
### Game Pillars
{{game_pillars}}
### Core Gameplay Loop
{{gameplay_loop}}
### Win/Loss Conditions
{{win_loss_conditions}}
---
## Game Mechanics
### Primary Mechanics
{{primary_mechanics}}
### Controls and Input
{{controls}}
---
{{GAME_TYPE_SPECIFIC_SECTIONS}}
---
## Progression and Balance
### Player Progression
{{player_progression}}
### Difficulty Curve
{{difficulty_curve}}
### Economy and Resources
{{economy_resources}}
---
## Level Design Framework
### Level Types
{{level_types}}
### Level Progression
{{level_progression}}
---
## Art and Audio Direction
### Art Style
{{art_style}}
### Audio and Music
{{audio_music}}
---
## Technical Specifications
### Performance Requirements
{{performance_requirements}}
### Platform-Specific Details
{{platform_details}}
### Asset Requirements
{{asset_requirements}}
---
## Development Epics
### Epic Structure
{{epics}}
---
## Success Metrics
### Technical Metrics
{{technical_metrics}}
### Gameplay Metrics
{{gameplay_metrics}}
---
## Out of Scope
{{out_of_scope}}
---
## Assumptions and Dependencies
{{assumptions_and_dependencies}}

View File

@ -184,7 +184,7 @@ I'll use this to identify the right game type framework for our GDD."
I'll be listening for signals to help us identify the right game type framework." I'll be listening for signals to help us identify the right game type framework."
**AFTER this message, continue to Section 4.** **AFTER this message, SKIP to Section 4.**
--- ---

View File

@ -1,195 +0,0 @@
# {{game_name}} - Narrative Design Document
**Author:** {{user_name}}
**Game Type:** {{game_type}}
**Narrative Complexity:** {{narrative_complexity}}
---
## Executive Summary
### Narrative Premise
{{narrative_premise}}
### Core Themes
{{core_themes}}
### Tone and Atmosphere
{{tone_atmosphere}}
---
## Story Structure
### Story Type
{{story_type}}
**Structure used:** (3-act, hero's journey, kishōtenketsu, episodic, branching, etc.)
### Act Breakdown
{{act_breakdown}}
### Story Beats
{{story_beats}}
### Pacing and Flow
{{pacing_flow}}
---
## Characters
### Protagonist(s)
{{protagonists}}
### Antagonist(s)
{{antagonists}}
### Supporting Characters
{{supporting_characters}}
### Character Arcs
{{character_arcs}}
---
## World and Lore
### World Overview
{{world_overview}}
### History and Backstory
{{history_backstory}}
### Factions and Organizations
{{factions_organizations}}
### Locations
{{locations}}
### Cultural Elements
{{cultural_elements}}
---
## Dialogue Framework
### Dialogue Style
{{dialogue_style}}
### Key Conversations
{{key_conversations}}
### Branching Dialogue
{{branching_dialogue}}
### Voice and Characterization
{{voice_characterization}}
---
## Environmental Storytelling
### Visual Storytelling
{{visual_storytelling}}
### Audio Storytelling
{{audio_storytelling}}
### Found Documents
{{found_documents}}
### Environmental Clues
{{environmental_clues}}
---
## Narrative Delivery
### Cutscenes and Cinematics
{{cutscenes}}
### In-Game Storytelling
{{ingame_storytelling}}
### Optional Content
{{optional_content}}
### Multiple Endings
{{multiple_endings}}
---
## Integration with Gameplay
### Narrative-Gameplay Harmony
{{narrative_gameplay}}
### Story Gates
{{story_gates}}
### Player Agency
{{player_agency}}
---
## Production Notes
### Writing Scope
{{writing_scope}}
### Localization Considerations
{{localization}}
### Voice Acting
{{voice_acting}}
---
## Appendix
### Character Relationship Map
{{relationship_map}}
### Timeline
{{timeline}}
### References and Inspirations
{{references}}

View File

@ -56,7 +56,7 @@ Validate workflow readiness, check for existing narrative document, load GDD con
**Search for workflow status file:** **Search for workflow status file:**
Check if `{output_folder}/bmm-workflow-status.yaml` exists. Check if `{output_folder}/bmgd-workflow-status.yaml` exists.
**If status file found:** **If status file found:**

View File

@ -1,103 +0,0 @@
# Architecture
## Executive Summary
{{executive_summary}}
{{project_initialization_section}}
## Decision Summary
| Category | Decision | Version | Affects Epics | Rationale |
| -------- | -------- | ------- | ------------- | --------- |
{{decision_table_rows}}
## Project Structure
```
{{project_root}}/
{{source_tree}}
```
## Epic to Architecture Mapping
{{epic_mapping_table}}
## Technology Stack Details
### Core Technologies
{{core_stack_details}}
### Integration Points
{{integration_details}}
{{novel_pattern_designs_section}}
## Implementation Patterns
These patterns ensure consistent implementation across all AI agents:
{{implementation_patterns}}
## Consistency Rules
### Naming Conventions
{{naming_conventions}}
### Code Organization
{{code_organization_patterns}}
### Error Handling
{{error_handling_approach}}
### Logging Strategy
{{logging_approach}}
## Data Architecture
{{data_models_and_relationships}}
## API Contracts
{{api_specifications}}
## Security Architecture
{{security_approach}}
## Performance Considerations
{{performance_strategies}}
## Deployment Architecture
{{deployment_approach}}
## Development Environment
### Prerequisites
{{development_prerequisites}}
### Setup Commands
```bash
{{setup_commands}}
```
## Architecture Decision Records (ADRs)
{{key_architecture_decisions}}
---
_Generated by BMAD Decision Architecture Workflow v1.0_
_Date: {{date}}_
_For: {{user_name}}_

View File

@ -21,7 +21,7 @@
<check if="{{story_path}} is provided by user or user provided the epic and story number such as 2-4 or 1.6 or epic 1 story 5"> <check if="{{story_path}} is provided by user or user provided the epic and story number such as 2-4 or 1.6 or epic 1 story 5">
<action>Parse user-provided story path: extract epic_num, story_num, story_title from format like "1-2-user-auth"</action> <action>Parse user-provided story path: extract epic_num, story_num, story_title from format like "1-2-user-auth"</action>
<action>Set {{epic_num}}, {{story_num}}, {{story_key}} from user input</action> <action>Set {{epic_num}}, {{story_num}}, {{story_key}} from user input</action>
<action>GOTO step 2a</action> <action>GOTO step 2</action>
</check> </check>
<action>Check if {{sprint_status}} file exists for auto discover</action> <action>Check if {{sprint_status}} file exists for auto discover</action>
@ -47,12 +47,12 @@
<check if="user provides epic-story number"> <check if="user provides epic-story number">
<action>Parse user input: extract epic_num, story_num, story_title</action> <action>Parse user input: extract epic_num, story_num, story_title</action>
<action>Set {{epic_num}}, {{story_num}}, {{story_key}} from user input</action> <action>Set {{epic_num}}, {{story_num}}, {{story_key}} from user input</action>
<action>GOTO step 2a</action> <action>GOTO step 2</action>
</check> </check>
<check if="user provides story docs path"> <check if="user provides story docs path">
<action>Use user-provided path for story documents</action> <action>Use user-provided path for story documents</action>
<action>GOTO step 2a</action> <action>GOTO step 2</action>
</check> </check>
</check> </check>
@ -114,64 +114,8 @@
<output>📊 Epic {{epic_num}} status updated to in-progress</output> <output>📊 Epic {{epic_num}} status updated to in-progress</output>
</check> </check>
<action>GOTO step 2a</action> <action>GOTO step 2</action>
</check> </check>
<action>Load the FULL file: {{sprint_status}}</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely</action>
<action>Find the FIRST story (by reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "backlog"
</action>
<check if="no backlog story found">
<output>📋 No backlog stories found in sprint-status.yaml
All stories are either already created, in progress, or done.
**Options:**
1. Run sprint-planning to refresh story tracking
2. Load PM agent and run correct-course to add more stories
3. Check if current sprint is complete and run retrospective
</output>
<action>HALT</action>
</check>
<action>Extract from found story key (e.g., "1-2-user-authentication"):
- epic_num: first number before dash (e.g., "1")
- story_num: second number after first dash (e.g., "2")
- story_title: remainder after second dash (e.g., "user-authentication")
</action>
<action>Set {{story_id}} = "{{epic_num}}.{{story_num}}"</action>
<action>Store story_key for later use (e.g., "1-2-user-authentication")</action>
<!-- Mark epic as in-progress if this is first story -->
<action>Check if this is the first story in epic {{epic_num}} by looking for {{epic_num}}-1-* pattern</action>
<check if="this is first story in epic {{epic_num}}">
<action>Load {{sprint_status}} and check epic-{{epic_num}} status</action>
<action>If epic status is "backlog" → update to "in-progress"</action>
<action>If epic status is "contexted" (legacy status) → update to "in-progress" (backward compatibility)</action>
<action>If epic status is "in-progress" → no change needed</action>
<check if="epic status is 'done'">
<output>🚫 ERROR: Cannot create story in completed epic</output>
<output>Epic {{epic_num}} is marked as 'done'. All stories are complete.</output>
<output>If you need to add more work, either:</output>
<output>1. Manually change epic status back to 'in-progress' in sprint-status.yaml</output>
<output>2. Create a new epic for additional work</output>
<action>HALT - Cannot proceed</action>
</check>
<check if="epic status is not one of: backlog, contexted, in-progress, done">
<output>🚫 ERROR: Invalid epic status '{{epic_status}}'</output>
<output>Epic {{epic_num}} has invalid status. Expected: backlog, in-progress, or done</output>
<output>Please fix sprint-status.yaml manually or run sprint-planning to regenerate</output>
<action>HALT - Cannot proceed</action>
</check>
<output>📊 Epic {{epic_num}} status updated to in-progress</output>
</check>
<action>GOTO step 2a</action>
</step> </step>
<step n="2" goal="Load and analyze core artifacts"> <step n="2" goal="Load and analyze core artifacts">

View File

@ -23,6 +23,18 @@ variables:
session_duration: 60 # minutes session_duration: 60 # minutes
participant_count: 5 participant_count: 5
# Smart input file references - for understanding game mechanics to test
input_file_patterns:
gdd:
description: "Game Design Document for mechanics to validate"
whole: "{output_folder}/*gdd*.md"
sharded: "{output_folder}/*gdd*/*.md"
load_strategy: "FULL_LOAD"
game_brief:
description: "Game Brief for understanding core pillars"
whole: "{output_folder}/*brief*.md"
load_strategy: "FULL_LOAD"
# Output configuration # Output configuration
default_output_file: "{output_folder}/playtest-plan.md" default_output_file: "{output_folder}/playtest-plan.md"

View File

@ -12,7 +12,7 @@ document_output_language: "{config_source}:document_output_language"
date: system-generated date: system-generated
# Workflow components # Workflow components
installed_path: "{project-root}/_bmad/bmgd/workflows/gametest/framework" installed_path: "{project-root}/_bmad/bmgd/workflows/gametest/test-framework"
instructions: "{installed_path}/instructions.md" instructions: "{installed_path}/instructions.md"
validation: "{installed_path}/checklist.md" validation: "{installed_path}/checklist.md"

View File

@ -9,7 +9,7 @@ output_folder: "{config_source}:output_folder"
user_name: "{config_source}:user_name" user_name: "{config_source}:user_name"
communication_language: "{config_source}:communication_language" communication_language: "{config_source}:communication_language"
document_output_language: "{config_source}:document_output_language" document_output_language: "{config_source}:document_output_language"
user_skill_level: "{config_source}:game_dev_experience" game_dev_experience: "{config_source}:game_dev_experience"
date: system-generated date: system-generated
# Workflow components # Workflow components