@musashishao/agent-kit 1.9.0 → 1.9.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.
Files changed (125) hide show
  1. package/.agent/agents/ai-asset-factory.md +700 -0
  2. package/.agent/agents/ai-audio-factory.md +503 -0
  3. package/.agent/agents/game-developer.md +4 -4
  4. package/.agent/agents/orchestrator.md +113 -3
  5. package/.agent/agents/project-planner.md +67 -0
  6. package/.agent/agents/unity-mobile-master.md +949 -0
  7. package/.agent/mcp/config/registry.json +65 -51
  8. package/.agent/mcp/servers/notebooklm/README.md +114 -0
  9. package/.agent/mcp/servers/notebooklm/package.json +35 -0
  10. package/.agent/mcp/servers/notebooklm/src/auth/chrome.ts +225 -0
  11. package/.agent/mcp/servers/notebooklm/src/auth/index.ts +1 -0
  12. package/.agent/mcp/servers/notebooklm/src/index.ts +516 -0
  13. package/.agent/mcp/servers/notebooklm/src/services/index.ts +3 -0
  14. package/.agent/mcp/servers/notebooklm/src/services/library.ts +217 -0
  15. package/.agent/mcp/servers/notebooklm/src/services/notebooklm.ts +380 -0
  16. package/.agent/mcp/servers/notebooklm/tsconfig.json +15 -0
  17. package/.agent/mcp-gateway/README.md +169 -20
  18. package/.agent/mcp-gateway/package.json +22 -7
  19. package/.agent/mcp-gateway/src/auth/index.ts +55 -0
  20. package/.agent/mcp-gateway/src/auth/middleware.ts +242 -0
  21. package/.agent/mcp-gateway/src/auth/oauth.ts +462 -0
  22. package/.agent/mcp-gateway/src/auth/scopes.ts +227 -0
  23. package/.agent/mcp-gateway/src/index.ts +252 -105
  24. package/.agent/mcp-gateway/src/observability/index.ts +5 -0
  25. package/.agent/mcp-gateway/src/observability/otel.ts +405 -0
  26. package/.agent/mcp-gateway/src/transports/index.ts +5 -0
  27. package/.agent/mcp-gateway/src/transports/streamableHttp.ts +235 -0
  28. package/.agent/rules/CODEX.md +89 -0
  29. package/.agent/rules/CODE_RULES.md +73 -0
  30. package/.agent/rules/GEMINI.md +25 -0
  31. package/.agent/rules/MEMORY_STATE.md +110 -0
  32. package/.agent/rules/REFERENCE.md +33 -141
  33. package/.agent/rules/REF_SKILLS.md +116 -0
  34. package/.agent/rules/REF_WORKFLOWS.md +81 -0
  35. package/.agent/scripts/ak_cli.py +106 -5
  36. package/.agent/scripts/memory_manager.py +48 -9
  37. package/.agent/skills/anti-hallucination/SKILL.md +295 -0
  38. package/.agent/skills/anti-hallucination/scripts/check_hallucination.py +299 -0
  39. package/.agent/skills/bifurcation-analysis/SKILL.md +56 -0
  40. package/.agent/skills/brainstorming/SKILL.md +80 -6
  41. package/.agent/skills/decision-memory/SKILL.md +317 -0
  42. package/.agent/skills/emergence-detector/SKILL.md +230 -0
  43. package/.agent/skills/emergence-detector/scripts/check_emergence.py +265 -0
  44. package/.agent/skills/explained-qa/SKILL.md +142 -0
  45. package/.agent/skills/explained-qa/game-terminology.md +214 -0
  46. package/.agent/skills/game-development/ai-dialogue-engine/SKILL.md +442 -0
  47. package/.agent/skills/game-development/ai-graphics-generator/SKILL.md +463 -0
  48. package/.agent/skills/game-development/ai-playtest-framework/SKILL.md +570 -0
  49. package/.agent/skills/game-development/camera-systems/SKILL.md +607 -0
  50. package/.agent/skills/game-development/card-battle-engine/SKILL.md +618 -0
  51. package/.agent/skills/game-development/character-controller-3d/SKILL.md +908 -0
  52. package/.agent/skills/game-development/cloud-save-sync/SKILL.md +527 -0
  53. package/.agent/skills/game-development/combat-system/SKILL.md +748 -0
  54. package/.agent/skills/game-development/compliance-rating/SKILL.md +277 -0
  55. package/.agent/skills/game-development/crossplatform-build/SKILL.md +386 -0
  56. package/.agent/skills/game-development/cultivation-progression/SKILL.md +520 -0
  57. package/.agent/skills/game-development/data-driven-balance/SKILL.md +535 -0
  58. package/.agent/skills/game-development/game-analytics-integrator/SKILL.md +410 -0
  59. package/.agent/skills/game-development/game-audio-advanced/SKILL.md +646 -0
  60. package/.agent/skills/game-development/game-economy-designer/SKILL.md +375 -0
  61. package/.agent/skills/game-development/game-marketing/SKILL.md +85 -0
  62. package/.agent/skills/game-development/game-state-manager/SKILL.md +883 -0
  63. package/.agent/skills/game-development/hybrid-game-spec/SKILL.md +220 -0
  64. package/.agent/skills/game-development/inventory-quest/SKILL.md +747 -0
  65. package/.agent/skills/game-development/liveops/SKILL.md +308 -0
  66. package/.agent/skills/game-development/localization/SKILL.md +286 -0
  67. package/.agent/skills/game-development/mobile-input-patterns/SKILL.md +343 -0
  68. package/.agent/skills/game-development/monetization-strategy/SKILL.md +94 -0
  69. package/.agent/skills/game-development/multiplayer-master/SKILL.md +727 -0
  70. package/.agent/skills/game-development/narrative-branching/SKILL.md +593 -0
  71. package/.agent/skills/game-development/procedural-level-ai/SKILL.md +367 -0
  72. package/.agent/skills/game-development/prototyping-rapid/SKILL.md +205 -0
  73. package/.agent/skills/game-development/spec-ecosystem/SKILL.md +155 -0
  74. package/.agent/skills/game-development/spec-ecosystem/decision-log-format.md +129 -0
  75. package/.agent/skills/game-development/spec-ecosystem/templates/PLAN-template.md +178 -0
  76. package/.agent/skills/game-development/spec-ecosystem/templates/SPEC-template.md +110 -0
  77. package/.agent/skills/game-development/spec-ecosystem/templates/TASKS-template.md +156 -0
  78. package/.agent/skills/game-development/survival-systems/SKILL.md +493 -0
  79. package/.agent/skills/game-development/testing-qa/SKILL.md +270 -0
  80. package/.agent/skills/game-development/unity-mobile-optimization/SKILL.md +271 -0
  81. package/.agent/skills/intent-capture/SKILL.md +65 -0
  82. package/.agent/skills/mcp-composition/SKILL.md +362 -0
  83. package/.agent/skills/mcp-observability/SKILL.md +323 -0
  84. package/.agent/skills/mcp-security/SKILL.md +314 -0
  85. package/.agent/skills/trust-spectrum/SKILL.md +291 -0
  86. package/.agent/skills/vibe-coding-guard/SKILL.md +328 -0
  87. package/.agent/templates/AGENTS.game.md +63 -0
  88. package/.agent/templates/docs/WORKFLOW_GUIDE.en.md +100 -0
  89. package/.agent/templates/docs/WORKFLOW_GUIDE.vi.md +100 -0
  90. package/.agent/workflows/ai-agent.md +2 -0
  91. package/.agent/workflows/autofix.md +1 -0
  92. package/.agent/workflows/brainstorm.md +1 -0
  93. package/.agent/workflows/context.md +1 -0
  94. package/.agent/workflows/create.md +39 -8
  95. package/.agent/workflows/dashboard.md +1 -0
  96. package/.agent/workflows/debug.md +14 -0
  97. package/.agent/workflows/deploy.md +14 -0
  98. package/.agent/workflows/enhance.md +44 -0
  99. package/.agent/workflows/gamekit-init.md +177 -0
  100. package/.agent/workflows/gamekit-launch.md +338 -0
  101. package/.agent/workflows/gamekit-plan.md +204 -0
  102. package/.agent/workflows/gamekit-qa.md +153 -0
  103. package/.agent/workflows/gamekit-spec.md +243 -0
  104. package/.agent/workflows/gamekit-tasks.md +208 -0
  105. package/.agent/workflows/marketing.md +2 -0
  106. package/.agent/workflows/next.md +1 -0
  107. package/.agent/workflows/orchestrate.md +12 -0
  108. package/.agent/workflows/pentest.md +2 -0
  109. package/.agent/workflows/plan.md +42 -0
  110. package/.agent/workflows/preview.md +1 -0
  111. package/.agent/workflows/quality.md +1 -0
  112. package/.agent/workflows/saas.md +2 -0
  113. package/.agent/workflows/spec.md +42 -0
  114. package/.agent/workflows/status.md +1 -0
  115. package/.agent/workflows/test.md +14 -0
  116. package/.agent/workflows/ui-ux-pro-max.md +1 -0
  117. package/bin/cli.js +411 -111
  118. package/package.json +1 -2
  119. package/.agent/agents/game-asset-curator.md +0 -317
  120. package/.agent/agents/game-narrative-designer.md +0 -310
  121. package/.agent/agents/game-qa-agent.md +0 -441
  122. package/.agent/workflows/game-prototype.md +0 -154
  123. package/docs/AI_DATA_INFRASTRUCTURE.md +0 -288
  124. package/docs/CHANGELOG_AI_INFRA.md +0 -141
  125. package/docs/MIGRATION_GUIDE_V1.9.md +0 -55
@@ -0,0 +1,593 @@
1
+ ---
2
+ name: narrative-branching
3
+ description: Branching narrative and dialogue systems. Dialogue trees, story branches, player choices, relationship systems, quest journals, and conditional content for Unity.
4
+ ---
5
+
6
+ # Narrative Branching Skill
7
+
8
+ > **Purpose**: Build games with meaningful choices and branching stories.
9
+
10
+ ## When to Use
11
+ - Building story-driven games
12
+ - Implementing dialogue systems
13
+ - Creating relationship mechanics
14
+ - Designing quest systems
15
+
16
+ ---
17
+
18
+ ## 1. Dialogue Node System
19
+
20
+ ### Core Data Structures
21
+ ```csharp
22
+ [CreateAssetMenu(fileName = "DialogueTree", menuName = "Game/Narrative/DialogueTree")]
23
+ public class DialogueTree : ScriptableObject
24
+ {
25
+ public string treeId;
26
+ public string treeName;
27
+
28
+ [Header("Nodes")]
29
+ public DialogueNode startNode;
30
+ public DialogueNode[] allNodes;
31
+
32
+ [Header("Requirements")]
33
+ public Condition[] startConditions;
34
+
35
+ [Header("Metadata")]
36
+ public CharacterData speaker;
37
+ public bool isRepeatable = true;
38
+ }
39
+
40
+ [System.Serializable]
41
+ public class DialogueNode
42
+ {
43
+ public string nodeId;
44
+ public NodeType type;
45
+
46
+ [Header("Content")]
47
+ public CharacterData speaker;
48
+ [TextArea(3, 10)]
49
+ public string dialogueText;
50
+ public AudioClip voiceover;
51
+ public float displayDuration = 0f; // 0 = wait for input
52
+
53
+ [Header("Choices")]
54
+ public DialogueChoice[] choices;
55
+
56
+ [Header("Auto-Continue")]
57
+ public DialogueNode nextNode; // Used when no choices
58
+
59
+ [Header("Effects")]
60
+ public DialogueEffect[] onEnterEffects;
61
+ public DialogueEffect[] onExitEffects;
62
+ }
63
+
64
+ public enum NodeType
65
+ {
66
+ Dialogue, // Normal dialogue
67
+ Choice, // Player makes choice
68
+ Branch, // Conditional branch (NPC decides)
69
+ Event, // Trigger game event
70
+ End // End conversation
71
+ }
72
+
73
+ [System.Serializable]
74
+ public class DialogueChoice
75
+ {
76
+ public string choiceText;
77
+ public DialogueNode targetNode;
78
+
79
+ [Header("Requirements")]
80
+ public Condition[] showConditions; // To display choice
81
+ public Condition[] enableConditions; // To select choice (grayed vs available)
82
+
83
+ [Header("Tooltip")]
84
+ public string disabledReason; // "Requires 5 Charisma"
85
+
86
+ [Header("Effects")]
87
+ public DialogueEffect[] onSelectEffects;
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 2. Condition System
94
+
95
+ ### Conditions for Branching
96
+ ```csharp
97
+ [System.Serializable]
98
+ public class Condition
99
+ {
100
+ public ConditionType type;
101
+ public string targetId;
102
+ public ComparisonOperator comparison;
103
+ public int value;
104
+
105
+ public bool Evaluate()
106
+ {
107
+ int actualValue = GetActualValue();
108
+
109
+ return comparison switch
110
+ {
111
+ ComparisonOperator.Equals => actualValue == value,
112
+ ComparisonOperator.NotEquals => actualValue != value,
113
+ ComparisonOperator.GreaterThan => actualValue > value,
114
+ ComparisonOperator.LessThan => actualValue < value,
115
+ ComparisonOperator.GreaterOrEqual => actualValue >= value,
116
+ ComparisonOperator.LessOrEqual => actualValue <= value,
117
+ _ => false
118
+ };
119
+ }
120
+
121
+ private int GetActualValue()
122
+ {
123
+ return type switch
124
+ {
125
+ ConditionType.HasItem => InventoryManager.GetItemCount(targetId),
126
+ ConditionType.QuestState => QuestManager.GetQuestState(targetId),
127
+ ConditionType.RelationshipLevel => RelationshipManager.GetLevel(targetId),
128
+ ConditionType.PlayerStat => PlayerStats.GetStat(targetId),
129
+ ConditionType.Flag => FlagManager.IsSet(targetId) ? 1 : 0,
130
+ ConditionType.DialogueHistory => DialogueHistory.TimesChosen(targetId),
131
+ ConditionType.TimeOfDay => TimeManager.CurrentHour,
132
+ ConditionType.Random => Random.Range(0, 100),
133
+ _ => 0
134
+ };
135
+ }
136
+ }
137
+
138
+ public enum ConditionType
139
+ {
140
+ HasItem,
141
+ QuestState,
142
+ RelationshipLevel,
143
+ PlayerStat,
144
+ Flag,
145
+ DialogueHistory,
146
+ TimeOfDay,
147
+ Random
148
+ }
149
+
150
+ public enum ComparisonOperator
151
+ {
152
+ Equals,
153
+ NotEquals,
154
+ GreaterThan,
155
+ LessThan,
156
+ GreaterOrEqual,
157
+ LessOrEqual
158
+ }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 3. Dialogue Effects
164
+
165
+ ### Effect System
166
+ ```csharp
167
+ [System.Serializable]
168
+ public class DialogueEffect
169
+ {
170
+ public EffectType type;
171
+ public string targetId;
172
+ public int value;
173
+ public string stringValue;
174
+
175
+ public void Execute()
176
+ {
177
+ switch (type)
178
+ {
179
+ case EffectType.GiveItem:
180
+ InventoryManager.AddItem(targetId, value);
181
+ break;
182
+
183
+ case EffectType.TakeItem:
184
+ InventoryManager.RemoveItem(targetId, value);
185
+ break;
186
+
187
+ case EffectType.ChangeRelationship:
188
+ RelationshipManager.Modify(targetId, value);
189
+ break;
190
+
191
+ case EffectType.SetFlag:
192
+ FlagManager.Set(targetId, value == 1);
193
+ break;
194
+
195
+ case EffectType.StartQuest:
196
+ QuestManager.StartQuest(targetId);
197
+ break;
198
+
199
+ case EffectType.CompleteQuestObjective:
200
+ QuestManager.CompleteObjective(targetId);
201
+ break;
202
+
203
+ case EffectType.ChangePlayerStat:
204
+ PlayerStats.Modify(targetId, value);
205
+ break;
206
+
207
+ case EffectType.PlayCutscene:
208
+ CutsceneManager.Play(targetId);
209
+ break;
210
+
211
+ case EffectType.TeleportPlayer:
212
+ PlayerManager.Teleport(targetId);
213
+ break;
214
+
215
+ case EffectType.SpawnNPC:
216
+ NPCManager.Spawn(targetId);
217
+ break;
218
+
219
+ case EffectType.Custom:
220
+ GameEvents.OnCustomDialogueEffect?.Invoke(targetId, stringValue);
221
+ break;
222
+ }
223
+
224
+ GameEvents.OnDialogueEffectExecuted?.Invoke(this);
225
+ }
226
+ }
227
+
228
+ public enum EffectType
229
+ {
230
+ GiveItem,
231
+ TakeItem,
232
+ ChangeRelationship,
233
+ SetFlag,
234
+ StartQuest,
235
+ CompleteQuestObjective,
236
+ ChangePlayerStat,
237
+ PlayCutscene,
238
+ TeleportPlayer,
239
+ SpawnNPC,
240
+ Custom
241
+ }
242
+ ```
243
+
244
+ ---
245
+
246
+ ## 4. Dialogue Manager
247
+
248
+ ### Runtime Controller
249
+ ```csharp
250
+ public class DialogueManager : MonoBehaviour
251
+ {
252
+ public static DialogueManager Instance { get; private set; }
253
+
254
+ [SerializeField] private DialogueUI _dialogueUI;
255
+
256
+ public bool IsInDialogue { get; private set; }
257
+ public DialogueTree CurrentTree { get; private set; }
258
+ public DialogueNode CurrentNode { get; private set; }
259
+
260
+ public event Action<DialogueTree> OnDialogueStarted;
261
+ public event Action<DialogueNode> OnNodeEntered;
262
+ public event Action<DialogueChoice> OnChoiceSelected;
263
+ public event Action OnDialogueEnded;
264
+
265
+ public bool StartDialogue(DialogueTree tree)
266
+ {
267
+ // Check start conditions
268
+ if (!EvaluateConditions(tree.startConditions))
269
+ return false;
270
+
271
+ IsInDialogue = true;
272
+ CurrentTree = tree;
273
+
274
+ OnDialogueStarted?.Invoke(tree);
275
+ _dialogueUI.Show();
276
+
277
+ EnterNode(tree.startNode);
278
+ return true;
279
+ }
280
+
281
+ private void EnterNode(DialogueNode node)
282
+ {
283
+ CurrentNode = node;
284
+
285
+ // Execute on-enter effects
286
+ foreach (var effect in node.onEnterEffects)
287
+ {
288
+ effect.Execute();
289
+ }
290
+
291
+ OnNodeEntered?.Invoke(node);
292
+
293
+ // Update UI
294
+ _dialogueUI.DisplayNode(node);
295
+
296
+ // Handle node type
297
+ switch (node.type)
298
+ {
299
+ case NodeType.Dialogue:
300
+ // Wait for player input or auto-continue
301
+ if (node.nextNode != null && node.displayDuration > 0)
302
+ {
303
+ StartCoroutine(AutoContinue(node.displayDuration));
304
+ }
305
+ break;
306
+
307
+ case NodeType.Choice:
308
+ // Display available choices
309
+ var validChoices = GetValidChoices(node.choices);
310
+ _dialogueUI.ShowChoices(validChoices);
311
+ break;
312
+
313
+ case NodeType.Branch:
314
+ // Auto-select based on conditions
315
+ AutoBranch(node.choices);
316
+ break;
317
+
318
+ case NodeType.Event:
319
+ // Execute and continue
320
+ foreach (var effect in node.onExitEffects)
321
+ {
322
+ effect.Execute();
323
+ }
324
+ if (node.nextNode != null)
325
+ EnterNode(node.nextNode);
326
+ else
327
+ EndDialogue();
328
+ break;
329
+
330
+ case NodeType.End:
331
+ EndDialogue();
332
+ break;
333
+ }
334
+ }
335
+
336
+ public void SelectChoice(DialogueChoice choice)
337
+ {
338
+ // Execute choice effects
339
+ foreach (var effect in choice.onSelectEffects)
340
+ {
341
+ effect.Execute();
342
+ }
343
+
344
+ // Record in history
345
+ DialogueHistory.RecordChoice(CurrentTree.treeId, CurrentNode.nodeId, choice.choiceText);
346
+
347
+ OnChoiceSelected?.Invoke(choice);
348
+
349
+ // Navigate to target
350
+ if (choice.targetNode != null)
351
+ {
352
+ // Execute current node exit effects
353
+ foreach (var effect in CurrentNode.onExitEffects)
354
+ {
355
+ effect.Execute();
356
+ }
357
+
358
+ EnterNode(choice.targetNode);
359
+ }
360
+ else
361
+ {
362
+ EndDialogue();
363
+ }
364
+ }
365
+
366
+ private void EndDialogue()
367
+ {
368
+ IsInDialogue = false;
369
+ _dialogueUI.Hide();
370
+
371
+ OnDialogueEnded?.Invoke();
372
+ GameEvents.OnDialogueEnded?.Invoke(CurrentTree);
373
+
374
+ CurrentTree = null;
375
+ CurrentNode = null;
376
+ }
377
+ }
378
+ ```
379
+
380
+ ---
381
+
382
+ ## 5. Relationship System
383
+
384
+ ### Relationship Data
385
+ ```csharp
386
+ [CreateAssetMenu(fileName = "Character", menuName = "Game/Narrative/Character")]
387
+ public class CharacterData : ScriptableObject
388
+ {
389
+ public string characterId;
390
+ public string displayName;
391
+ public Sprite portrait;
392
+
393
+ [Header("Relationship")]
394
+ public int defaultRelationship = 50; // 0-100
395
+ public RelationshipTier[] tiers;
396
+
397
+ [Header("Personality")]
398
+ public PersonalityTrait[] traits;
399
+ public string[] likes;
400
+ public string[] dislikes;
401
+ }
402
+
403
+ [System.Serializable]
404
+ public class RelationshipTier
405
+ {
406
+ public string tierName; // Stranger, Acquaintance, Friend, Close Friend, Romance
407
+ public int minValue;
408
+ public DialogueTree[] availableDialogues;
409
+ public Sprite tierIcon;
410
+ }
411
+
412
+ public class RelationshipManager : MonoBehaviour
413
+ {
414
+ private Dictionary<string, int> _relationships = new();
415
+
416
+ public event Action<string, int, int> OnRelationshipChanged; // characterId, oldVal, newVal
417
+ public event Action<string, RelationshipTier> OnTierChanged;
418
+
419
+ public int GetLevel(string characterId)
420
+ {
421
+ _relationships.TryGetValue(characterId, out int level);
422
+ return level;
423
+ }
424
+
425
+ public void Modify(string characterId, int delta)
426
+ {
427
+ int oldValue = GetLevel(characterId);
428
+ int newValue = Mathf.Clamp(oldValue + delta, 0, 100);
429
+
430
+ _relationships[characterId] = newValue;
431
+
432
+ OnRelationshipChanged?.Invoke(characterId, oldValue, newValue);
433
+
434
+ // Check tier change
435
+ var oldTier = GetTier(characterId, oldValue);
436
+ var newTier = GetTier(characterId, newValue);
437
+
438
+ if (oldTier != newTier)
439
+ {
440
+ OnTierChanged?.Invoke(characterId, newTier);
441
+ GameEvents.OnRelationshipTierChanged?.Invoke(characterId, newTier);
442
+ }
443
+ }
444
+
445
+ public void GiveGift(string characterId, ItemData item)
446
+ {
447
+ var character = GetCharacter(characterId);
448
+
449
+ int delta = 5; // Base
450
+
451
+ if (character.likes.Contains(item.itemId))
452
+ delta = 15;
453
+ else if (character.dislikes.Contains(item.itemId))
454
+ delta = -10;
455
+
456
+ Modify(characterId, delta);
457
+ GameEvents.OnGiftGiven?.Invoke(characterId, item, delta);
458
+ }
459
+ }
460
+ ```
461
+
462
+ ---
463
+
464
+ ## 6. Quest Journal
465
+
466
+ ### Quest System
467
+ ```csharp
468
+ [CreateAssetMenu(fileName = "Quest", menuName = "Game/Narrative/Quest")]
469
+ public class QuestData : ScriptableObject
470
+ {
471
+ public string questId;
472
+ public string questName;
473
+ [TextArea] public string description;
474
+
475
+ public QuestType type;
476
+ public CharacterData questGiver;
477
+
478
+ [Header("Objectives")]
479
+ public QuestObjective[] objectives;
480
+
481
+ [Header("Rewards")]
482
+ public ItemReward[] itemRewards;
483
+ public int goldReward;
484
+ public int expReward;
485
+
486
+ [Header("Flow")]
487
+ public QuestData[] prerequisiteQuests;
488
+ public DialogueTree startDialogue;
489
+ public DialogueTree completeDialogue;
490
+ }
491
+
492
+ [System.Serializable]
493
+ public class QuestObjective
494
+ {
495
+ public string objectiveId;
496
+ public string description;
497
+ public ObjectiveType type;
498
+ public string targetId;
499
+ public int requiredCount = 1;
500
+ public bool isOptional = false;
501
+ }
502
+
503
+ public enum ObjectiveType
504
+ {
505
+ Kill, // Kill X enemies of type
506
+ Collect, // Collect X items
507
+ TalkTo, // Talk to NPC
508
+ GoTo, // Reach location
509
+ Escort, // Escort NPC
510
+ Defend, // Defend location for time
511
+ Deliver, // Bring item to NPC
512
+ Investigate, // Examine objects
513
+ Custom // Custom trigger
514
+ }
515
+
516
+ public class QuestManager : MonoBehaviour
517
+ {
518
+ private Dictionary<string, QuestState> _questStates = new();
519
+ private Dictionary<string, int> _objectiveProgress = new();
520
+
521
+ public event Action<QuestData> OnQuestStarted;
522
+ public event Action<QuestData, QuestObjective> OnObjectiveCompleted;
523
+ public event Action<QuestData> OnQuestCompleted;
524
+
525
+ public void StartQuest(string questId)
526
+ {
527
+ var quest = GetQuestData(questId);
528
+ if (quest == null || _questStates.ContainsKey(questId))
529
+ return;
530
+
531
+ _questStates[questId] = QuestState.Active;
532
+
533
+ // Initialize objective progress
534
+ foreach (var obj in quest.objectives)
535
+ {
536
+ _objectiveProgress[$"{questId}_{obj.objectiveId}"] = 0;
537
+ }
538
+
539
+ OnQuestStarted?.Invoke(quest);
540
+ GameEvents.OnQuestStarted?.Invoke(quest);
541
+ }
542
+
543
+ public void UpdateObjective(string questId, string objectiveId, int progress)
544
+ {
545
+ string key = $"{questId}_{objectiveId}";
546
+ _objectiveProgress[key] = progress;
547
+
548
+ var quest = GetQuestData(questId);
549
+ var objective = quest.objectives.First(o => o.objectiveId == objectiveId);
550
+
551
+ if (progress >= objective.requiredCount)
552
+ {
553
+ OnObjectiveCompleted?.Invoke(quest, objective);
554
+ CheckQuestCompletion(quest);
555
+ }
556
+ }
557
+
558
+ private void CheckQuestCompletion(QuestData quest)
559
+ {
560
+ bool allComplete = quest.objectives
561
+ .Where(o => !o.isOptional)
562
+ .All(o => IsObjectiveComplete(quest.questId, o.objectiveId));
563
+
564
+ if (allComplete)
565
+ {
566
+ _questStates[quest.questId] = QuestState.Completed;
567
+ GiveRewards(quest);
568
+ OnQuestCompleted?.Invoke(quest);
569
+ }
570
+ }
571
+ }
572
+
573
+ public enum QuestState { NotStarted, Active, Completed, Failed }
574
+ ```
575
+
576
+ ---
577
+
578
+ ## Anti-Patterns
579
+
580
+ | ❌ Don't | ✅ Do |
581
+ |----------|-------|
582
+ | Hardcode dialogue text | Data-driven dialogue trees |
583
+ | Binary choices only | Gradient of options |
584
+ | Ignore past choices | Track and reference history |
585
+ | One-time dialogues | Reactive, contextual dialogue |
586
+ | Linear quests | Branching objectives |
587
+
588
+ ---
589
+
590
+ ## Related Skills
591
+ - `game-development/ai-dialogue-engine` - LLM-powered NPCs
592
+ - `game-development/game-state-manager` - Save narrative state
593
+ - `game-development/localization` - Translate dialogues