# Fighter3D Networked MiniGame Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Build a first playable server-authoritative Fighter3D networked mini game in the existing hot-update mini game framework. **Architecture:** Follow the existing RockPaperScissors mini game layout. Put deterministic combat rules and snapshot codec in `Fighter3D.Core`, room authority in `Fighter3D.Server`, and Unity-only UI/input in `Fighter3D.Client`. **Tech Stack:** C# 9, .NET `netstandard2.1` hot-update projects, xUnit server tests, Unity runtime APIs only inside the client hot-update assembly. ## Global Constraints - Do not hand-edit Unity `.meta`, `.prefab`, `.unity`, `.mat`, `.asset`, `.controller`, or `.anim` files. - Core must not reference `UnityEngine`. - Client must send gameplay messages only through `IGameClientCtx.Send`. - Client assets must load through `ctx.Assets.Load`. - Server is authoritative for damage, block, KO, winner, and settlement. - First playable scope excludes jump, crouch, command specials, supers, polished 3D assets, and replay tooling. --- ### Task 1: Core Combat Model **Files:** - Create: `Client/Assets/MiniGames/Fighter3D/scripts~/Core/FighterTypes.cs` - Create: `Client/Assets/MiniGames/Fighter3D/scripts~/Core/FighterLogic.cs` - Create: `Server/games-src/Fighter3D/Fighter3D.Core/Fighter3D.Core.csproj` - Modify: `Server/Server.Host.Tests/Server.Host.Tests.csproj` - Test: `Server/Server.Host.Tests/Fighter3DLogicTests.cs` **Interfaces:** - Produces: `Fighter3D.Core.FighterLogic.CreateInitial(RoomConfig, IRandom) : FighterState` - Produces: `Fighter3D.Core.FighterLogic.Step(FighterState, FighterInput, IRandom) : StepResult` - Produces: `Fighter3D.Core.FighterLogic.Encode(FighterState) : byte[]` - Produces: `Fighter3D.Core.FighterLogic.Decode(byte[]) : FighterState` - [ ] **Step 1: Write failing core tests** Create tests that assert initial state, movement clamp, light hit damage/stun, guard block, timeout winner, and codec round-trip. - [ ] **Step 2: Run tests and verify red** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj --filter Fighter3DLogicTests` Expected: compile failure because `Fighter3D.Core` does not exist. - [ ] **Step 3: Implement minimal core** Implement two fighters, fixed 60 Hz step accumulation, stage bounds, facing, horizontal movement, light/heavy attacks, attack active collision by range, guard-away block, hit/block stun, HP, KO, timeout, and packet codec. - [ ] **Step 4: Run tests and verify green** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj --filter Fighter3DLogicTests` Expected: all Fighter3D core tests pass. ### Task 2: Server Room Authority **Files:** - Create: `Server/games-src/Fighter3D/Fighter3D.Server/Fighter3D.Server.csproj` - Create: `Server/games-src/Fighter3D/Fighter3D.Server/FighterServerRoom.cs` - Modify: `Server/Server.Host.Tests/Server.Host.Tests.csproj` - Test: `Server/Server.Host.Tests/Fighter3DServerRoomTests.cs` **Interfaces:** - Consumes: `FighterLogic`, `FighterInput`, `FighterState` - Produces: `Fighter3D.Server.FighterServerRoom : IGameServerRoom` - Produces: `FighterServerRoom.InputOpcode = 1` - Produces: `FighterServerRoom.SnapshotOpcode = 100` - [ ] **Step 1: Write failing room tests** Create tests that start a two-player room, assert initial broadcast, send attack input from player 1, tick until KO, and assert `EndRoom` winner is player 1. - [ ] **Step 2: Run tests and verify red** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj --filter Fighter3DServerRoomTests` Expected: compile failure because `Fighter3D.Server` does not exist. - [ ] **Step 3: Implement minimal room** Map `PlayerInfo.PlayerId` to seats, decode input messages, feed Core, broadcast snapshots each room tick, and call `EndRoom(RoomEndResult)` exactly once when Core is finished. - [ ] **Step 4: Run tests and verify green** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj --filter Fighter3DServerRoomTests` Expected: all Fighter3D server room tests pass. ### Task 3: Client Hot-Update Shell **Files:** - Create: `Client/Assets/MiniGames/Fighter3D/scripts~/Client/FighterGameClient.cs` - Create: `Client/HotUpdateGames/Fighter3D.Client/Fighter3D.Client.csproj` **Interfaces:** - Consumes: `FighterLogic.Decode(byte[])` - Produces: `Fighter3D.Client.FighterGameClient : IGameClient` - [ ] **Step 1: Implement client shell** Load `Assets/MiniGames/Fighter3D/res/UI/Prefab/UI_Fighter3D.prefab` through `ctx.Assets.Load`, fallback to a generated Canvas if it is missing, bind no-prefab UI labels, send input frames, and update HUD from snapshots. - [ ] **Step 2: Build client project** Run: `dotnet build Client/HotUpdateGames/Fighter3D.Client/Fighter3D.Client.csproj -c Release` Expected: build succeeds. ### Task 4: MiniGame Publish Metadata **Files:** - Create: `Client/Assets/MiniGames/Fighter3D/README.md` - Create: `Client/Assets/MiniGames/Fighter3D/publish.json` **Interfaces:** - Produces: `gameId = "fighter3d"` - Produces: `clientEntryType = "Fighter3D.Client.FighterGameClient"` - Produces: `serverEntryType = "Fighter3D.Server.FighterServerRoom"` - [ ] **Step 1: Add publish metadata** Create `publish.json` matching the existing RPS fields with `playerCount` 2 and `tickRateHz` 20. - [ ] **Step 2: Build server and client projects** Run: `dotnet build Server/games-src/Fighter3D/Fighter3D.Server/Fighter3D.Server.csproj -c Release` Run: `dotnet build Client/HotUpdateGames/Fighter3D.Client/Fighter3D.Client.csproj -c Release` Expected: both builds succeed. ### Task 5: Verification **Files:** - No new files. **Interfaces:** - Verifies all earlier outputs. - [ ] **Step 1: Run focused tests** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj --filter Fighter3D` Expected: all Fighter3D tests pass. - [ ] **Step 2: Run full server host tests if focused tests pass** Run: `dotnet test Server/Server.Host.Tests/Server.Host.Tests.csproj` Expected: pass, or document unrelated existing failures. - [ ] **Step 3: Check working tree** Run: `git status --short` Expected: only intended Fighter3D files plus pre-existing unrelated user changes.