--- name: implement-game description: Implements a game from its architecture document using strict TDD. Use after architect-game produces an architecture doc. --- # Implement Game — Architecture to Code Pipeline ## Prerequisites - A completed architecture doc at `docs/plans/{game-name}-architecture.md` - **MCP bridge must be configured and connected** — `.mcp.json` must exist with correct paths (set up by clone-game Step 0b) - **Unity editor must be open** with the project loaded — MCP communicates with the running editor - Load these skills before writing any code: - `code-style` — naming, explicit types, attributes, braces, async rules - `patterns` — Config+Data, service pattern, installer pattern, MessagePipe events, reactive disposal - `testing` — TDD mandate, NUnit + NSubstitute patterns, MockFactory, Assert.That syntax - Module skills for every reused package (e.g., `wallet-module`, `stats-module`, `pool-module`, etc.) ## Code Rules (Non-Negotiable) These rules apply to ALL code written during implementation: | Rule | Correct | Forbidden | |------|---------|-----------| | No `var` | `List items = new();` | `var items = new List();` | | UniTask only | `async UniTask DoAsync(CancellationToken ct)` | `async Task`, `IEnumerator`, coroutines | | R3 Observable | `ReactiveProperty`, `Observable` | UniRx, `Subject` from UniRx | | MessagePipe | `IPublisher`, `ISubscriber` | `UnityEvent`, `Action` for domain events | | VContainer | `[Inject]`, constructor injection | Zenject, `FindObjectOfType`, singletons | | One attribute per line | See code-style skill | Chained `[A, B]` or `[A][B]` | | Data structs | `public` fields + extension methods | Properties, methods on data structs | | Explicit visibility | `private int _count;` | `int _count;` | ## Process ### Step 0: Verify MCP Connection Before writing any code, verify the MCP bridge is running and the Unity editor is reachable: 1. Check `.mcp.json` exists with valid paths 2. Call `execute_editor_method` to confirm connection: - Get Unity version: `Application.unityVersion` - Get project name: `Application.productName` 3. If the connection fails, **STOP** and tell the user: > "MCP bridge is not connected. Please: > 1. Open the Unity project in the editor > 2. Restart Claude Code so the MCP server connects > 3. Run `/implement-game` again" **Do NOT proceed with any implementation if MCP is not connected.** MCP is required for scene creation, prefab setup, material assignment, and test execution. ### Step 1: Read Architecture Doc Read the architecture document and extract the implementation order. The order is always: 1. Data structs and configs (no dependencies) 2. Models and containers 3. Service interfaces 4. Tests for services (write FIRST) 5. Service implementations (make tests pass) 6. ViewModels 7. Views (MonoBehaviours) 8. Installers 9. Scenes ### Step 2: Implement Per Module (TDD) For each new module in dependency order, follow this strict cycle: #### 2a. Create Data + Config ```csharp // Data struct — pure data, public fields, no methods [Serializable] public struct SpawnerConfigData { public float spawnInterval; public int maxEnemies; public float difficultyScaling; } // Config SO — thin wrapper [CreateAssetMenu(menuName = "Game/{GameName}/Spawner Config")] public sealed class SpawnerConfig : ScriptableObject { public SpawnerConfigData data; } // Extension methods — logic lives here public static class SpawnerConfigDataExtensions { public static float GetScaledInterval(this SpawnerConfigData data, int wave) { return data.spawnInterval / (1f + data.difficultyScaling * wave); } } ``` #### 2b. Define Service Interface ```csharp public interface ISpawnerService { ReadOnlyReactiveProperty ActiveCount { get; } ReadOnlyReactiveProperty CurrentWave { get; } void StartSpawning(); void StopSpawning(); } ``` #### 2c. Write Tests FIRST (Red Phase) Write comprehensive tests BEFORE the implementation exists: ```csharp [TestFixture] public sealed class SpawnerServiceTests { private IPoolService _mockPool; private IPublisher _mockPublisher; private SpawnerConfig _config; private SpawnerService _service; [SetUp] public void SetUp() { _mockPool = Substitute.For(); _mockPublisher = Substitute.For>(); _config = ScriptableObject.CreateInstance(); _config.data = new SpawnerConfigData { spawnInterval = 1f, maxEnemies = 10, difficultyScaling = 0.1f }; _service = new SpawnerService(_config, _mockPool, _mockPublisher); } [Test] public void Constructor_NullConfig_ThrowsArgumentNullException() { Assert.Throws(() => new SpawnerService(null, _mockPool, _mockPublisher)); } [Test] public void ActiveCount_InitialState_ReturnsZero() { Assert.That(_service.ActiveCount.CurrentValue, Is.EqualTo(0)); } [Test] public void StartSpawning_Called_BeginsWaveOne() { _service.StartSpawning(); Assert.That(_service.CurrentWave.CurrentValue, Is.EqualTo(1)); } } ``` #### 2d. Implement Service (Green Phase) Write minimal code to make all tests pass. Follow the service pattern from the `patterns` skill. #### 2e. Refactor (Refactor Phase) Clean up while keeping tests green. Ensure code-style compliance. ### Step 3: Wire Installers Create static installer for each module: ```csharp public static class SpawnerInstaller { public static void Install( IContainerBuilder builder, MessagePipeOptions options, SpawnerConfig config = null) { builder.RegisterEntryPoint() .As(); if (config) { builder.RegisterInstance(config); } builder.RegisterMessageBroker(options); builder.RegisterMessageBroker(options); } } ``` ### Step 4: Create Scenes via MCP Use MCP tools to set up scenes in the Unity editor — do NOT create scenes manually or skip this step. Set up scenes per the architecture doc's scene graph: 1. **Create scenes** via `execute_editor_method`: - BOOTSTRAP scene with `ProjectLifetimeScope` - MAINMENU scene with `MainMenuLifetimeScope` - GAMEPLAY scene with `GameplayLifetimeScope` 2. **Create GameObjects** via `execute_editor_method`: - LifetimeScope root objects in each scene - Camera rigs (use `create_light` for initial directional light) - UI Canvas / UIDocument roots - Spawn points, trigger zones, and other level geometry 3. **Create prefabs** via `execute_editor_method`: - For each entry in the architecture doc's Prefab Plan - Add required components (Rigidbody, Collider, View scripts) - Configure pooled prefabs with appropriate initial counts 4. **Create placeholder materials** via MCP material tools: - `create_material` with URP/Lit or URP/Unlit for each entity type - `set_material_property` — assign distinct colors from GDD palette so entities are visually distinguishable during development - `assign_material` to prefab renderers 5. **Set up basic lighting** via MCP lighting tools: - `create_light` — directional light matching GDD art direction - `set_environment_lighting` — ambient color, skybox 6. **Add scenes to Build Settings** via `execute_editor_method`: - BOOTSTRAP at index 0 - MAINMENU at index 1 - GAMEPLAY at index 2 7. **Create ScriptableObject config assets** via `execute_editor_method`: - One config asset per module in `Assets/Config/` - Populate with default values from architecture doc ### Step 5: Run Full Test Suite via MCP Use MCP to run tests through the Unity Test Runner — do NOT rely on `dotnet test` alone: ``` # Via MCP execute_editor_method: # 1. Run EditMode tests # 2. Run PlayMode tests (if any) # 3. Collect results ``` 1. Call `execute_editor_method` to run EditMode tests and capture results 2. If PlayMode tests exist, call `execute_editor_method` to run PlayMode tests 3. Parse test results — if any failures, trace root cause (see testing skill's "No False Greens" section) 4. Fix failures and re-run until ALL tests pass ### Step 5b: Visual Validation via MCP After all tests pass, use MCP to verify the game runs correctly: 1. `capture_and_evaluate` — capture the game running in Play Mode 2. Compare against reference screenshots from GDD 3. Verify: - All entities spawn and are visible - UI elements are positioned correctly - No missing materials (pink/magenta objects) - Camera framing matches GDD art direction 4. Note any visual gaps for the polish-game phase ### Step 6: Validate - Invoke the `code-style` skill mentally to verify all code complies - Check that every public class has corresponding test coverage - Verify all serialized fields have proper configs created as assets - Verify all scenes are in Build Settings (use `execute_editor_method` to check) ### Step 7: Commit Per Module Commit each module separately for clean history: ```bash git add Assets/Scripts/PunkFuncGames/GameTemplate/Runtime/Spawner/ git add Assets/Scripts/PunkFuncGames/GameTemplate/Tests/EditMode/Spawner/ git commit -m "feat({game-name}): add spawner module with tests" ``` After all modules are committed, do a final integration commit if needed: ```bash git commit -m "feat({game-name}): wire installers and scenes" ``` ## Output Summary of modules implemented, test count and pass rate, and any issues encountered.