@loonylabs/create-game 0.1.0

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 (166) hide show
  1. package/bin/create-game.js +213 -0
  2. package/package.json +18 -0
  3. package/template/.claude/skills/aigdtk-create-game-stories/SKILL.md +177 -0
  4. package/template/.claude/skills/aigdtk-create-game-stories/story-template.md +85 -0
  5. package/template/.claude/skills/aigdtk-implement-game-stories/SKILL.md +129 -0
  6. package/template/.claude/skills/aigdtk-new-game/SKILL.md +126 -0
  7. package/template/.claude/skills/aigdtk-shared/ascii-grammar.md +133 -0
  8. package/template/.claude/skills/aigdtk-shared/enemies.md +112 -0
  9. package/template/.claude/skills/aigdtk-shared/framework.md +93 -0
  10. package/template/.claude/skills/aigdtk-shared/visuals.md +125 -0
  11. package/template/apps/client/index.html +14 -0
  12. package/template/apps/client/package.json +31 -0
  13. package/template/apps/client/public/assets/audio/enemy_killed.wav +0 -0
  14. package/template/apps/client/src/components/App.svelte +290 -0
  15. package/template/apps/client/src/components/CraftingPanel.svelte +253 -0
  16. package/template/apps/client/src/components/DevPanel.svelte +180 -0
  17. package/template/apps/client/src/components/DungeonClearOverlay.svelte +53 -0
  18. package/template/apps/client/src/components/EquipmentPanel.svelte +191 -0
  19. package/template/apps/client/src/components/HealthBar.svelte +50 -0
  20. package/template/apps/client/src/components/Hub/BackToHubButton.svelte +37 -0
  21. package/template/apps/client/src/components/Hub/ExperienceCard.svelte +115 -0
  22. package/template/apps/client/src/components/Hub/Hub.svelte +88 -0
  23. package/template/apps/client/src/components/Inventory.svelte +174 -0
  24. package/template/apps/client/src/components/Runner/RunnerDeathScreen.svelte +182 -0
  25. package/template/apps/client/src/components/Runner/RunnerHUD.svelte +157 -0
  26. package/template/apps/client/src/components/Shooter/DamageNumbers.svelte +96 -0
  27. package/template/apps/client/src/components/Shooter/GameOverScreen.svelte +109 -0
  28. package/template/apps/client/src/components/Shooter/ShooterHUD.svelte +95 -0
  29. package/template/apps/client/src/components/SkillBar.svelte +146 -0
  30. package/template/apps/client/src/components/ToastSystem.svelte +158 -0
  31. package/template/apps/client/src/game.ts +918 -0
  32. package/template/apps/client/src/input.ts +92 -0
  33. package/template/apps/client/src/lib/audio/CombatDetector.test.ts +59 -0
  34. package/template/apps/client/src/lib/audio/CombatDetector.ts +53 -0
  35. package/template/apps/client/src/lib/audio/MusicManager.ts +137 -0
  36. package/template/apps/client/src/lib/audio/SoundManager.ts +59 -0
  37. package/template/apps/client/src/lib/audio/index.ts +9 -0
  38. package/template/apps/client/src/main.ts +32 -0
  39. package/template/apps/client/src/renderer/basecamp.ts +126 -0
  40. package/template/apps/client/src/renderer/dungeon.ts +250 -0
  41. package/template/apps/client/src/renderer/dungeonPortal.ts +73 -0
  42. package/template/apps/client/src/renderer/dungeonZone.ts +301 -0
  43. package/template/apps/client/src/renderer/entities.ts +197 -0
  44. package/template/apps/client/src/renderer/runnerTrack.ts +221 -0
  45. package/template/apps/client/src/renderer/shaders/SkyShader.ts +190 -0
  46. package/template/apps/client/src/renderer/shaders/TerrainShaderMaterial.ts +133 -0
  47. package/template/apps/client/src/renderer/shaders/floor.frag.glsl.ts +17 -0
  48. package/template/apps/client/src/renderer/shaders/shaderConfig.ts +18 -0
  49. package/template/apps/client/src/renderer/shaders/spawn.frag.glsl.ts +19 -0
  50. package/template/apps/client/src/renderer/shaders/terrain.frag.glsl.ts +314 -0
  51. package/template/apps/client/src/renderer/shaders/terrain.vert.glsl.ts +16 -0
  52. package/template/apps/client/src/renderer/shaders/wall.frag.glsl.ts +20 -0
  53. package/template/apps/client/src/renderer/shooterArena.ts +102 -0
  54. package/template/apps/client/src/renderer/voxelChunkStreamer.ts +79 -0
  55. package/template/apps/client/src/renderer/voxelMesh.ts +86 -0
  56. package/template/apps/client/src/renderer/voxelTerrain.ts +74 -0
  57. package/template/apps/client/src/socket.ts +268 -0
  58. package/template/apps/client/src/store.ts +74 -0
  59. package/template/apps/client/src/style.css +60 -0
  60. package/template/apps/client/tsconfig.json +11 -0
  61. package/template/apps/client/vite.config.ts +10 -0
  62. package/template/apps/client/vitest.config.ts +8 -0
  63. package/template/apps/experiences/diablo/index.ts +94 -0
  64. package/template/apps/experiences/diablo/systems/dungeonClearSystem.ts +60 -0
  65. package/template/apps/experiences/diablo/systems/enemyAISystem.ts +11 -0
  66. package/template/apps/experiences/diablo/systems/entitySyncSystem.ts +80 -0
  67. package/template/apps/experiences/diablo/systems/itemPickupSystem.ts +11 -0
  68. package/template/apps/experiences/diablo/systems/movementSystem.ts +13 -0
  69. package/template/apps/experiences/diablo/systems/physicsSystem.ts +92 -0
  70. package/template/apps/experiences/diablo/systems/transitionSystem.ts +105 -0
  71. package/template/apps/experiences/runner/data/runner-config.ts +54 -0
  72. package/template/apps/experiences/runner/index.ts +143 -0
  73. package/template/apps/experiences/runner/systems/collectibleSystem.ts +157 -0
  74. package/template/apps/experiences/runner/systems/deathSystem.ts +42 -0
  75. package/template/apps/experiences/runner/systems/entitySyncSystem.ts +59 -0
  76. package/template/apps/experiences/runner/systems/obstacleSystem.ts +91 -0
  77. package/template/apps/experiences/runner/systems/runnerPhysicsSystem.ts +82 -0
  78. package/template/apps/experiences/runner/systems/trackStreamSystem.ts +19 -0
  79. package/template/apps/experiences/runner/track/laneSystem.ts +53 -0
  80. package/template/apps/experiences/runner/track/segmentTypes.ts +141 -0
  81. package/template/apps/experiences/runner/track/trackGenerator.ts +292 -0
  82. package/template/apps/experiences/shooter/ai/aiStateMachine.ts +394 -0
  83. package/template/apps/experiences/shooter/ai/lineOfSight.ts +32 -0
  84. package/template/apps/experiences/shooter/arena/arenaGenerator.ts +101 -0
  85. package/template/apps/experiences/shooter/arena/arenaTypes.ts +49 -0
  86. package/template/apps/experiences/shooter/arena/hitscan.ts +101 -0
  87. package/template/apps/experiences/shooter/data/enemy-types.ts +108 -0
  88. package/template/apps/experiences/shooter/data/wave-definitions.ts +40 -0
  89. package/template/apps/experiences/shooter/data/weapon-config.ts +80 -0
  90. package/template/apps/experiences/shooter/index.ts +127 -0
  91. package/template/apps/experiences/shooter/systems/enemyAISystem.ts +113 -0
  92. package/template/apps/experiences/shooter/systems/entitySyncSystem.ts +68 -0
  93. package/template/apps/experiences/shooter/systems/shooterPhysicsSystem.ts +89 -0
  94. package/template/apps/experiences/shooter/systems/waveSpawnerSystem.ts +87 -0
  95. package/template/apps/experiences/shooter/systems/weaponSystem.ts +157 -0
  96. package/template/apps/game-data/src/areas/area-manifest.json +18 -0
  97. package/template/apps/game-data/src/assets/migration.test.ts +291 -0
  98. package/template/apps/game-data/src/audio/music-config.json +21 -0
  99. package/template/apps/game-data/src/audio/sound-config.json +11 -0
  100. package/template/apps/game-data/src/combat/action-types.ts +2 -0
  101. package/template/apps/game-data/src/combat/enemy-def.ts +12 -0
  102. package/template/apps/game-data/src/combat/hitboxes.ts +23 -0
  103. package/template/apps/game-data/src/dungeon/cell-types.ts +20 -0
  104. package/template/apps/game-data/src/dungeon/cell-visuals.ts +13 -0
  105. package/template/apps/game-data/src/dungeon/door-directions.ts +2 -0
  106. package/template/apps/game-data/src/enemies/enemy-defs.json +32 -0
  107. package/template/apps/game-data/src/equipment/slots.json +5 -0
  108. package/template/apps/game-data/src/events/event-defs.ts +20 -0
  109. package/template/apps/game-data/src/events/event-types.ts +10 -0
  110. package/template/apps/game-data/src/events/toast-config.json +49 -0
  111. package/template/apps/game-data/src/items/item-pool.json +13 -0
  112. package/template/apps/game-data/src/loot/item-pool.ts +14 -0
  113. package/template/apps/game-data/src/loot/rarities.ts +2 -0
  114. package/template/apps/game-data/src/physics/dungeon-physics-config.ts +12 -0
  115. package/template/apps/game-data/src/physics/jump-config.ts +17 -0
  116. package/template/apps/game-data/src/recipes/recipe-book.json +68 -0
  117. package/template/apps/game-data/src/rooms/room_basecamp.json +16 -0
  118. package/template/apps/game-data/src/rooms/room_corridor_ew.json +9 -0
  119. package/template/apps/game-data/src/rooms/room_corridor_ns.json +11 -0
  120. package/template/apps/game-data/src/rooms/room_crossroads.json +11 -0
  121. package/template/apps/game-data/src/rooms/room_dead_end.json +10 -0
  122. package/template/apps/game-data/src/rooms/room_staircase.json +12 -0
  123. package/template/apps/game-data/src/rooms/room_start.json +11 -0
  124. package/template/apps/game-data/src/skills/skill-book.json +20 -0
  125. package/template/apps/game-data/src/voxel/biome-terrain.ts +76 -0
  126. package/template/apps/game-data/src/voxel/materials.ts +45 -0
  127. package/template/apps/game-data/src/voxel/sandbox-terrain-config.ts +19 -0
  128. package/template/apps/game-data/src/world/area-config.ts +33 -0
  129. package/template/apps/game-data/src/world/biome-def.ts +15 -0
  130. package/template/apps/game-data/src/world/biomes.json +57 -0
  131. package/template/apps/game-data/src/world/movement.ts +2 -0
  132. package/template/apps/game-data/src/world/overworld-layout.test.ts +93 -0
  133. package/template/apps/game-data/src/world/overworld-layout.ts +127 -0
  134. package/template/apps/server/data/game.db +0 -0
  135. package/template/apps/server/package.json +30 -0
  136. package/template/apps/server/src/areaManager.ts +346 -0
  137. package/template/apps/server/src/db/client.ts +45 -0
  138. package/template/apps/server/src/db/schema.ts +40 -0
  139. package/template/apps/server/src/gameLoop.ts +267 -0
  140. package/template/apps/server/src/gameState.ts +3 -0
  141. package/template/apps/server/src/handlers/actionEvent.ts +55 -0
  142. package/template/apps/server/src/handlers/craftHandler.ts +59 -0
  143. package/template/apps/server/src/handlers/equipHandler.ts +73 -0
  144. package/template/apps/server/src/handlers/raycastHandler.ts +97 -0
  145. package/template/apps/server/src/handlers/skillHandler.ts +87 -0
  146. package/template/apps/server/src/handlers/terraformHandler.ts +74 -0
  147. package/template/apps/server/src/index.ts +597 -0
  148. package/template/apps/server/src/persistence.ts +135 -0
  149. package/template/apps/server/src/rooms.ts +20 -0
  150. package/template/apps/server/src/systems/dungeonPhysics.test.ts +32 -0
  151. package/template/apps/server/src/systems/dungeonPhysics.ts +16 -0
  152. package/template/apps/server/src/systems/enemyAI.ts +129 -0
  153. package/template/apps/server/src/systems/itemPickup.ts +31 -0
  154. package/template/apps/server/src/tests/areaManager.test.ts +77 -0
  155. package/template/apps/server/src/tests/diablo-experience.test.ts +60 -0
  156. package/template/apps/server/src/tests/runner-experience.test.ts +273 -0
  157. package/template/apps/server/src/tests/runner-powerups-scoring.test.ts +221 -0
  158. package/template/apps/server/src/tests/server.integration.test.ts +92 -0
  159. package/template/apps/server/src/tests/shooter-enemy-ai.test.ts +328 -0
  160. package/template/apps/server/src/tests/shooter-experience.test.ts +281 -0
  161. package/template/apps/server/src/tests/voxelChunkCache.test.ts +29 -0
  162. package/template/apps/server/src/tests/voxelSandbox.test.ts +133 -0
  163. package/template/apps/server/src/voxelChunkCache.ts +31 -0
  164. package/template/apps/server/src/voxelPlayerState.ts +23 -0
  165. package/template/apps/server/tsconfig.json +17 -0
  166. package/template/apps/server/vitest.config.ts +8 -0
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * create-game.js — Scaffold a new game project from @loonylabs/create-game templates.
4
+ *
5
+ * Usage:
6
+ * npx @loonylabs/create-game <game-name> <target-dir>
7
+ *
8
+ * Example:
9
+ * npx @loonylabs/create-game shadow-dungeon ~/Desktop/shadow-dungeon
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import { fileURLToPath } from 'url';
15
+
16
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
+ const TEMPLATE_DIR = path.resolve(__dirname, '..', 'template');
18
+ const FRAMEWORK_VERSION = '0.1.0';
19
+
20
+ // ─── Args ────────────────────────────────────────────────────────────────────
21
+
22
+ const [, , gameName, targetDir] = process.argv;
23
+
24
+ if (!gameName || !targetDir) {
25
+ console.error('Usage: npx @loonylabs/create-game <game-name> <target-dir>');
26
+ process.exit(1);
27
+ }
28
+
29
+ const target = path.resolve(targetDir);
30
+ const gameDataPackage = `@${gameName}/game-data`;
31
+
32
+ if (fs.existsSync(target)) {
33
+ console.error(`Error: Target directory already exists: ${target}`);
34
+ process.exit(1);
35
+ }
36
+
37
+ console.log(`\n🎮 Creating game project: ${gameName}`);
38
+ console.log(` Target: ${target}\n`);
39
+
40
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
41
+
42
+ const SKIP_DIRS = new Set(['node_modules', 'dist', '.turbo', '.git']);
43
+
44
+ function copyDir(src, dest, transformFn = null) {
45
+ fs.mkdirSync(dest, { recursive: true });
46
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
47
+ if (SKIP_DIRS.has(entry.name)) continue;
48
+ const srcPath = path.join(src, entry.name);
49
+ const destPath = path.join(dest, entry.name);
50
+ const stat = fs.statSync(srcPath);
51
+ if (stat.isDirectory()) {
52
+ copyDir(srcPath, destPath, transformFn);
53
+ } else if (stat.isFile()) {
54
+ let content = fs.readFileSync(srcPath);
55
+ if (transformFn && (srcPath.endsWith('.json') || srcPath.endsWith('.ts') || srcPath.endsWith('.js') || srcPath.endsWith('.md') || srcPath.endsWith('.svelte') || srcPath.endsWith('.html'))) {
56
+ content = Buffer.from(transformFn(content.toString(), srcPath));
57
+ }
58
+ fs.writeFileSync(destPath, content);
59
+ }
60
+ }
61
+ }
62
+
63
+ function writeJson(filePath, obj) {
64
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
65
+ fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + '\n');
66
+ }
67
+
68
+ function writeText(filePath, text) {
69
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
70
+ fs.writeFileSync(filePath, text);
71
+ }
72
+
73
+ // ─── Step 1: Root config files ───────────────────────────────────────────────
74
+
75
+ console.log('📁 Creating project structure...');
76
+
77
+ writeJson(path.join(target, 'package.json'), {
78
+ name: gameName,
79
+ private: true,
80
+ type: 'module',
81
+ scripts: {
82
+ dev: 'turbo dev --ui=stream',
83
+ build: 'turbo build',
84
+ test: 'turbo test',
85
+ },
86
+ packageManager: 'pnpm@10.30.2',
87
+ devDependencies: {
88
+ turbo: 'latest',
89
+ typescript: '^5.0.0',
90
+ },
91
+ engines: { node: '>=18.0.0', pnpm: '>=8.0.0' },
92
+ pnpm: { onlyBuiltDependencies: ['better-sqlite3', 'esbuild'] },
93
+ });
94
+
95
+ writeText(path.join(target, 'pnpm-workspace.yaml'), 'packages:\n - \'apps/*\'\n');
96
+
97
+ writeJson(path.join(target, 'turbo.json'), {
98
+ $schema: 'https://turbo.build/schema.json',
99
+ tasks: {
100
+ build: { dependsOn: ['^build'], outputs: ['dist/**'] },
101
+ dev: { persistent: true, cache: false },
102
+ test: { dependsOn: ['^build'] },
103
+ },
104
+ });
105
+
106
+ writeText(path.join(target, '.gitignore'),
107
+ 'node_modules/\ndist/\n.turbo/\n*.db\n*.db-shm\n*.db-wal\n');
108
+
109
+ writeText(path.join(target, '.npmrc'),
110
+ 'public-hoist-pattern[]=@loonylabs/*\n');
111
+
112
+ // ─── Step 2: game-data app ───────────────────────────────────────────────────
113
+
114
+ console.log('📦 Copying game-data...');
115
+
116
+ copyDir(
117
+ path.join(TEMPLATE_DIR, 'apps', 'game-data', 'src'),
118
+ path.join(target, 'apps', 'game-data', 'src')
119
+ );
120
+
121
+ writeJson(path.join(target, 'apps', 'game-data', 'package.json'), {
122
+ name: gameDataPackage,
123
+ version: '0.1.0',
124
+ type: 'module',
125
+ private: true,
126
+ exports: { '.': './src/index.ts' },
127
+ dependencies: {
128
+ '@loonylabs/gamedev-core': FRAMEWORK_VERSION,
129
+ },
130
+ });
131
+
132
+ // ─── Step 3: client app ──────────────────────────────────────────────────────
133
+
134
+ console.log('🖥️ Copying client app...');
135
+
136
+ function transformClientDeps(content, filePath) {
137
+ if (!filePath.endsWith('package.json')) return content;
138
+ const pkg = JSON.parse(content);
139
+ if (pkg.dependencies?.['@loonylabs/game-data']) {
140
+ pkg.dependencies[gameDataPackage] = 'workspace:*';
141
+ delete pkg.dependencies['@loonylabs/game-data'];
142
+ }
143
+ for (const key of ['@loonylabs/gamedev-core', '@loonylabs/gamedev-client', '@loonylabs/gamedev-server', '@loonylabs/gamedev-protocol']) {
144
+ if (pkg.dependencies?.[key]) pkg.dependencies[key] = FRAMEWORK_VERSION;
145
+ if (pkg.devDependencies?.[key]) pkg.devDependencies[key] = FRAMEWORK_VERSION;
146
+ }
147
+ return JSON.stringify(pkg, null, 2) + '\n';
148
+ }
149
+
150
+ function transformImports(content, filePath) {
151
+ if (filePath.endsWith('package.json')) return transformClientDeps(content, filePath);
152
+ let result = content;
153
+ result = result.replaceAll('gamedev-ai-toolkit', gameName);
154
+ result = result.replaceAll('@loonylabs/game-data', gameDataPackage);
155
+ result = result.replace(/['"](?:\.\.\/)+packages\/core\/src\/[^'"]+['"]/g, "'@loonylabs/gamedev-core'");
156
+ result = result.replace(/['"](?:\.\.\/)+packages\/server\/src\/[^'"]+['"]/g, "'@loonylabs/gamedev-server'");
157
+ result = result.replace(/['"](?:\.\.\/)+packages\/client\/src\/[^'"]+['"]/g, "'@loonylabs/gamedev-client'");
158
+ return result;
159
+ }
160
+
161
+ copyDir(
162
+ path.join(TEMPLATE_DIR, 'apps', 'client'),
163
+ path.join(target, 'apps', 'client'),
164
+ transformImports
165
+ );
166
+
167
+ // ─── Step 4: server app ──────────────────────────────────────────────────────
168
+
169
+ console.log('🖥️ Copying server app...');
170
+
171
+ copyDir(
172
+ path.join(TEMPLATE_DIR, 'apps', 'server'),
173
+ path.join(target, 'apps', 'server'),
174
+ transformImports
175
+ );
176
+
177
+ // ─── Step 4b: experiences ────────────────────────────────────────────────────
178
+
179
+ console.log('🗺️ Copying experiences...');
180
+
181
+ copyDir(
182
+ path.join(TEMPLATE_DIR, 'apps', 'experiences'),
183
+ path.join(target, 'apps', 'experiences'),
184
+ transformImports
185
+ );
186
+
187
+ // ─── Step 5: aigdtk skills ───────────────────────────────────────────────────
188
+
189
+ console.log('🤖 Copying aigdtk skills...');
190
+
191
+ const skillsToCopy = ['aigdtk-new-game', 'aigdtk-create-game-stories', 'aigdtk-implement-game-stories', 'aigdtk-shared'];
192
+ for (const skill of skillsToCopy) {
193
+ const src = path.join(TEMPLATE_DIR, '.claude', 'skills', skill);
194
+ if (fs.existsSync(src)) {
195
+ copyDir(src, path.join(target, '.claude', 'skills', skill));
196
+ }
197
+ }
198
+
199
+ // ─── Done ────────────────────────────────────────────────────────────────────
200
+
201
+ console.log(`
202
+ ✅ Game project created: ${gameName}
203
+
204
+ Next steps:
205
+ cd ${target}
206
+ pnpm install
207
+ pnpm dev
208
+
209
+ Then open http://localhost:3200 in your browser.
210
+
211
+ To start building your game with AI:
212
+ /aigdtk-new-game
213
+ `);
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@loonylabs/create-game",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "create-game": "./bin/create-game.js"
7
+ },
8
+ "files": [
9
+ "bin",
10
+ "template"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "engines": {
16
+ "node": ">=18.0.0"
17
+ }
18
+ }
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: aigdtk-create-game-stories
3
+ description: Creates implementation-ready game stories from a saved Game Brief. Run after /aigdtk-new-game in a new session.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Create Game Stories
8
+
9
+ ## Supporting files (shared knowledge base)
10
+ - Framework reference: [../aigdtk-shared/framework.md](../aigdtk-shared/framework.md)
11
+ - ASCII room grammar: [../aigdtk-shared/ascii-grammar.md](../aigdtk-shared/ascii-grammar.md)
12
+ - Enemy definitions reference: [../aigdtk-shared/enemies.md](../aigdtk-shared/enemies.md)
13
+ - Cell visuals / palettes: [../aigdtk-shared/visuals.md](../aigdtk-shared/visuals.md)
14
+
15
+ <activation CRITICAL="TRUE">
16
+ You are now in game story generation mode. Your role is **technical architect**.
17
+ You translate a developer's game vision into implementation-ready stories.
18
+
19
+ ## NON-NEGOTIABLE RULES
20
+
21
+ 1. **NEVER ask technical questions** to the developer.
22
+ 2. **NEVER ask the developer to make technical decisions.** You decide everything.
23
+ 3. **Ask only if something is genuinely ambiguous about the game vision** — and only
24
+ product-level questions (e.g. "Should the second area feel like an overworld or
25
+ another dungeon?"), never technical ones.
26
+ 4. **Generate complete, ready-to-implement stories** — no placeholders, no TODOs
27
+ in acceptance criteria, no "TBD" in technical specs.
28
+
29
+ ---
30
+
31
+ ## STEP 1 — Read the Game Brief
32
+
33
+ Read `docs/aigdtk/game-brief.md` now.
34
+
35
+ If the file does not exist, stop and tell the developer:
36
+ > "Kein Game Brief gefunden. Bitte starte zuerst mit `/aigdtk-new-game`."
37
+
38
+ ---
39
+
40
+ ## STEP 2 — Read framework reference and derive area type
41
+
42
+ Read `../aigdtk-shared/framework.md`.
43
+
44
+ From the Game Brief's Core Loop and Happy When, decide:
45
+ - **Area type**: `dungeon` (room-based exploration/combat) or `voxel` (open world) or both
46
+ - **Number of rooms**: 2–3 minimal, 4–6 if the Happy When demands more variety
47
+ - **Number of enemy types**: 1 base + 1–2 variants minimum
48
+
49
+ Do NOT ask — decide.
50
+
51
+ ---
52
+
53
+ ## STEP 3 — Read enemy reference and derive enemy definitions
54
+
55
+ Read `../aigdtk-shared/enemies.md`.
56
+
57
+ Generate complete enemy stats for:
58
+ - The enemy described in the Game Brief (map description to archetype)
59
+ - 1–2 additional variants (one easier, one harder — or a boss if Happy When mentions it)
60
+
61
+ Derive color from description keywords using the color table in enemies.md.
62
+
63
+ ---
64
+
65
+ ## STEP 4 — Read ASCII grammar and plan rooms
66
+
67
+ Read `../aigdtk-shared/ascii-grammar.md`.
68
+
69
+ Plan the room set:
70
+ - 1 start room (with `S`, `tags: ["start"]`)
71
+ - 1–2 combat rooms with doors
72
+ - 1 special room if Happy When mentions a goal (boss, loot, exit)
73
+
74
+ Draft the ASCII layouts mentally — they go in the stories.
75
+
76
+ ---
77
+
78
+ ## STEP 5 — Read visuals reference and derive palette
79
+
80
+ Read `../aigdtk-shared/visuals.md`.
81
+
82
+ Pick or compose a color palette that fits the reference game + enemy description.
83
+ Derive all 7 `GameCellType` colors and heights. Do not leave any unset.
84
+
85
+ ---
86
+
87
+ ## STEP 6 — Derive story prefix
88
+
89
+ From the game name, derive a short prefix:
90
+ - Take first letter of each word, lowercase
91
+ - Examples: "Shadow Dungeon" → `sd`, "Bone Crawler" → `bc`, "The Last Keeper" → `tlk`
92
+ - If the result is less than 2 chars, use first 2–3 letters of the first word
93
+
94
+ ---
95
+
96
+ ## STEP 7 — Write the stories
97
+
98
+ Write 2–3 stories to `docs/stories/`.
99
+ **Do NOT read any existing files in `docs/stories/`.**
100
+
101
+ Use `story-template.md` (in this skill's directory) as the format reference.
102
+ Read it now and follow it exactly for every story you write.
103
+
104
+ ### Story 1: `[prefix]01_enemies-and-visuals.md`
105
+
106
+ **Scope**: Generate and write `enemy-defs.json` + `cell-visuals.ts`
107
+
108
+ Technical spec must include:
109
+ - Complete `enemy-defs.json` array with all enemy objects (filled, not placeholder)
110
+ - Complete `cell-visuals.ts` with all 7 cell types and derived colors/heights
111
+
112
+ Task list:
113
+ - [ ] Write `apps/game-data/src/enemies/enemy-defs.json`
114
+ - [ ] Write `apps/game-data/src/dungeon/cell-visuals.ts`
115
+ - [ ] Run `pnpm test:changed` — all green
116
+ - [ ] Lessons Learned ausfüllen
117
+ - [ ] Handover für Story 2 schreiben
118
+
119
+ ### Story 2: `[prefix]02_rooms-and-areas.md`
120
+
121
+ **Scope**: Generate and write `room_*.json` files + `area-manifest.json`
122
+
123
+ Technical spec must include:
124
+ - All planned room files with complete ASCII layouts (filled, valid per ascii-grammar.md rules)
125
+ - Complete `area-manifest.json` with correct area type
126
+
127
+ Task list:
128
+ - [ ] Write `apps/game-data/src/rooms/room_start.json`
129
+ - [ ] Write `apps/game-data/src/rooms/room_combat.json` (and others if planned)
130
+ - [ ] Write `apps/game-data/src/areas/area-manifest.json`
131
+ - [ ] Run `pnpm test:changed` — all green
132
+ - [ ] Run `pnpm dev` und prüfen ob Welt sichtbar ist
133
+ - [ ] Lessons Learned ausfüllen
134
+ - [ ] Handover schreiben (oder "Fertig" wenn keine weitere Story)
135
+
136
+ ### Story 3 (optional): `[prefix]03_[topic].md`
137
+
138
+ Only create if the developer's "Happy When" requires it (e.g. boss room, second area, transitions).
139
+
140
+ ---
141
+
142
+ ## STEP 8 — Update Derived Decisions in Game Brief
143
+
144
+ Append to the `## Derived Decisions` section of `docs/aigdtk/game-brief.md`:
145
+
146
+ ```markdown
147
+ ## Derived Decisions
148
+
149
+ _Filled by /aigdtk-create-game-stories_
150
+
151
+ - **Area type:** [dungeon / voxel / both]
152
+ - **Color palette:** [mood name]
153
+ - **Enemy archetypes:** [list]
154
+ - **Rooms planned:** [count + types]
155
+ - **Story prefix:** [prefix]
156
+ - **Stories created:** [prefix]01, [prefix]02, ...
157
+ ```
158
+
159
+ ---
160
+
161
+ ## STEP 9 — Handover message
162
+
163
+ Output:
164
+
165
+ ```
166
+ ✅ [N] Stories erstellt unter docs/stories/
167
+
168
+ - [prefix]01_enemies-and-visuals.md
169
+ - [prefix]02_rooms-and-areas.md
170
+ [- prefix03_... falls erstellt]
171
+
172
+ Starte eine neue Claude Code Session und führe aus:
173
+
174
+ /aigdtk-implement-game-stories docs/stories/[prefix]01_enemies-and-visuals.md docs/stories/[prefix]02_rooms-and-areas.md
175
+ ```
176
+
177
+ </activation>
@@ -0,0 +1,85 @@
1
+ # Story [N]: [Title]
2
+
3
+ **Feature**: [Feature Name]
4
+ **Type**: New Feature
5
+ **Estimated Effort**: 1 Session (~3-4h)
6
+ **Dependencies**: Story [N-1] or "None"
7
+
8
+ ---
9
+
10
+ ## Context & Background
11
+
12
+ ### The Problem
13
+ [1-2 sentences: what is missing or broken]
14
+
15
+ ### The Solution
16
+ [1-2 sentences: what this story builds]
17
+
18
+ ---
19
+
20
+ ## Acceptance Criteria
21
+
22
+ ### ✅ Definition of Done
23
+
24
+ #### [Category, e.g. Enemies]
25
+ - [ ] [Concrete, verifiable criterion]
26
+ - [ ] [Concrete, verifiable criterion]
27
+
28
+ #### [Category, e.g. Visuals]
29
+ - [ ] [Concrete, verifiable criterion]
30
+
31
+ ---
32
+
33
+ ## Technical Specification
34
+
35
+ ### [File: path/to/file.json]
36
+
37
+ ```json
38
+ // Complete file contents — no placeholders
39
+ ```
40
+
41
+ ### [File: path/to/file.ts]
42
+
43
+ ```typescript
44
+ // Complete file contents — no placeholders
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Task List
50
+
51
+ - [ ] Write [file 1]
52
+ - [ ] Write [file 2]
53
+ - [ ] Run `pnpm test:changed` — all green
54
+ - [ ] **Lessons Learned ausfüllen**
55
+ - [ ] **Handover für Follow-up Story schreiben**
56
+
57
+ ---
58
+
59
+ ## Lessons Learned
60
+
61
+ <!-- FILL IN AFTER IMPLEMENTATION -->
62
+
63
+ ### What went well
64
+
65
+ ### Architecture decisions
66
+
67
+ ### Important files created/changed
68
+
69
+ ### Open items for follow-up
70
+
71
+ ---
72
+
73
+ ## Handover for Follow-up Story
74
+
75
+ <!-- FILL IN AFTER IMPLEMENTATION -->
76
+
77
+ ### Context Summary
78
+
79
+ ### Relevant files to read
80
+
81
+ ### Start prompt for next story
82
+
83
+ ---
84
+
85
+ **End of Story [N]**
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: aigdtk-implement-game-stories
3
+ description: Implements game stories generated by /aigdtk-create-game-stories. Pass story file paths as arguments.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Implement Game Stories
8
+
9
+ $ARGUMENTS
10
+
11
+ ---
12
+
13
+ <activation CRITICAL="TRUE">
14
+ You are now in game implementation mode. Your role is **developer executing stories**.
15
+ Implement exactly ONE story per session. Stop after completing it.
16
+
17
+ ## SETUP — Branch check
18
+
19
+ Check the current git branch. If on `master` or `main`:
20
+ - Create a new branch: `git checkout -b game/[game-name]-implementation`
21
+ - Tell the developer which branch was created
22
+
23
+ ---
24
+
25
+ ## STEP 1 — Read all stories
26
+
27
+ Read ALL story files passed as arguments in `$ARGUMENTS` completely:
28
+ - Read every section including Lessons Learned and Handover (may contain prior context)
29
+ - Note which tasks are already checked off
30
+ - Identify the **first story with incomplete tasks** — that is the one to implement
31
+
32
+ If no story files are passed, look for story files in `docs/stories/` that match a game prefix
33
+ (non-`ng` and non-`cb` prefixes). If ambiguous, ask the developer which to implement.
34
+
35
+ ---
36
+
37
+ ## STEP 2 — Implement the story
38
+
39
+ Implement **only the identified story** — do not touch the next story.
40
+
41
+ During implementation:
42
+ - Check off each task in the story file as you complete it (`- [ ]` → `- [x]`)
43
+ - All game content files go into `apps/game-data/src/` — never anywhere else
44
+ - Do not modify framework code (`packages/`, `apps/client/`, `apps/server/`, `apps/protocol/`)
45
+ - Use the technical spec in the story as the source of truth for file contents
46
+
47
+ ### Game content file locations
48
+
49
+ | Content | Path |
50
+ |---------|------|
51
+ | Enemy definitions | `apps/game-data/src/enemies/enemy-defs.json` |
52
+ | Room files | `apps/game-data/src/rooms/room_*.json` |
53
+ | Area manifest | `apps/game-data/src/areas/area-manifest.json` |
54
+ | Cell visuals | `apps/game-data/src/dungeon/cell-visuals.ts` |
55
+
56
+ ---
57
+
58
+ ## STEP 3 — Run tests
59
+
60
+ Run: `pnpm test:changed`
61
+
62
+ - If all green: proceed to commit
63
+ - If tests fail: fix the issue first, then re-run. Do not commit with failing tests.
64
+
65
+ ---
66
+
67
+ ## STEP 4 — Commit
68
+
69
+ Create a commit with:
70
+ ```
71
+ feat([game-name]): implement [story name] — [short description]
72
+
73
+ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74
+ ```
75
+
76
+ ---
77
+
78
+ ## STEP 5 — Fill in Lessons Learned and Handover
79
+
80
+ In the story file, fill in:
81
+
82
+ ### Lessons Learned
83
+ - What went well
84
+ - Architecture decisions (with reasoning)
85
+ - Technical debt or workarounds
86
+ - Important files created/changed
87
+
88
+ ### Handover for Follow-up Story
89
+ - Context summary (2–3 sentences)
90
+ - Relevant files to read
91
+ - Start prompt for next story (copy-paste ready `/aigdtk-implement-game-stories [next-path]`)
92
+
93
+ ---
94
+
95
+ ## STEP 6 — Completion report
96
+
97
+ Output a compact report:
98
+
99
+ ```
100
+ ## Story abgeschlossen: [Story Name]
101
+
102
+ **Was wurde gebaut:**
103
+ - [Punkt 1]
104
+ - [Punkt 2]
105
+ - [Punkt 3]
106
+
107
+ **Geänderte Dateien:**
108
+ - [Datei 1]
109
+ - [Datei 2]
110
+
111
+ **Tests:** pnpm test:changed — ✅ alle grün
112
+ **Commit:** [commit hash / message]
113
+
114
+ **Manuell testen:**
115
+ pnpm dev → http://localhost:5173
116
+ [Was der Dev konkret prüfen soll]
117
+
118
+ **Nächste Story:**
119
+ /aigdtk-implement-game-stories [next-story-path]
120
+ ```
121
+
122
+ ---
123
+
124
+ ## STEP 7 — STOP
125
+
126
+ **Stop here.** Do NOT implement the next story automatically.
127
+ The developer decides when and whether to continue.
128
+
129
+ </activation>