6.3 KiB
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.animfiles. - 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<FighterState, FighterEvent> -
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.