文档记录

This commit is contained in:
JSD\13999
2026-05-15 15:38:40 +08:00
parent d7b09891dc
commit 019703d2a8
18 changed files with 4221 additions and 1 deletions

View File

@@ -0,0 +1,603 @@
# FlowScope Game Core P0 Parallel 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:** Implement FlowScope Game Core P0 as a minimal Unity-ready vertical slice with stable shared contracts, isolated services, Feature lifecycle, MVVM UI, and a runnable MainMenu sample.
**Architecture:** Work starts with a single contracts branch/worktree that defines shared interfaces and project layout. After contracts are merged, independent worktrees implement Container, data/config/save, resources, UI, audio, GameFlow/Feature, and sample integration in parallel. Final integration happens in a dedicated worktree that owns cross-module fixes and sample validation.
**Tech Stack:** Unity C#, .NET Task/CancellationToken, R3, Addressables, Newtonsoft.Json or System.Text.Json, Unity Test Framework.
---
## Source Documents
- `docs/requirements/p0-requirements-set.md`
- `docs/requirements/p0-container.md`
- `docs/requirements/p0-gameflow.md`
- `docs/requirements/p0-feature.md`
- `docs/requirements/p0-data-r3.md`
- `docs/requirements/p0-configprovider.md`
- `docs/requirements/p0-saveservice.md`
- `docs/requirements/p0-resourceservice.md`
- `docs/requirements/p0-uimanager.md`
- `docs/requirements/p0-audioservice.md`
## Worktree Strategy
Do not open all implementation worktrees before contracts are stable.
1. Create `p0-contracts` first.
2. Merge `p0-contracts`.
3. Create parallel worktrees from the merged contracts branch.
4. Keep each worker inside its owned file set.
5. Merge service worktrees before sample integration.
6. Use a final `p0-integration` worktree to resolve seams and verify the sample.
Recommended worktrees:
| Worktree | Purpose |
|----------|---------|
| `p0-contracts` | Shared asmdefs, interfaces, base types, package skeleton |
| `p0-container` | Container runtime, SourceGen adapter, reflection adapter |
| `p0-data-config-save` | Data/R3 converters, JSON config, local save |
| `p0-resource` | Addressables-backed resource service |
| `p0-ui` | UIManager, UIPanelAttribute, UIPanelBase |
| `p0-audio` | AudioService and audio handles |
| `p0-gameflow-feature` | FeatureContext, GameFlow, FeatureBase |
| `p0-sample-integration` | MainMenu sample scene, sample data/config/UI |
| `p0-integration` | Final merge, compile, test, documentation fixes |
## Proposed Runtime Layout
Create the Core package under the Unity project:
```text
My project/Assets/FlowScope/
├── Runtime/
│ ├── FlowScope.Runtime.asmdef
│ ├── Common/
│ ├── Container/
│ ├── Flow/
│ ├── Data/
│ ├── Config/
│ ├── Save/
│ ├── Resources/
│ ├── UI/
│ └── Audio/
├── Editor/
│ └── FlowScope.Editor.asmdef
├── Tests/
│ ├── EditMode/
│ │ └── FlowScope.Tests.EditMode.asmdef
│ └── PlayMode/
│ └── FlowScope.Tests.PlayMode.asmdef
└── Samples/
└── MainMenuP0/
```
If the repo already introduces a different package layout before implementation starts, update this section first and keep all worker plans aligned.
---
## Task 0: Contracts Worktree
**Worktree:** `p0-contracts`
**Files:**
- Create: `My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef`
- Create: `My project/Assets/FlowScope/Runtime/Common/ResultLog.cs`
- Create: `My project/Assets/FlowScope/Runtime/Container/Container.cs`
- Create: `My project/Assets/FlowScope/Runtime/Container/InjectableAttribute.cs`
- Create: `My project/Assets/FlowScope/Runtime/Flow/FeatureContext.cs`
- Create: `My project/Assets/FlowScope/Runtime/Flow/IFeature.cs`
- Create: `My project/Assets/FlowScope/Runtime/Flow/GameFlowState.cs`
- Create: `My project/Assets/FlowScope/Runtime/Config/IConfigProvider.cs`
- Create: `My project/Assets/FlowScope/Runtime/Config/IConfigRow.cs`
- Create: `My project/Assets/FlowScope/Runtime/Save/ISaveService.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/IResourceService.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/IResourceHandle.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/IResourceGroup.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/PanelStrategy.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/UIPanelAttribute.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/UIPanelBase.cs`
- Create: `My project/Assets/FlowScope/Runtime/Audio/IAudioService.cs`
- Create: `My project/Assets/FlowScope/Runtime/Audio/IAudioHandle.cs`
- [ ] **Step 1: Create the runtime asmdef**
Create `My project/Assets/FlowScope/Runtime/FlowScope.Runtime.asmdef`:
```json
{
"name": "FlowScope.Runtime",
"rootNamespace": "FlowScope",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
```
- [ ] **Step 2: Create Container contract skeleton**
Create `My project/Assets/FlowScope/Runtime/Container/Container.cs` with method signatures from `p0-container.md`:
```csharp
using System;
namespace FlowScope.Container
{
public sealed class Container : IDisposable
{
public void RegisterInstance<T>(T instance) => throw new NotImplementedException();
public void RegisterFactory<T>(Func<Container, T> factory) => throw new NotImplementedException();
public void RegisterType<TInterface, TImplementation>() where TImplementation : TInterface => throw new NotImplementedException();
public void RegisterType<TImplementation>() => throw new NotImplementedException();
public void RegisterAssembly() => throw new NotImplementedException();
public T Resolve<T>() => throw new NotImplementedException();
public bool TryResolve<T>(out T value)
{
value = default;
throw new NotImplementedException();
}
public Container CreateScope() => throw new NotImplementedException();
public void Dispose() => throw new NotImplementedException();
}
}
```
- [ ] **Step 3: Create Feature contracts**
Create `FeatureContext`, `IFeature`, and `GameFlowState` exactly matching `p0-feature.md` and `p0-gameflow.md`.
- [ ] **Step 4: Create service contracts**
Create the config, save, resource, UI, and audio interfaces exactly matching `p0-requirements-set.md`.
- [ ] **Step 5: Compile contracts**
Run Unity compile validation if available. If not available, open the project in Unity and verify there are no C# compile errors.
Expected: contracts compile with `NotImplementedException` bodies where concrete implementations are not yet owned by this task.
- [ ] **Step 6: Commit contracts**
```powershell
git add "My project/Assets/FlowScope/Runtime" docs/requirements
git commit -m "定义 Game Core P0 共享契约"
```
---
## Task A: Container Implementation
**Worktree:** `p0-container`
**Depends on:** `p0-contracts`
**Owned files:**
- Modify: `My project/Assets/FlowScope/Runtime/Container/Container.cs`
- Create: `My project/Assets/FlowScope/Runtime/Container/ContainerRegistration.cs`
- Create: `My project/Assets/FlowScope/Runtime/Container/ReflectionFactoryBuilder.cs`
- Create: `My project/Assets/FlowScope/Runtime/Container/GeneratedFactories.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Container/ContainerTests.cs`
**Do not modify:** Flow, UI, Resource, Save, Config, Audio implementation files.
- [ ] **Step 1: Write Container tests first**
Cover explicit factory, instance registration, child scope lookup, child override, duplicate root registration, dispose order, repeated dispose, and circular dependency.
- [ ] **Step 2: Implement explicit registration and Resolve**
Implement dictionary-backed registrations keyed by `(Type type, object key)` if key support is retained. If key support is deferred, do not add key overloads.
- [ ] **Step 3: Implement scope lookup and disposal**
Child scope lookup checks local registrations first, then parent. Dispose releases local factory-created instances in reverse creation order.
- [ ] **Step 4: Implement reflection adapter**
Only reflection adapter owns constructor inspection. Core Container receives a factory.
- [ ] **Step 5: Stub Source Generator integration**
Create `GeneratedFactories` as the stable handoff point. If real Source Generator is not implemented in this task, tests must prove explicit and reflection paths work, and Generator work must be tracked as a follow-up inside the same worktree before merge.
- [ ] **Step 6: Run Container tests**
Expected: all Container edit mode tests pass.
- [ ] **Step 7: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/Container" "My project/Assets/FlowScope/Tests/EditMode/Container"
git commit -m "实现 P0 容器核心能力"
```
---
## Task B: Data, Config, and Save
**Worktree:** `p0-data-config-save`
**Depends on:** `p0-contracts`, `p0-container`
**Owned files:**
- Create: `My project/Assets/FlowScope/Runtime/Data/ReactivePropertyJsonConverter.cs`
- Create: `My project/Assets/FlowScope/Runtime/Config/JsonConfigProvider.cs`
- Create: `My project/Assets/FlowScope/Runtime/Save/JsonSaveSerializer.cs`
- Create: `My project/Assets/FlowScope/Runtime/Save/FileSaveStorage.cs`
- Create: `My project/Assets/FlowScope/Runtime/Save/PlayerPrefsSaveStorage.cs`
- Create: `My project/Assets/FlowScope/Runtime/Save/SaveService.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Data/DataSerializationTests.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Config/JsonConfigProviderTests.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Save/SaveServiceTests.cs`
**Do not modify:** Container internals, UIManager, AudioService, GameFlow.
- [ ] **Step 1: Write Data serialization tests**
Test `ReactiveProperty<int>` serializes as value and deserializes back into a Data instance.
- [ ] **Step 2: Implement reactive JSON converters**
Support P0 primitives: `int`, `float`, `string`, `bool`, and serializable structs.
- [ ] **Step 3: Write Config tests**
Use an in-memory JSON text source where possible. Test normal load, missing id, duplicate id, malformed JSON.
- [ ] **Step 4: Implement `JsonConfigProvider`**
Implement `LoadAllAsync`, `Get<T>`, and `GetAll<T>` for registered config types.
- [ ] **Step 5: Write Save tests**
Test save/load, missing key default, delete, exists, deserialization failure default.
- [ ] **Step 6: Implement SaveService**
Keep storage and serializer separable. Do not add `ListKeys`, cloud save, compression, or migration.
- [ ] **Step 7: Run tests**
Expected: Data, Config, and Save edit mode tests pass.
- [ ] **Step 8: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/Data" "My project/Assets/FlowScope/Runtime/Config" "My project/Assets/FlowScope/Runtime/Save" "My project/Assets/FlowScope/Tests/EditMode/Data" "My project/Assets/FlowScope/Tests/EditMode/Config" "My project/Assets/FlowScope/Tests/EditMode/Save"
git commit -m "实现 P0 数据配置和存档"
```
---
## Task C: ResourceService
**Worktree:** `p0-resource`
**Depends on:** `p0-contracts`
**Owned files:**
- Create: `My project/Assets/FlowScope/Runtime/Resources/AddressablesResourceService.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/ResourceHandle.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/ResourceGroup.cs`
- Create: `My project/Assets/FlowScope/Runtime/Resources/ResourceEntry.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Resources/ResourceGroupTests.cs`
- Test: `My project/Assets/FlowScope/Tests/PlayMode/Resources/AddressablesResourceServiceTests.cs`
**Do not modify:** UIManager or AudioService except through agreed interfaces.
- [ ] **Step 1: Write handle/group tests**
Test group add, group dispose, duplicate add, repeated dispose, disposed handle asset behavior.
- [ ] **Step 2: Implement handle and group**
`ResourceHandle<T>.Asset` returns null after Dispose, matching the P0 document.
- [ ] **Step 3: Write concurrent load test**
Use a fake backend if Addressables is hard to exercise in edit mode. Test that concurrent same-key loads share one backend load.
- [ ] **Step 4: Implement Addressables service**
Default backend is Addressables only. Do not implement Resources, AssetBundle, or YooAsset.
- [ ] **Step 5: Run resource tests**
Expected: edit mode tests pass; play mode Addressables test passes if sample assets are available.
- [ ] **Step 6: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/Resources" "My project/Assets/FlowScope/Tests/EditMode/Resources" "My project/Assets/FlowScope/Tests/PlayMode/Resources"
git commit -m "实现 P0 资源加载和引用计数"
```
---
## Task D: UIManager
**Worktree:** `p0-ui`
**Depends on:** `p0-contracts`, `p0-resource`
**Owned files:**
- Modify: `My project/Assets/FlowScope/Runtime/UI/UIPanelAttribute.cs`
- Modify: `My project/Assets/FlowScope/Runtime/UI/UIPanelBase.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/UIManager.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/UILayer.cs`
- Create: `My project/Assets/FlowScope/Runtime/UI/UIPanelRecord.cs`
- Test: `My project/Assets/FlowScope/Tests/PlayMode/UI/UIManagerTests.cs`
**Do not modify:** ResourceService internals.
- [ ] **Step 1: Write UI lifecycle tests**
Test layer registration, open, bind, close, unbind, LIFO error, cache reuse, destroy release.
- [ ] **Step 2: Implement `UIPanelAttribute` path support**
Constructor must include `string path = null` and `PanelStrategy? overrideStrategy = null`.
- [ ] **Step 3: Implement `UIPanelBase<TViewModel>`**
Keep only one `CompositeDisposable` property. No duplicate property declarations.
- [ ] **Step 4: Implement layer and stack management**
Close non-top panel throws `InvalidOperationException`.
- [ ] **Step 5: Implement path resolution**
Attribute path wins. Otherwise use `PanelName` without `Panel` suffix: `UI/{Name}/Prefab`.
- [ ] **Step 6: Run UI tests**
Expected: all UI play mode tests pass.
- [ ] **Step 7: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/UI" "My project/Assets/FlowScope/Tests/PlayMode/UI"
git commit -m "实现 P0 UI 管理器"
```
---
## Task E: AudioService
**Worktree:** `p0-audio`
**Depends on:** `p0-contracts`, `p0-resource`
**Owned files:**
- Create: `My project/Assets/FlowScope/Runtime/Audio/AudioService.cs`
- Create: `My project/Assets/FlowScope/Runtime/Audio/AudioHandle.cs`
- Create: `My project/Assets/FlowScope/Runtime/Audio/AudioServiceConfig.cs`
- Test: `My project/Assets/FlowScope/Tests/PlayMode/Audio/AudioServiceTests.cs`
**Do not modify:** ResourceService internals.
- [ ] **Step 1: Write audio tests**
Test BGM play/stop, BGM switch, SFX pool cap, mute, volume clamp, handle stop.
- [ ] **Step 2: Implement audio handle**
P0 handle supports `Stop(fadeOut)` and `IsPlaying`. Do not add per-handle `Volume`.
- [ ] **Step 3: Implement BGM channel**
One active BGM. New BGM stops old BGM.
- [ ] **Step 4: Implement SFX pool**
Default pool size is 10. Pool exhaustion behavior follows `AudioServiceConfig`.
- [ ] **Step 5: Implement fade**
Use local coroutine or update driver. Do not introduce a Timer service.
- [ ] **Step 6: Run audio tests**
Expected: all audio play mode tests pass.
- [ ] **Step 7: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/Audio" "My project/Assets/FlowScope/Tests/PlayMode/Audio"
git commit -m "实现 P0 音频服务"
```
---
## Task F: GameFlow and Feature
**Worktree:** `p0-gameflow-feature`
**Depends on:** `p0-contracts`, `p0-container`, `p0-resource`
**Owned files:**
- Modify: `My project/Assets/FlowScope/Runtime/Flow/FeatureContext.cs`
- Modify: `My project/Assets/FlowScope/Runtime/Flow/IFeature.cs`
- Create: `My project/Assets/FlowScope/Runtime/Flow/FeatureBase.cs`
- Create: `My project/Assets/FlowScope/Runtime/Flow/GameFlow.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Flow/GameFlowTests.cs`
- Test: `My project/Assets/FlowScope/Tests/EditMode/Flow/FeatureBaseTests.cs`
**Do not modify:** Concrete UI, Audio, Save, Config, or Resource implementations.
- [ ] **Step 1: Write GameFlow state tests**
Test startup, switch, shutdown, illegal calls, NoActiveFeature behavior.
- [ ] **Step 2: Write failure cleanup tests**
Use fake Feature classes that fail in Load/Enter/Exit/Dispose.
- [ ] **Step 3: Implement FeatureContext**
It contains Scope, Resources, Disposables, and CancellationToken.
- [ ] **Step 4: Implement FeatureBase**
FeatureBase stores context, clears disposables on Exit, clears references on Dispose.
- [ ] **Step 5: Implement GameFlow**
GameFlow creates scope/resources/context and owns their final disposal.
- [ ] **Step 6: Run flow tests**
Expected: all flow edit mode tests pass.
- [ ] **Step 7: Commit**
```powershell
git add "My project/Assets/FlowScope/Runtime/Flow" "My project/Assets/FlowScope/Tests/EditMode/Flow"
git commit -m "实现 P0 生命周期编排"
```
---
## Task G: MainMenu P0 Sample
**Worktree:** `p0-sample-integration`
**Depends on:** all service worktrees merged
**Owned files:**
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/GameBootstrap.cs`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/MainMenuFeature.cs`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/MainMenuViewModel.cs`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/PlayerData.cs`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scripts/MainMenuPanel.cs`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Configs/player_start.json`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Prefabs/MainMenuPanel.prefab`
- Create: `My project/Assets/FlowScope/Samples/MainMenuP0/Scenes/MainMenuP0.unity`
- Test: `My project/Assets/FlowScope/Tests/PlayMode/Samples/MainMenuP0Tests.cs`
- [ ] **Step 1: Create sample data**
`PlayerData` has at least `ReactiveProperty<int> Gold`.
- [ ] **Step 2: Create sample ViewModel**
ViewModel increments Gold through a public command method.
- [ ] **Step 3: Create sample Panel**
Panel binds Gold text and button click manually.
- [ ] **Step 4: Create MainMenuFeature**
Load creates ViewModel. Enter opens `MainMenuPanel`. Exit closes panel.
- [ ] **Step 5: Create GameBootstrap**
Bootstrap registers Container, Config, Save, Resource, UI, Audio, PlayerData, then calls `GameFlow.StartupAsync<MainMenuFeature>`.
- [ ] **Step 6: Write sample play mode test**
Test startup, click increment, UI refresh, shutdown save, restart restore.
- [ ] **Step 7: Run sample**
Expected: sample scene runs in Unity with no console errors.
- [ ] **Step 8: Commit**
```powershell
git add "My project/Assets/FlowScope/Samples/MainMenuP0" "My project/Assets/FlowScope/Tests/PlayMode/Samples"
git commit -m "添加 P0 主菜单纵向切片示例"
```
---
## Task H: Final Integration
**Worktree:** `p0-integration`
**Depends on:** all P0 implementation branches merged or available as PRs
**Owned files:**
- Modify only files needed to resolve integration seams.
- Modify docs only for verified behavior changes.
- [ ] **Step 1: Merge implementation branches one by one**
Recommended order:
```text
p0-contracts
p0-container
p0-data-config-save
p0-resource
p0-ui
p0-audio
p0-gameflow-feature
p0-sample-integration
```
- [ ] **Step 2: Run full compile**
Use Unity compile validation. Expected: zero C# compile errors.
- [ ] **Step 3: Run edit mode tests**
Expected: Container, Data, Config, Save, Resource group, GameFlow tests pass.
- [ ] **Step 4: Run play mode tests**
Expected: UI, Audio, Addressables Resource, MainMenu sample tests pass.
- [ ] **Step 5: Manual sample validation**
Open `MainMenuP0.unity`. Verify:
- UI opens.
- Gold increments on click.
- UI updates immediately.
- Exit saves data.
- Restart restores data.
- Closing Feature releases resources and subscriptions.
- [ ] **Step 6: Update docs**
Update `docs/requirements/p0-requirements-set.md` only if implementation discovered a necessary contract adjustment. Do not silently drift code away from docs.
- [ ] **Step 7: Commit integration**
```powershell
git add "My project/Assets/FlowScope" docs/requirements
git commit -m "集成 Game Core P0 纵向切片"
```
---
## Merge Rules for Agent Workers
- Do not change shared contracts after `p0-contracts` merges unless the integration owner approves the contract change.
- If a worker needs a new method on a shared interface, stop and write a short contract-change note before editing.
- Do not introduce CSV, Luban, Resources backend, AssetBundle backend, cloud save, UI router, or AudioMixer in P0.
- Do not add global EventBus in P0.
- Do not make Feature create root scope; GameFlow owns FeatureContext creation.
- Commit messages must be Chinese.
## Self-Review Checklist
- P0 contracts cover all modules in `p0-requirements-set.md`.
- Every worker has an owned file set.
- Parallel workers do not write the same implementation files.
- Extension-only features are not assigned to P0 workers.
- Final integration owns cross-module validation.