Files
AIC-Project/docs/superpowers/plans/2026-08-10-fighter3d-networked-minigame.md

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 .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<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.