gameforge-cli 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -44
- package/dist/agents/base/BaseAgent.d.ts +31 -0
- package/dist/agents/base/BaseAgent.d.ts.map +1 -1
- package/dist/agents/base/BaseAgent.js +57 -0
- package/dist/agents/base/BaseAgent.js.map +1 -1
- package/dist/agents/core/Architect.d.ts +21 -5
- package/dist/agents/core/Architect.d.ts.map +1 -1
- package/dist/agents/core/Architect.js +413 -150
- package/dist/agents/core/Architect.js.map +1 -1
- package/dist/agents/core/Chaos.d.ts +4 -0
- package/dist/agents/core/Chaos.d.ts.map +1 -1
- package/dist/agents/core/Chaos.js +46 -11
- package/dist/agents/core/Chaos.js.map +1 -1
- package/dist/agents/core/Consistency.d.ts +1 -0
- package/dist/agents/core/Consistency.d.ts.map +1 -1
- package/dist/agents/core/Consistency.js +86 -11
- package/dist/agents/core/Consistency.js.map +1 -1
- package/dist/agents/core/DocumentUpdater.d.ts +13 -0
- package/dist/agents/core/DocumentUpdater.d.ts.map +1 -0
- package/dist/agents/core/DocumentUpdater.js +165 -0
- package/dist/agents/core/DocumentUpdater.js.map +1 -0
- package/dist/agents/core/Modifier.d.ts +13 -0
- package/dist/agents/core/Modifier.d.ts.map +1 -0
- package/dist/agents/core/Modifier.js +141 -0
- package/dist/agents/core/Modifier.js.map +1 -0
- package/dist/agents/core/Remediation.d.ts +3 -1
- package/dist/agents/core/Remediation.d.ts.map +1 -1
- package/dist/agents/core/Remediation.js +63 -3
- package/dist/agents/core/Remediation.js.map +1 -1
- package/dist/agents/specialists/CreativeSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/CreativeSpecialist.js +162 -25
- package/dist/agents/specialists/CreativeSpecialist.js.map +1 -1
- package/dist/agents/specialists/EntitySpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/EntitySpecialist.js +79 -25
- package/dist/agents/specialists/EntitySpecialist.js.map +1 -1
- package/dist/agents/specialists/FeatureSpecialist.d.ts +4 -0
- package/dist/agents/specialists/FeatureSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/FeatureSpecialist.js +114 -39
- package/dist/agents/specialists/FeatureSpecialist.js.map +1 -1
- package/dist/agents/specialists/TechSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/TechSpecialist.js +169 -32
- package/dist/agents/specialists/TechSpecialist.js.map +1 -1
- package/dist/config/schema.d.ts +1319 -709
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +142 -52
- package/dist/config/schema.js.map +1 -1
- package/dist/config/templates.d.ts.map +1 -1
- package/dist/config/templates.js +6 -66
- package/dist/config/templates.js.map +1 -1
- package/dist/core/Orchestrator.d.ts +17 -3
- package/dist/core/Orchestrator.d.ts.map +1 -1
- package/dist/core/Orchestrator.js +46 -16
- package/dist/core/Orchestrator.js.map +1 -1
- package/dist/index.js +544 -226
- package/dist/index.js.map +1 -1
- package/dist/types/issueReview.d.ts +19 -0
- package/dist/types/issueReview.d.ts.map +1 -0
- package/dist/types/issueReview.js +3 -0
- package/dist/types/issueReview.js.map +1 -0
- package/dist/utils/costTracker.d.ts +28 -0
- package/dist/utils/costTracker.d.ts.map +1 -1
- package/dist/utils/costTracker.js +71 -1
- package/dist/utils/costTracker.js.map +1 -1
- package/dist/utils/disambiguationHelper.d.ts +54 -0
- package/dist/utils/disambiguationHelper.d.ts.map +1 -0
- package/dist/utils/disambiguationHelper.js +262 -0
- package/dist/utils/disambiguationHelper.js.map +1 -0
- package/dist/utils/fileManager.d.ts +7 -0
- package/dist/utils/fileManager.d.ts.map +1 -1
- package/dist/utils/fileManager.js +47 -0
- package/dist/utils/fileManager.js.map +1 -1
- package/dist/utils/issueReviewer.d.ts +10 -0
- package/dist/utils/issueReviewer.d.ts.map +1 -0
- package/dist/utils/issueReviewer.js +206 -0
- package/dist/utils/issueReviewer.js.map +1 -0
- package/dist/utils/issueSelector.d.ts +26 -0
- package/dist/utils/issueSelector.d.ts.map +1 -0
- package/dist/utils/issueSelector.js +132 -0
- package/dist/utils/issueSelector.js.map +1 -0
- package/dist/utils/pdfGenerator.d.ts +12 -0
- package/dist/utils/pdfGenerator.d.ts.map +1 -0
- package/dist/utils/pdfGenerator.js +341 -0
- package/dist/utils/pdfGenerator.js.map +1 -0
- package/package.json +20 -15
- package/dist/core/CheckpointManager.d.ts +0 -16
- package/dist/core/CheckpointManager.d.ts.map +0 -1
- package/dist/core/CheckpointManager.js +0 -52
- package/dist/core/CheckpointManager.js.map +0 -1
|
@@ -7,20 +7,67 @@ class EntitySpecialist extends BaseAgent_1.BaseAgent {
|
|
|
7
7
|
constructor(apiKey, costTracker, modelSelector) {
|
|
8
8
|
const config = {
|
|
9
9
|
systemPrompt: `You are an Entity Design Specialist.
|
|
10
|
-
Generate
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- Balance formulas
|
|
10
|
+
Generate concise game entity descriptions including:
|
|
11
|
+
- What the entity is and its role in the game
|
|
12
|
+
- Key characteristics and behaviors
|
|
13
|
+
- Brief narrative context if relevant
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Keep descriptions brief and design-focused. Avoid technical implementation details.`
|
|
17
16
|
};
|
|
18
17
|
super(apiKey, config, costTracker, modelSelector);
|
|
19
18
|
}
|
|
20
19
|
async execute(bible, onProgress) {
|
|
21
|
-
const sections = ['#
|
|
22
|
-
//
|
|
23
|
-
const
|
|
20
|
+
const sections = ['# Game Objects & Entities\n'];
|
|
21
|
+
// Per-category MAXIMUM thresholds - only flag if exceeded (not minimums)
|
|
22
|
+
const scope = bible.meta.estimatedScope;
|
|
23
|
+
const entityMaxThresholds = {
|
|
24
|
+
'Prototype': {
|
|
25
|
+
NPC: 5, Monster: 5, Item: 8, Ability: 8, Interactable: 5, Card: 20, Vehicle: 3, Building: 5
|
|
26
|
+
},
|
|
27
|
+
'Vertical Slice': {
|
|
28
|
+
NPC: 8, Monster: 8, Item: 15, Ability: 12, Interactable: 8, Card: 40, Vehicle: 5, Building: 8
|
|
29
|
+
},
|
|
30
|
+
'MVP': {
|
|
31
|
+
NPC: 15, Monster: 15, Item: 30, Ability: 20, Interactable: 15, Card: 60, Vehicle: 10, Building: 15
|
|
32
|
+
},
|
|
33
|
+
'Full Game': {
|
|
34
|
+
NPC: 40, Monster: 40, Item: 80, Ability: 50, Interactable: 40, Card: 150, Vehicle: 25, Building: 40
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const thresholds = entityMaxThresholds[scope] || entityMaxThresholds['MVP'];
|
|
38
|
+
// Count entities by category
|
|
39
|
+
const categoryCounts = {};
|
|
40
|
+
bible.gameObjects.forEach(entity => {
|
|
41
|
+
categoryCounts[entity.category] = (categoryCounts[entity.category] || 0) + 1;
|
|
42
|
+
});
|
|
43
|
+
// Check each category against its max threshold
|
|
44
|
+
const overages = [];
|
|
45
|
+
for (const [category, count] of Object.entries(categoryCounts)) {
|
|
46
|
+
const maxAllowed = thresholds[category];
|
|
47
|
+
if (maxAllowed && count > maxAllowed) {
|
|
48
|
+
overages.push(`${category}s (${count} > ${maxAllowed} max)`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (overages.length > 0) {
|
|
52
|
+
await this.askClarification(`The following entity categories exceed typical limits for a "${scope}" scope:\n\n${overages.map(o => `- ${o}`).join('\n')}`, bible, 'Entity Count');
|
|
53
|
+
}
|
|
54
|
+
// Check for economy features without currency items
|
|
55
|
+
const hasEconomyFeature = bible.features.some((f) => f.economy);
|
|
56
|
+
const hasCurrencyItems = bible.gameObjects.some((e) => e.category === 'Item' &&
|
|
57
|
+
(e.name.toLowerCase().includes('coin') ||
|
|
58
|
+
e.name.toLowerCase().includes('gold') ||
|
|
59
|
+
e.name.toLowerCase().includes('currency') ||
|
|
60
|
+
e.name.toLowerCase().includes('money')));
|
|
61
|
+
if (hasEconomyFeature && !hasCurrencyItems) {
|
|
62
|
+
await this.askClarification('Game has economy features but no currency items defined. Should we add coins, gold, or other tradeable items?', bible, 'Economy Items');
|
|
63
|
+
}
|
|
64
|
+
// Check for progression features without abilities/skills
|
|
65
|
+
const hasProgressionFeature = bible.features.some((f) => f.progression);
|
|
66
|
+
const hasAbilities = bible.gameObjects.some((e) => e.category === 'Ability');
|
|
67
|
+
if (hasProgressionFeature && !hasAbilities && bible.meta.genre.some((g) => g.toLowerCase().includes('rpg'))) {
|
|
68
|
+
await this.askClarification('RPG with progression but no abilities/skills defined. Should we add unlockable abilities?', bible, 'Progression Abilities');
|
|
69
|
+
}
|
|
70
|
+
const categories = ['NPC', 'Monster', 'Item', 'Interactable', 'Vehicle', 'Card', 'Building', 'Ability'];
|
|
24
71
|
for (const category of categories) {
|
|
25
72
|
const entities = bible.gameObjects.filter(e => e.category === category);
|
|
26
73
|
if (entities.length > 0) {
|
|
@@ -35,35 +82,42 @@ Be specific and create production-ready documentation.`
|
|
|
35
82
|
return sections.join('\n\n');
|
|
36
83
|
}
|
|
37
84
|
async generateEntityDoc(entity, bible, onProgress) {
|
|
38
|
-
const
|
|
85
|
+
const genre = bible.meta.genre.join(', ');
|
|
86
|
+
const prompt = `Generate a brief, design-focused description for this game entity:
|
|
39
87
|
|
|
40
88
|
Entity: ${JSON.stringify(entity, null, 2)}
|
|
41
|
-
Game
|
|
89
|
+
Game: ${bible.meta.title}
|
|
90
|
+
Genre: ${genre}
|
|
42
91
|
|
|
43
|
-
Create markdown
|
|
92
|
+
Create a concise markdown entry:
|
|
44
93
|
|
|
45
94
|
### ${entity.name}
|
|
46
|
-
**ID**: ${entity.id}
|
|
47
|
-
**Category**: ${entity.category}
|
|
48
95
|
|
|
49
|
-
|
|
96
|
+
Write 2-3 sentences describing what this entity is and its role in the game.
|
|
97
|
+
|
|
98
|
+
${entity.narrative?.backstory ? `**Background**: Brief narrative context based on: "${entity.narrative.backstory}"` : ''}
|
|
50
99
|
|
|
51
|
-
|
|
100
|
+
${entity.stats ? `**Key Characteristics**:
|
|
52
101
|
${Object.entries(entity.stats.attributes).map(([key, val]) => `- ${key}: ${val}`).join('\n')}
|
|
102
|
+
` : ''}
|
|
53
103
|
|
|
54
|
-
|
|
55
|
-
${entity.stats.behaviors.map(b => `- ${b}`).join('\n')}
|
|
104
|
+
${entity.stats?.behaviors && entity.stats.behaviors.length > 0 ? `**Behaviors**: ${entity.stats.behaviors.join(', ')}` : ''}
|
|
56
105
|
|
|
57
|
-
${entity.
|
|
58
|
-
|
|
59
|
-
${entity.
|
|
60
|
-
` : ''}
|
|
106
|
+
${entity.cardGame ? `**Card Info**: ${entity.cardGame.cardType || 'Card'}${entity.cardGame.effects && entity.cardGame.effects.length > 0 ? ` - ${entity.cardGame.effects.join(', ')}` : ''}` : ''}
|
|
107
|
+
|
|
108
|
+
${entity.combat ? `**Combat Role**: Describe briefly how this entity participates in combat.` : ''}
|
|
61
109
|
|
|
62
|
-
${entity.
|
|
110
|
+
${entity.social?.questGiver ? `**Quest Giver**: This character offers quests to the player.` : ''}
|
|
63
111
|
|
|
64
|
-
|
|
112
|
+
IMPORTANT - Keep it SHORT and DESIGN-FOCUSED:
|
|
113
|
+
- 1 short paragraph describing the entity
|
|
114
|
+
- Simple list of key characteristics (no RPG stat blocks unless this IS an RPG)
|
|
115
|
+
- NO balance formulas or math
|
|
116
|
+
- NO AI implementation details (behavior trees, detection radius, etc.)
|
|
117
|
+
- NO code references or feature IDs
|
|
118
|
+
- Focus on what this entity MEANS to the player experience`;
|
|
65
119
|
const result = await this.callLLMWithAutoRetry(prompt, modelSelector_1.TaskComplexity.SIMPLE, {
|
|
66
|
-
initialMaxTokens:
|
|
120
|
+
initialMaxTokens: 2000,
|
|
67
121
|
maxRetries: 2,
|
|
68
122
|
onProgress: (msg) => onProgress?.(`${entity.name}: ${msg}`)
|
|
69
123
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntitySpecialist.js","sourceRoot":"","sources":["../../../src/agents/specialists/EntitySpecialist.ts"],"names":[],"mappings":";;;AAAA,iDAA2D;AAC3D,6DAA2D;AAG3D,MAAa,gBAAiB,SAAQ,qBAAS;IAC7C,YAAY,MAAc,EAAE,WAAgB,EAAE,aAAkB;QAC9D,MAAM,MAAM,GAAgB;YAC1B,YAAY,EAAE
|
|
1
|
+
{"version":3,"file":"EntitySpecialist.js","sourceRoot":"","sources":["../../../src/agents/specialists/EntitySpecialist.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,10 @@ import { GameBible } from '../../config/schema';
|
|
|
3
3
|
export declare class FeatureSpecialist extends BaseAgent {
|
|
4
4
|
constructor(apiKey: string, costTracker: any, modelSelector: any);
|
|
5
5
|
execute(bible: GameBible, onProgress?: (message: string) => void): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Calculate dependency depth for each feature
|
|
8
|
+
*/
|
|
9
|
+
private calculateDependencyDepths;
|
|
6
10
|
private generateFeatureDoc;
|
|
7
11
|
}
|
|
8
12
|
//# sourceMappingURL=FeatureSpecialist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureSpecialist.d.ts","sourceRoot":"","sources":["../../../src/agents/specialists/FeatureSpecialist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAW,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"FeatureSpecialist.d.ts","sourceRoot":"","sources":["../../../src/agents/specialists/FeatureSpecialist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAW,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG;IAa1D,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAmFxF;;OAEG;IACH,OAAO,CAAC,yBAAyB;YA+BnB,kBAAkB;CA8DjC"}
|
|
@@ -7,18 +7,58 @@ class FeatureSpecialist extends BaseAgent_1.BaseAgent {
|
|
|
7
7
|
constructor(apiKey, costTracker, modelSelector) {
|
|
8
8
|
const config = {
|
|
9
9
|
systemPrompt: `You are a Feature Design Specialist.
|
|
10
|
-
Generate
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- Data structure pseudo-code
|
|
10
|
+
Generate clear feature descriptions including:
|
|
11
|
+
- What the feature does and why it exists
|
|
12
|
+
- How players interact with it (gameplay loop)
|
|
13
|
+
- UI/UX considerations
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Focus on player experience, not technical implementation.`
|
|
17
16
|
};
|
|
18
17
|
super(apiKey, config, costTracker, modelSelector);
|
|
19
18
|
}
|
|
20
19
|
async execute(bible, onProgress) {
|
|
21
|
-
const sections = ['#
|
|
20
|
+
const sections = ['# Systems & Features\n'];
|
|
21
|
+
// Check for very high complexity features that need clarification
|
|
22
|
+
const veryHighComplexityFeatures = bible.features.filter(f => f.technical.estimatedComplexity === 'Very High');
|
|
23
|
+
if (veryHighComplexityFeatures.length > 0) {
|
|
24
|
+
const feature = veryHighComplexityFeatures[0];
|
|
25
|
+
await this.askClarification(`The feature "${feature.name}" is marked as "Very High" complexity.`, bible, 'Feature Complexity');
|
|
26
|
+
}
|
|
27
|
+
// Check if all features have the same complexity
|
|
28
|
+
const complexities = bible.features.map((f) => f.technical.estimatedComplexity);
|
|
29
|
+
const uniqueComplexities = new Set(complexities);
|
|
30
|
+
if (uniqueComplexities.size === 1 && bible.features.length > 2) {
|
|
31
|
+
const complexity = complexities[0];
|
|
32
|
+
await this.askClarification(`All ${bible.features.length} features are marked "${complexity}" complexity. Are some more critical or complex than others?`, bible, 'Feature Complexity Variation');
|
|
33
|
+
}
|
|
34
|
+
// Check for vague feature intents
|
|
35
|
+
for (const feature of bible.features) {
|
|
36
|
+
const intent = feature.intent || '';
|
|
37
|
+
const hasVagueIntent = intent.length < 20 ||
|
|
38
|
+
intent.toLowerCase().includes('handles') ||
|
|
39
|
+
intent.toLowerCase().includes('manages') ||
|
|
40
|
+
intent.toLowerCase().includes('system for');
|
|
41
|
+
if (hasVagueIntent) {
|
|
42
|
+
await this.askClarification(`Feature "${feature.name}" has a vague intent. WHY does this exist? What does it add to the player experience?`, bible, 'Feature Intent');
|
|
43
|
+
break; // Only ask about the first vague intent
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Check for player-facing features without UI
|
|
47
|
+
for (const feature of bible.features) {
|
|
48
|
+
const hasGameplayLoop = feature.gameplayLoop && feature.gameplayLoop.length > 0;
|
|
49
|
+
const hasUI = feature.uiRequirements && feature.uiRequirements.length > 0;
|
|
50
|
+
if (hasGameplayLoop && !hasUI) {
|
|
51
|
+
await this.askClarification(`Feature "${feature.name}" has gameplay but no UI specified. What does the player see and interact with?`, bible, 'Feature UI Requirements');
|
|
52
|
+
break; // Only ask about the first missing UI
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check for deep dependency chains
|
|
56
|
+
const dependencyDepths = this.calculateDependencyDepths(bible.features);
|
|
57
|
+
const deepDependencies = dependencyDepths.filter(d => d.depth > 3);
|
|
58
|
+
if (deepDependencies.length > 0) {
|
|
59
|
+
const feature = deepDependencies[0];
|
|
60
|
+
await this.askClarification(`Feature "${feature.name}" has a complex dependency chain (${feature.depth} levels deep). Can we simplify the feature unlock order?`, bible, 'Feature Dependencies');
|
|
61
|
+
}
|
|
22
62
|
for (const feature of bible.features) {
|
|
23
63
|
onProgress?.(`Processing feature ${feature.name}...`);
|
|
24
64
|
const markdown = await this.generateFeatureDoc(feature, bible, onProgress);
|
|
@@ -26,53 +66,88 @@ Be specific and technical. Use industry-standard notation.`
|
|
|
26
66
|
}
|
|
27
67
|
return sections.join('\n\n---\n\n');
|
|
28
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Calculate dependency depth for each feature
|
|
71
|
+
*/
|
|
72
|
+
calculateDependencyDepths(features) {
|
|
73
|
+
const featureMap = new Map(features.map(f => [f.id, f]));
|
|
74
|
+
const depths = [];
|
|
75
|
+
const getDepth = (featureId, visited = new Set()) => {
|
|
76
|
+
if (visited.has(featureId)) {
|
|
77
|
+
return 0; // Circular dependency, return 0
|
|
78
|
+
}
|
|
79
|
+
const feature = featureMap.get(featureId);
|
|
80
|
+
if (!feature || !feature.dependencies || feature.dependencies.length === 0) {
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
visited.add(featureId);
|
|
84
|
+
const maxDepth = Math.max(...feature.dependencies.map(depId => getDepth(depId, new Set(visited))));
|
|
85
|
+
return maxDepth + 1;
|
|
86
|
+
};
|
|
87
|
+
for (const feature of features) {
|
|
88
|
+
depths.push({
|
|
89
|
+
name: feature.name,
|
|
90
|
+
depth: getDepth(feature.id)
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return depths;
|
|
94
|
+
}
|
|
29
95
|
async generateFeatureDoc(feature, bible, onProgress) {
|
|
30
|
-
const prompt = `Generate
|
|
96
|
+
const prompt = `Generate a clear, player-focused description for this game feature:
|
|
31
97
|
|
|
32
98
|
Feature: ${JSON.stringify(feature, null, 2)}
|
|
33
|
-
Game
|
|
99
|
+
Game: ${bible.meta.title} (${bible.meta.genre.join(', ')})
|
|
34
100
|
|
|
35
|
-
Create markdown documentation
|
|
101
|
+
Create markdown documentation:
|
|
36
102
|
|
|
37
103
|
## ${feature.name}
|
|
38
|
-
**Epic**: ${feature.agile.epic}
|
|
39
104
|
|
|
40
|
-
###
|
|
41
|
-
|
|
105
|
+
### Purpose
|
|
106
|
+
Explain in 2-3 sentences why this feature exists and what it adds to the player experience.
|
|
107
|
+
Base this on: "${feature.intent}"
|
|
42
108
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
${feature.gameplayLoop.map((step, i) => ` participant Step${i} as ${step}`).join('\n')}
|
|
47
|
-
\`\`\`
|
|
109
|
+
${feature.gameplayLoop && feature.gameplayLoop.length > 0 ? `### How It Works
|
|
110
|
+
Describe the gameplay loop in plain language as a numbered list:
|
|
111
|
+
${feature.gameplayLoop.map((step, i) => `${i + 1}. ${step}`).join('\n')}
|
|
48
112
|
|
|
49
|
-
|
|
50
|
-
|
|
113
|
+
Expand each step with 1-2 sentences explaining the player's actions and the game's response.
|
|
114
|
+
` : ''}
|
|
51
115
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
\`\`\`
|
|
57
|
-
|
|
58
|
-
**Math Formulas**:
|
|
59
|
-
${feature.technical.mathFormulas?.map(f => `
|
|
60
|
-
- Formula: \\\`${f.expression}\\\`
|
|
61
|
-
- Variables: ${Object.entries(f.variables).map(([k, v]) => `${k} (${v.type})`).join(', ')}
|
|
62
|
-
`).join('\n') || 'None'}
|
|
116
|
+
${feature.uiRequirements && feature.uiRequirements.length > 0 ? `### User Interface
|
|
117
|
+
What UI elements does this feature need?
|
|
118
|
+
${feature.uiRequirements.map(ui => `- ${ui}`).join('\n')}
|
|
119
|
+
` : ''}
|
|
63
120
|
|
|
64
|
-
|
|
121
|
+
${feature.multiplayer ? `### Multiplayer
|
|
122
|
+
- Supports ${feature.multiplayer.playerCount} players
|
|
123
|
+
${feature.multiplayer.networkModel ? `- Uses ${feature.multiplayer.networkModel} architecture` : ''}
|
|
124
|
+
Briefly describe how multiple players interact with this feature.
|
|
125
|
+
` : ''}
|
|
65
126
|
|
|
66
|
-
|
|
127
|
+
${feature.economy ? `### Economy Impact
|
|
128
|
+
${feature.economy.currencies ? `Currencies involved: ${feature.economy.currencies.join(', ')}` : ''}
|
|
129
|
+
Describe how this feature affects the game's economy.
|
|
130
|
+
` : ''}
|
|
67
131
|
|
|
68
|
-
|
|
69
|
-
|
|
132
|
+
${feature.progression ? `### Progression
|
|
133
|
+
Describe how players unlock or advance through this feature.
|
|
134
|
+
${feature.progression.unlockConditions ? `Unlock requirements: ${feature.progression.unlockConditions.join(', ')}` : ''}
|
|
135
|
+
` : ''}
|
|
70
136
|
|
|
71
|
-
${feature.
|
|
137
|
+
${feature.narrative ? `### Story Integration
|
|
138
|
+
How does this feature connect to the game's narrative?
|
|
139
|
+
${feature.narrative.storyBeats && feature.narrative.storyBeats.length > 0 ? `Key story moments: ${feature.narrative.storyBeats.join(', ')}` : ''}
|
|
140
|
+
` : ''}
|
|
72
141
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
142
|
+
IMPORTANT - This is a DESIGN document, not an engineering spec:
|
|
143
|
+
- NO code or pseudo-code
|
|
144
|
+
- NO data structures
|
|
145
|
+
- NO math formulas with variable types
|
|
146
|
+
- NO file paths or complexity ratings
|
|
147
|
+
- Focus on WHAT the player experiences, not HOW it's implemented
|
|
148
|
+
- Keep it concise (half a page per feature max)`;
|
|
149
|
+
const result = await this.callLLMWithAutoRetry(prompt, modelSelector_1.TaskComplexity.SIMPLE, {
|
|
150
|
+
initialMaxTokens: 4000,
|
|
76
151
|
maxRetries: 2,
|
|
77
152
|
onProgress: (msg) => onProgress?.(`${feature.name}: ${msg}`)
|
|
78
153
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureSpecialist.js","sourceRoot":"","sources":["../../../src/agents/specialists/FeatureSpecialist.ts"],"names":[],"mappings":";;;AAAA,iDAA2D;AAC3D,6DAA2D;AAG3D,MAAa,iBAAkB,SAAQ,qBAAS;IAC9C,YAAY,MAAc,EAAE,WAAgB,EAAE,aAAkB;QAC9D,MAAM,MAAM,GAAgB;YAC1B,YAAY,EAAE
|
|
1
|
+
{"version":3,"file":"FeatureSpecialist.js","sourceRoot":"","sources":["../../../src/agents/specialists/FeatureSpecialist.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechSpecialist.d.ts","sourceRoot":"","sources":["../../../src/agents/specialists/TechSpecialist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"TechSpecialist.d.ts","sourceRoot":"","sources":["../../../src/agents/specialists/TechSpecialist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG;IAc1D,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CA+NzF"}
|
|
@@ -6,52 +6,189 @@ const modelSelector_1 = require("../../utils/modelSelector");
|
|
|
6
6
|
class TechSpecialist extends BaseAgent_1.BaseAgent {
|
|
7
7
|
constructor(apiKey, costTracker, modelSelector) {
|
|
8
8
|
const config = {
|
|
9
|
-
systemPrompt: `You are a Technical
|
|
10
|
-
Generate
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Be precise and actionable.`
|
|
9
|
+
systemPrompt: `You are a Technical Overview Specialist.
|
|
10
|
+
Generate a high-level technical summary for stakeholders including:
|
|
11
|
+
- Recommended game engine and why
|
|
12
|
+
- Target platforms
|
|
13
|
+
- Multiplayer approach (if applicable)
|
|
14
|
+
- Accessibility features
|
|
15
|
+
|
|
16
|
+
Keep it brief and non-technical. This is a design document, not an engineering spec.`
|
|
18
17
|
};
|
|
19
18
|
super(apiKey, config, costTracker, modelSelector);
|
|
20
19
|
}
|
|
21
20
|
async execute(bible, onProgress) {
|
|
22
|
-
|
|
21
|
+
if (!bible.technical) {
|
|
22
|
+
return '# Technical Overview\n\n*No technical specifications provided for this design document.*';
|
|
23
|
+
}
|
|
24
|
+
// Check if targeting too many platforms for the scope
|
|
25
|
+
const platformCount = bible.technical.buildTargets.length;
|
|
26
|
+
const scope = bible.meta.estimatedScope;
|
|
27
|
+
if (platformCount > 2 && (scope === 'Prototype' || scope === 'Vertical Slice')) {
|
|
28
|
+
const result = await this.askClarification(`You're targeting ${platformCount} platforms (${bible.technical.buildTargets.join(', ')}) for a "${scope}" scope.`, bible, 'Platform Scope');
|
|
29
|
+
const decision = (result.answer || '').toLowerCase();
|
|
30
|
+
const currentTargets = bible.technical.buildTargets;
|
|
31
|
+
if (decision.includes('focus on primary') || decision.includes('primary platform')) {
|
|
32
|
+
if (currentTargets.length > 0) {
|
|
33
|
+
bible.technical.buildTargets = [currentTargets[0]];
|
|
34
|
+
onProgress?.(`Technical scope updated: focusing on primary platform "${currentTargets[0]}".`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (decision.includes('start with fewer') || decision.includes('fewer platform')) {
|
|
38
|
+
if (currentTargets.length > 1) {
|
|
39
|
+
const reducedTargets = currentTargets.slice(0, 2);
|
|
40
|
+
bible.technical.buildTargets = reducedTargets;
|
|
41
|
+
onProgress?.(`Technical scope updated: starting with fewer platforms (${reducedTargets.join(', ')}).`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
onProgress?.('Technical scope: keeping all configured platforms.');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Check for platform-monetization mismatch
|
|
49
|
+
// Get monetization from features (monetization is defined per-feature in schema)
|
|
50
|
+
const featureMonetization = bible.features
|
|
51
|
+
.filter((f) => f.monetization?.strategy)
|
|
52
|
+
.map((f) => f.monetization.strategy);
|
|
53
|
+
const monetization = featureMonetization.length > 0 ? featureMonetization[0] : '';
|
|
54
|
+
const platforms = bible.technical.buildTargets.map((p) => p.toLowerCase());
|
|
55
|
+
const monetizationLower = monetization.toLowerCase();
|
|
56
|
+
// Exclude hybrid models like "Freemium" or "Free-to-Play with Premium"
|
|
57
|
+
const isHybridFreeModel = monetizationLower.includes('freemium') ||
|
|
58
|
+
monetizationLower.includes('free-to-play') ||
|
|
59
|
+
(monetizationLower.includes('free') && monetizationLower.includes('premium'));
|
|
60
|
+
if (platforms.includes('mobile') && monetizationLower.includes('premium') && !isHybridFreeModel) {
|
|
61
|
+
const result = await this.askClarification(`Premium paid games are rare on mobile. Most successful mobile games use Free-to-Play or Ad-Supported models. Is this intentional?`, bible, 'Mobile Monetization');
|
|
62
|
+
const decision = (result.answer || '').toLowerCase();
|
|
63
|
+
if (decision.includes('yes') || decision.includes('intentional') || decision.includes('premium')) {
|
|
64
|
+
onProgress?.('Premium mobile monetization acknowledged as intentional strategy');
|
|
65
|
+
}
|
|
66
|
+
else if (decision.includes('change') || decision.includes('free')) {
|
|
67
|
+
onProgress?.('Note: Consider revising monetization model for mobile platform');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (platforms.some((p) => p.includes('console')) && monetizationLower.includes('ads')) {
|
|
71
|
+
const result = await this.askClarification(`Ad-supported monetization is uncommon on console platforms. Did you mean a different model?`, bible, 'Console Monetization');
|
|
72
|
+
const decision = (result.answer || '').toLowerCase();
|
|
73
|
+
if (decision.includes('yes') || decision.includes('intentional') || decision.includes('ads')) {
|
|
74
|
+
onProgress?.('Ad-supported console monetization acknowledged as intentional');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
onProgress?.('Note: Consider revising monetization model for console platform');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Check for platform-control mismatches in UI requirements
|
|
81
|
+
const allUIRequirements = bible.features
|
|
82
|
+
.flatMap((f) => f.uiRequirements || [])
|
|
83
|
+
.join(' ')
|
|
84
|
+
.toLowerCase();
|
|
85
|
+
if (platforms.includes('mobile')) {
|
|
86
|
+
if (allUIRequirements.includes('keyboard') ||
|
|
87
|
+
allUIRequirements.includes('mouse') ||
|
|
88
|
+
allUIRequirements.includes('wasd')) {
|
|
89
|
+
await this.askClarification(`Detected keyboard/mouse controls for mobile platform. Should we use touch controls instead?`, bible, 'Mobile Controls');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (platforms.some((p) => p.includes('console'))) {
|
|
93
|
+
if (allUIRequirements.includes('touch') ||
|
|
94
|
+
allUIRequirements.includes('swipe') ||
|
|
95
|
+
allUIRequirements.includes('tap')) {
|
|
96
|
+
await this.askClarification(`Detected touch controls for console platform. Should we use gamepad controls instead?`, bible, 'Console Controls');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Check for complexity stacking
|
|
100
|
+
const hasMultiplayer = bible.technical.networking || bible.features.some((f) => f.multiplayer);
|
|
101
|
+
const hasProcedural = bible.features.some((f) => f.procedural);
|
|
102
|
+
const hasPhysics = bible.features.some((f) => f.physics);
|
|
103
|
+
if (hasMultiplayer && hasProcedural && hasPhysics) {
|
|
104
|
+
const result = await this.askClarification(`Combining multiplayer + procedural generation + physics simulation is very complex. Is this feasible for a "${scope}" project?`, bible, 'Technical Complexity');
|
|
105
|
+
const decision = (result.answer || '').toLowerCase();
|
|
106
|
+
if (decision.includes('yes') || decision.includes('feasible') || decision.includes('experienced')) {
|
|
107
|
+
onProgress?.('High technical complexity acknowledged - team has experience with complex systems');
|
|
108
|
+
}
|
|
109
|
+
else if (decision.includes('simplify') || decision.includes('reduce') || decision.includes('no')) {
|
|
110
|
+
onProgress?.('Note: Consider simplifying technical scope - remove procedural generation or reduce physics complexity');
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
onProgress?.('Technical complexity acknowledged');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Check for localization strategy mismatch
|
|
117
|
+
if (bible.technical.localization) {
|
|
118
|
+
const strategy = bible.technical.localization.strategy;
|
|
119
|
+
const languageCount = bible.technical.localization.languages?.length || 0;
|
|
120
|
+
if (strategy === 'Global' && languageCount < 5) {
|
|
121
|
+
const result = await this.askClarification(`Global localization strategy with only ${languageCount} languages. Did you mean 'EFIGS' or should we add more languages?`, bible, 'Localization Strategy');
|
|
122
|
+
const decision = (result.answer || '').toLowerCase();
|
|
123
|
+
if (decision.includes('efigs')) {
|
|
124
|
+
bible.technical.localization.strategy = 'EFIGS';
|
|
125
|
+
onProgress?.('Updated localization strategy to EFIGS');
|
|
126
|
+
}
|
|
127
|
+
else if (decision.includes('add') || decision.includes('more')) {
|
|
128
|
+
onProgress?.('Note: Consider expanding language list for Global localization strategy');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Check for cross-platform without clear primary
|
|
133
|
+
if (platformCount > 1) {
|
|
134
|
+
const result = await this.askClarification(`Targeting multiple platforms: ${bible.technical.buildTargets.join(', ')}. Which is PRIMARY for initial development?`, bible, 'Primary Platform');
|
|
135
|
+
const decision = (result.answer || '').toLowerCase();
|
|
136
|
+
const currentTargets = bible.technical.buildTargets;
|
|
137
|
+
// Try to identify primary platform from response
|
|
138
|
+
for (const platform of currentTargets) {
|
|
139
|
+
if (decision.includes(platform.toLowerCase())) {
|
|
140
|
+
onProgress?.(`Primary platform identified as: ${platform}`);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!decision.match(/windows|mac|linux|ios|android|console/i)) {
|
|
145
|
+
onProgress?.('Note: Primary platform should be clearly specified for development focus');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const prompt = `Generate a brief technical overview for stakeholders (not developers):
|
|
23
149
|
|
|
24
|
-
Technical Spec: ${JSON.stringify(bible.technical, null, 2)}
|
|
25
150
|
Game: ${bible.meta.title}
|
|
151
|
+
Technical Info: ${JSON.stringify(bible.technical, null, 2)}
|
|
26
152
|
|
|
27
|
-
Create markdown with these sections:
|
|
153
|
+
Create a concise markdown document with these sections:
|
|
28
154
|
|
|
29
|
-
#
|
|
155
|
+
# Technical Overview
|
|
30
156
|
|
|
31
|
-
## Engine
|
|
32
|
-
|
|
33
|
-
${bible.technical.engine.
|
|
34
|
-
${bible.technical.engine.reasoning ? `**Reasoning**: ${bible.technical.engine.reasoning}` : ''}
|
|
157
|
+
## Game Engine
|
|
158
|
+
Describe the chosen engine (${bible.technical.engine.primary}${bible.technical.engine.version ? ` ${bible.technical.engine.version}` : ''}) and briefly explain why it's a good fit for this project.
|
|
159
|
+
${bible.technical.engine.reasoning ? `Use this reasoning: ${bible.technical.engine.reasoning}` : ''}
|
|
35
160
|
|
|
36
|
-
##
|
|
37
|
-
|
|
161
|
+
## Target Platforms
|
|
162
|
+
List the platforms: ${bible.technical.buildTargets.join(', ')}
|
|
163
|
+
Briefly mention any platform-specific considerations.
|
|
38
164
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
${bible.technical.
|
|
42
|
-
|
|
165
|
+
${bible.technical.networking ? `## Multiplayer
|
|
166
|
+
${bible.technical.networking.architecture ? `Architecture: ${bible.technical.networking.architecture}` : ''}
|
|
167
|
+
${bible.technical.networking.maxPlayers ? `Supports up to ${bible.technical.networking.maxPlayers} players.` : ''}
|
|
168
|
+
Describe the multiplayer approach in 2-3 sentences.
|
|
169
|
+
` : ''}
|
|
43
170
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
${bible.technical.
|
|
47
|
-
|
|
171
|
+
${bible.technical.localization ? `## Localization
|
|
172
|
+
Strategy: ${bible.technical.localization.strategy}
|
|
173
|
+
${bible.technical.localization.languages ? `Languages: ${bible.technical.localization.languages.join(', ')}` : ''}
|
|
174
|
+
` : ''}
|
|
48
175
|
|
|
49
|
-
|
|
50
|
-
|
|
176
|
+
${bible.technical.accessibility ? `## Accessibility Features
|
|
177
|
+
List the planned accessibility features:
|
|
178
|
+
${bible.technical.accessibility.colorblindMode ? '- Colorblind mode support' : ''}
|
|
179
|
+
${bible.technical.accessibility.subtitles ? '- Subtitles for audio' : ''}
|
|
180
|
+
${bible.technical.accessibility.remappableControls ? '- Remappable controls' : ''}
|
|
181
|
+
${bible.technical.accessibility.difficultyOptions ? '- Adjustable difficulty options' : ''}
|
|
182
|
+
` : ''}
|
|
51
183
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
184
|
+
IMPORTANT: Keep this document SHORT (1-2 pages max). This is for stakeholders to understand the technical direction, not a developer specification. Do NOT include:
|
|
185
|
+
- Code or pseudo-code
|
|
186
|
+
- Directory structures
|
|
187
|
+
- Tool lists
|
|
188
|
+
- Performance metrics
|
|
189
|
+
- Implementation details`;
|
|
190
|
+
const result = await this.callLLMWithAutoRetry(prompt, modelSelector_1.TaskComplexity.SIMPLE, {
|
|
191
|
+
initialMaxTokens: 4000,
|
|
55
192
|
maxRetries: 2,
|
|
56
193
|
onProgress: onProgress
|
|
57
194
|
});
|