@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,570 @@
1
+ ---
2
+ name: ai-playtest-framework
3
+ description: AI-powered automated playtesting framework. Deploy bots that play your game, find bugs, test balance, and measure player experience.
4
+ ---
5
+
6
+ # AI Playtest Framework 🤖🎮
7
+
8
+ > **Let AI play your game 24/7.** Find bugs, test balance, and measure fun before players do.
9
+
10
+ ## Overview
11
+
12
+ This skill provides patterns for implementing AI-powered playtesting bots that can:
13
+ - Play through your entire game automatically
14
+ - Find crashes, soft locks, and progression blockers
15
+ - Test game balance and identify exploits
16
+ - Measure difficulty curves and player experience
17
+ - Generate coverage and performance reports
18
+
19
+ ---
20
+
21
+ ## Bot Types
22
+
23
+ ### 1. Random Bot (Monkey Testing)
24
+
25
+ **Purpose**: Find crashes and edge cases through random actions
26
+
27
+ ```python
28
+ # random_bot.py
29
+ class RandomBot:
30
+ """Executes random valid actions to find edge cases"""
31
+
32
+ def __init__(self, game_api):
33
+ self.game = game_api
34
+ self.action_log = []
35
+ self.crash_log = []
36
+
37
+ def run(self, max_steps=10000, max_crashes=10):
38
+ steps = 0
39
+ crashes = 0
40
+
41
+ while steps < max_steps and crashes < max_crashes:
42
+ try:
43
+ # Get current valid actions
44
+ actions = self.game.get_valid_actions()
45
+
46
+ if not actions:
47
+ self.log_softlock(steps)
48
+ self.game.reset()
49
+ continue
50
+
51
+ # Random action selection
52
+ action = random.choice(actions)
53
+ self.action_log.append(action)
54
+
55
+ # Execute
56
+ result = self.game.execute(action)
57
+
58
+ # Check for anomalies
59
+ self.check_anomalies(result, steps)
60
+
61
+ steps += 1
62
+
63
+ except Exception as e:
64
+ crashes += 1
65
+ self.log_crash(steps, e)
66
+ self.game.reset()
67
+
68
+ return self.generate_report()
69
+ ```
70
+
71
+ ### 2. Explorer Bot (Coverage Testing)
72
+
73
+ **Purpose**: Maximize game state coverage
74
+
75
+ ```python
76
+ # explorer_bot.py
77
+ class ExplorerBot:
78
+ """Systematically explores game states for maximum coverage"""
79
+
80
+ def __init__(self, game_api):
81
+ self.game = game_api
82
+ self.visited_states = set()
83
+ self.state_graph = {}
84
+
85
+ def run(self, target_coverage=0.8):
86
+ while self.get_coverage() < target_coverage:
87
+ # Prioritize unvisited states
88
+ current = self.game.get_state_hash()
89
+
90
+ if current not in self.visited_states:
91
+ self.visited_states.add(current)
92
+ self.map_connections(current)
93
+
94
+ # Move toward unexplored areas
95
+ next_action = self.find_path_to_unexplored()
96
+
97
+ if next_action:
98
+ self.game.execute(next_action)
99
+ else:
100
+ # Random exploration when stuck
101
+ self.random_action()
102
+
103
+ return self.generate_coverage_map()
104
+ ```
105
+
106
+ ### 3. Speedrun Bot (Exploit Detection)
107
+
108
+ **Purpose**: Find sequence breaks and exploits
109
+
110
+ ```python
111
+ # speedrun_bot.py
112
+ class SpeedrunBot:
113
+ """Uses optimization to find fastest paths, exposing exploits"""
114
+
115
+ def __init__(self, game_api):
116
+ self.game = game_api
117
+ self.best_time = float('inf')
118
+ self.best_route = []
119
+
120
+ def run(self, iterations=1000):
121
+ for i in range(iterations):
122
+ self.game.reset()
123
+ route, time = self.attempt_speedrun()
124
+
125
+ if time < self.best_time:
126
+ self.best_time = time
127
+ self.best_route = route
128
+ self.check_for_exploits(route)
129
+
130
+ return self.generate_report()
131
+
132
+ def check_for_exploits(self, route):
133
+ """Flag suspicious sequences"""
134
+ # Look for: skipped levels, duplicate rewards, etc.
135
+ for i, action in enumerate(route):
136
+ if self.is_sequence_break(route[max(0,i-5):i+1]):
137
+ self.log_potential_exploit(route[i-5:i+5])
138
+ ```
139
+
140
+ ### 4. Balance Bot (RL-Based)
141
+
142
+ **Purpose**: Find overpowered strategies using machine learning
143
+
144
+ ```python
145
+ # balance_bot.py
146
+ class BalanceBot:
147
+ """Uses reinforcement learning to find optimal strategies"""
148
+
149
+ def __init__(self, game_api, model_path=None):
150
+ self.game = game_api
151
+ self.model = self.load_or_create_model(model_path)
152
+ self.strategy_stats = {}
153
+
154
+ def train(self, episodes=10000):
155
+ for episode in range(episodes):
156
+ state = self.game.reset()
157
+ total_reward = 0
158
+ strategy_used = []
159
+
160
+ while not self.game.is_done():
161
+ action = self.model.predict(state)
162
+ next_state, reward, done = self.game.step(action)
163
+
164
+ self.model.learn(state, action, reward, next_state)
165
+
166
+ strategy_used.append(action)
167
+ total_reward += reward
168
+ state = next_state
169
+
170
+ self.log_strategy(strategy_used, total_reward)
171
+
172
+ return self.analyze_dominant_strategies()
173
+
174
+ def analyze_dominant_strategies(self):
175
+ """Find strategies that win too often"""
176
+ report = {
177
+ "dominant_strategies": [],
178
+ "underused_strategies": [],
179
+ "balance_issues": []
180
+ }
181
+
182
+ for strategy, stats in self.strategy_stats.items():
183
+ win_rate = stats['wins'] / stats['total']
184
+
185
+ if win_rate > 0.6:
186
+ report["dominant_strategies"].append({
187
+ "strategy": strategy,
188
+ "win_rate": win_rate,
189
+ "recommendation": "Consider nerfing"
190
+ })
191
+ elif win_rate < 0.4:
192
+ report["underused_strategies"].append({
193
+ "strategy": strategy,
194
+ "win_rate": win_rate,
195
+ "recommendation": "Consider buffing"
196
+ })
197
+
198
+ return report
199
+ ```
200
+
201
+ ### 5. New Player Bot (UX Testing)
202
+
203
+ **Purpose**: Simulate new player experience
204
+
205
+ ```python
206
+ # newplayer_bot.py
207
+ class NewPlayerBot:
208
+ """Simulates a new player to test onboarding and UX"""
209
+
210
+ def __init__(self, game_api, skill_level="novice"):
211
+ self.game = game_api
212
+ self.skill_level = skill_level
213
+ self.confusion_log = []
214
+ self.frustration_log = []
215
+
216
+ def run(self):
217
+ self.game.reset()
218
+
219
+ while not self.game.is_tutorial_complete():
220
+ # Simulate confusion: don't always pick optimal action
221
+ actions = self.game.get_valid_actions()
222
+
223
+ # New players might miss hints
224
+ if not self.noticed_hint():
225
+ self.confusion_log.append({
226
+ "state": self.game.get_state(),
227
+ "issue": "Missed tutorial hint"
228
+ })
229
+
230
+ # Simulate imperfect play
231
+ action = self.pick_suboptimal_action(actions)
232
+ result = self.game.execute(action)
233
+
234
+ # Track frustration
235
+ if result.is_failure:
236
+ self.track_frustration()
237
+
238
+ return self.generate_ux_report()
239
+
240
+ def track_frustration(self):
241
+ """Track repeated failures at same point"""
242
+ current_level = self.game.get_current_level()
243
+
244
+ if current_level in self.failure_counts:
245
+ self.failure_counts[current_level] += 1
246
+
247
+ if self.failure_counts[current_level] > 3:
248
+ self.frustration_log.append({
249
+ "level": current_level,
250
+ "issue": "Difficulty spike - 3+ failures"
251
+ })
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Unity ML-Agents Integration
257
+
258
+ ### Setup
259
+
260
+ ```csharp
261
+ // PlaytestAgent.cs
262
+ using Unity.MLAgents;
263
+ using Unity.MLAgents.Sensors;
264
+ using Unity.MLAgents.Actuators;
265
+
266
+ public class PlaytestAgent : Agent
267
+ {
268
+ [Header("References")]
269
+ [SerializeField] private GameManager _gameManager;
270
+
271
+ [Header("Playtest Mode")]
272
+ [SerializeField] private PlaytestMode _mode = PlaytestMode.Explorer;
273
+
274
+ public enum PlaytestMode
275
+ {
276
+ Explorer, // Maximize coverage
277
+ Speedrunner, // Minimize time
278
+ Griefer, // Find exploits
279
+ NewPlayer // Simulate confusion
280
+ }
281
+
282
+ public override void OnEpisodeBegin()
283
+ {
284
+ _gameManager.ResetGame();
285
+ }
286
+
287
+ public override void CollectObservations(VectorSensor sensor)
288
+ {
289
+ // Add game state observations
290
+ sensor.AddObservation(_gameManager.PlayerPosition);
291
+ sensor.AddObservation(_gameManager.PlayerHealth);
292
+ sensor.AddObservation(_gameManager.EnemyPositions);
293
+ sensor.AddObservation(_gameManager.CurrentLevel);
294
+ }
295
+
296
+ public override void OnActionReceived(ActionBuffers actions)
297
+ {
298
+ // Execute action
299
+ int action = actions.DiscreteActions[0];
300
+ var result = _gameManager.ExecuteAction(action);
301
+
302
+ // Reward based on mode
303
+ switch (_mode)
304
+ {
305
+ case PlaytestMode.Explorer:
306
+ AddReward(result.NewStateDiscovered ? 1f : 0f);
307
+ break;
308
+ case PlaytestMode.Speedrunner:
309
+ AddReward(-0.01f); // Penalize time
310
+ AddReward(result.LevelCompleted ? 10f : 0f);
311
+ break;
312
+ case PlaytestMode.Griefer:
313
+ AddReward(result.FoundExploit ? 100f : 0f);
314
+ break;
315
+ }
316
+
317
+ // End episode on game over
318
+ if (result.GameOver)
319
+ {
320
+ LogPlaytestResult(result);
321
+ EndEpisode();
322
+ }
323
+ }
324
+ }
325
+ ```
326
+
327
+ ### Training Configuration
328
+
329
+ ```yaml
330
+ # playtest_agent.yaml
331
+ behaviors:
332
+ PlaytestBot:
333
+ trainer_type: ppo
334
+ hyperparameters:
335
+ batch_size: 1024
336
+ buffer_size: 10240
337
+ learning_rate: 3.0e-4
338
+ beta: 5.0e-3
339
+ epsilon: 0.2
340
+ lambd: 0.95
341
+ num_epoch: 3
342
+ network_settings:
343
+ normalize: true
344
+ hidden_units: 256
345
+ num_layers: 2
346
+ reward_signals:
347
+ extrinsic:
348
+ gamma: 0.99
349
+ strength: 1.0
350
+ max_steps: 5000000
351
+ time_horizon: 128
352
+ summary_freq: 10000
353
+ ```
354
+
355
+ ---
356
+
357
+ ## Godot RL Integration
358
+
359
+ ### GDScript Agent
360
+
361
+ ```gdscript
362
+ # playtest_agent.gd
363
+ extends Node
364
+
365
+ class_name PlaytestAgent
366
+
367
+ enum Mode { RANDOM, EXPLORER, SPEEDRUN, BALANCE }
368
+
369
+ @export var mode: Mode = Mode.EXPLORER
370
+ @export var max_steps: int = 10000
371
+
372
+ var step_count: int = 0
373
+ var visited_states: Dictionary = {}
374
+ var bug_log: Array = []
375
+
376
+ func _ready():
377
+ run_playtest()
378
+
379
+ func run_playtest():
380
+ while step_count < max_steps:
381
+ var state = get_game_state()
382
+ var action = select_action(state)
383
+
384
+ var result = execute_action(action)
385
+
386
+ check_for_issues(result)
387
+
388
+ step_count += 1
389
+
390
+ generate_report()
391
+
392
+ func select_action(state: Dictionary) -> int:
393
+ match mode:
394
+ Mode.RANDOM:
395
+ return randi() % get_action_count()
396
+ Mode.EXPLORER:
397
+ return find_unexplored_action(state)
398
+ Mode.SPEEDRUN:
399
+ return find_fastest_action(state)
400
+ _:
401
+ return 0
402
+
403
+ func check_for_issues(result: Dictionary):
404
+ if result.has("error"):
405
+ bug_log.append({
406
+ "step": step_count,
407
+ "error": result.error,
408
+ "state": get_game_state()
409
+ })
410
+
411
+ if result.get("stuck", false):
412
+ bug_log.append({
413
+ "step": step_count,
414
+ "issue": "Soft lock detected",
415
+ "state": get_game_state()
416
+ })
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Test Reports
422
+
423
+ ### Coverage Report
424
+
425
+ ```markdown
426
+ # Playtest Coverage Report
427
+
428
+ ## Summary
429
+ - **Total States Explored**: 1,247
430
+ - **Estimated Coverage**: 78%
431
+ - **Unique Paths Found**: 342
432
+ - **Test Duration**: 4 hours
433
+
434
+ ## Unexplored Areas
435
+ 1. Level 7 secret room (requires specific item combo)
436
+ 2. Boss phase 3 rage mode (never triggered)
437
+ 3. Multiplayer lobby (not tested)
438
+
439
+ ## Heatmap
440
+ [Generated level heatmap showing visited areas]
441
+
442
+ ## Recommendations
443
+ - Add tutorial hint for secret room
444
+ - Lower boss phase 3 trigger threshold for testing
445
+ ```
446
+
447
+ ### Bug Report
448
+
449
+ ```markdown
450
+ # Automated Bug Report
451
+
452
+ ## Critical (2)
453
+ 1. **Crash at Level 5 Boss**
454
+ - Steps to reproduce: [action log]
455
+ - Stack trace: NullReferenceException at BossAI.cs:147
456
+
457
+ 2. **Soft Lock in Puzzle Room**
458
+ - Trigger: Push both blocks simultaneously
459
+ - Player cannot reset or escape
460
+
461
+ ## High (5)
462
+ 1. Out of bounds at coordinates (145, -20)
463
+ 2. Duplicate reward on rapid retry
464
+ 3. ...
465
+
466
+ ## Medium (12)
467
+ ...
468
+
469
+ ## Low (34)
470
+ ...
471
+ ```
472
+
473
+ ### Balance Report
474
+
475
+ ```markdown
476
+ # Balance Analysis Report
477
+
478
+ ## Dominant Strategies
479
+ | Strategy | Win Rate | Usage | Recommendation |
480
+ |----------|----------|-------|----------------|
481
+ | Spam Attack | 72% | 45% | Reduce attack speed |
482
+ | Corner Camp | 68% | 23% | Add anti-camping mechanic |
483
+
484
+ ## Underused Strategies
485
+ | Strategy | Win Rate | Usage | Recommendation |
486
+ |----------|----------|-------|----------------|
487
+ | Defensive Build | 31% | 5% | Buff shield abilities |
488
+ | Stealth Approach | 28% | 3% | Reduce detection range |
489
+
490
+ ## Difficulty Curve
491
+ [Graph showing expected vs actual difficulty by level]
492
+ - Level 6: Spike detected (35% more deaths than expected)
493
+ - Level 12-14: Too easy (consider adding challenge)
494
+ ```
495
+
496
+ ---
497
+
498
+ ## CI/CD Integration
499
+
500
+ ```yaml
501
+ # .github/workflows/playtest.yml
502
+ name: Automated Playtest
503
+
504
+ on:
505
+ push:
506
+ branches: [main, develop]
507
+ schedule:
508
+ - cron: '0 2 * * *' # Nightly
509
+
510
+ jobs:
511
+ playtest:
512
+ runs-on: ubuntu-latest
513
+ steps:
514
+ - uses: actions/checkout@v4
515
+
516
+ - name: Build Game
517
+ run: |
518
+ unity-builder --target StandaloneLinux64
519
+
520
+ - name: Run Random Bot (30 min)
521
+ run: |
522
+ python scripts/playtest/random_bot.py \
523
+ --duration 1800 \
524
+ --output reports/random_bot.json
525
+
526
+ - name: Run Explorer Bot (1 hour)
527
+ run: |
528
+ python scripts/playtest/explorer_bot.py \
529
+ --target-coverage 0.7 \
530
+ --max-duration 3600 \
531
+ --output reports/explorer.json
532
+
533
+ - name: Run Balance Bot (2 hours)
534
+ run: |
535
+ python scripts/playtest/balance_bot.py \
536
+ --episodes 1000 \
537
+ --output reports/balance.json
538
+
539
+ - name: Generate Report
540
+ run: |
541
+ python scripts/playtest/generate_report.py \
542
+ --inputs reports/*.json \
543
+ --output reports/final_report.md
544
+
545
+ - name: Upload Reports
546
+ uses: actions/upload-artifact@v4
547
+ with:
548
+ name: playtest-reports
549
+ path: reports/
550
+
551
+ - name: Fail on Critical Bugs
552
+ run: |
553
+ python scripts/playtest/check_critical.py reports/final_report.md
554
+ ```
555
+
556
+ ---
557
+
558
+ ## Best Practices
559
+
560
+ | Practice | Why |
561
+ |----------|-----|
562
+ | Run nightly | Catch regressions early |
563
+ | Vary seed values | Different random paths |
564
+ | Combine bot types | Each finds different issues |
565
+ | Track metrics over time | Detect trends |
566
+ | Automate report creation | Reduce manual work |
567
+
568
+ ---
569
+
570
+ > **AI playtesting runs while you sleep.** Wake up to bug reports and balance insights. 🌙