Add independent review reports for Minimap system (Rounds 8, 9, and 26)

- Round 8 report highlights improvements in architecture, editor usability, and data robustness, with a total score of 80/100.
- Round 9 report focuses on editor extension capabilities, identifying issues with room data indexing and layout editing, resulting in a score of 76/100.
- Round 26 report evaluates the system against commercial standards, noting new issues and confirming previous fixes, with a score of 95.8/100.
This commit is contained in:
2026-05-25 23:15:12 +08:00
parent e2bc324905
commit f74d7f1877
53 changed files with 6825 additions and 270 deletions

View File

@@ -0,0 +1,220 @@
# 小地图系统 独立审查报告 Round 14
**审查范围**`Assets/_Game/Scripts/World/Map/`Runtime 19 文件)+
`Assets/_Game/Scripts/Editor/World/Map/`Editor 4 文件)
**对标标准**:成熟 2D Metroidvania 类型游戏的专业编辑器扩展级别,
面向开发人员和策划人员,要求架构解耦、高性能、高可扩展性。
---
## 总评分(修复前)
| 维度 | 满分 | 得分 | 说明 |
|---|---|---|---|
| 架构解耦 | 10 | 9.0 | 接口 + ServiceLocator 完整MapPin.cs 文件名历史遗留 |
| 性能 | 10 | 9.0 | 对象池完整、dirty check 完整DrawExitLines 每帧 new HashSet |
| 编辑器 UX | 10 | 9.0 | 可视化布局编辑器成熟DrawExitLines HashSet GC 小问题 |
| 数据模型 | 10 | 8.5 | RoomType [Flags] 完善;缺少 TeleportStation 类型 |
| 输入系统 | 10 | 8.5 | InputSystem 软绑定完整MinimapInputHandler R13 已加 |
| 功能完整性 | 10 | 6.5 | TeleportService 存在但 MapPanel 无传送 UI 集成SaveKey 模式错误 |
| 代码质量 | 10 | 8.5 | 注释质量高TeleportService 含死代码字段 |
| 存档系统 | 10 | 5.0 | **TeleportService.ISaveable 签名错误(编译错误)** |
| 可扩展性 | 10 | 9.0 | SO 驱动、Event Channel 解耦、Region 机制完善 |
| **总分** | **90** | **73.0** | **换算 100 分81.1 / 100B** |
> **相比 R1385.0/100**R13 N1N4 + FA 修复提升了输入系统与 Bug 修复维度,
> 但 TeleportService 的 ISaveable 签名引入了编译错误N1使存档分大幅下降。
> 所有修复后预计 **92+**。
---
## Bug 发现
### N1致命 — 编译错误TeleportService 实现了错误的 ISaveable 签名
**文件**`TeleportService.cs`R13-FA 新增),`SaveData.cs`
**问题**
`ISaveable` 接口(`BaseGames.Core.Save`)定义为:
```csharp
public interface ISaveable
{
void OnSave(SaveData saveData);
void OnLoad(SaveData saveData);
}
```
`TeleportService` 实现的是:
```csharp
public string SaveKey => "TeleportService"; // ❌ 接口中不存在此成员
public string Serialize() { ... } // ❌ 接口中不存在此方法
public void Deserialize(string data) { ... } // ❌ 接口中不存在此方法
// ❌ 缺少 OnSave(SaveData) / OnLoad(SaveData)
```
这导致 `BaseGames.World.Map` 程序集**无法编译**,整个地图系统全部失效。
此外,`MapSaveData``SaveData.cs`)中没有 `UnlockedTeleportRoomIds` 字段,
即使签名正确,传送数据也无处存储。
**同时**`TeleportService``ISaveableRegistry` 注册自身OnEnable 中),
`ISaveableRegistry` 期望的是 `ISaveable` 对象,
`TeleportService` 未正确实现该接口,注册调用将在运行时无效。
**修复方案**
1. **`SaveData.cs`** — 在 `MapSaveData` 中添加:
```csharp
public HashSet<string> UnlockedTeleportRoomIds = new();
```
2. **`TeleportService.cs`** — 替换 `SaveKey/Serialize/Deserialize` 为:
```csharp
public void OnSave(SaveData saveData)
{
saveData.Map.UnlockedTeleportRoomIds = new HashSet<string>(_unlockedRoomIds);
}
public void OnLoad(SaveData saveData)
{
_unlockedRoomIds.Clear();
if (saveData.Map.UnlockedTeleportRoomIds != null)
foreach (var id in saveData.Map.UnlockedTeleportRoomIds)
_unlockedRoomIds.Add(id);
}
```
移除 `ISaveableRegistry` 手动注册(`OnSave/OnLoad` 由 `SaveManager` 直接调用,无需 Registry
---
### N2高优先级RoomType 缺少 TeleportStation 标志位
**文件**`MapRoomDataSO.cs``MapPanel.cs`
**问题**
`RoomType` [Flags] 枚举目前有 BossRoom / SavePoint / Shop / Merchant / Challenge
但没有 `TeleportStation`。`TeleportService` 的解锁状态存储于运行时,
但**策划无法在 SO 上标记"此房间有传送站"**`MapPanel` 也无法据此渲染传送图标。
```csharp
// 当前
public enum RoomType
{
None = 0,
BossRoom = 1 << 0,
SavePoint = 1 << 1,
Shop = 1 << 2,
Merchant = 1 << 3,
Challenge = 1 << 4,
// ❌ 缺少 TeleportStation
}
```
**修复**
1. `RoomType` 添加 `TeleportStation = 1 << 5`
2. `MapPanel` 添加 `[SerializeField] private Sprite _iconTeleport;` 字段
3. `MapPanel.ChooseIcon()` 中补充传送站图标逻辑
4. `MapPanel` 获取 `ITeleportService`,在 `BuildGrid` / `RefreshCell` 时区分
"已解锁传送站"和"未解锁传送站"的颜色/图标
---
### N3中等TeleportService._pendingSourceRoomId 是死代码
**文件**`TeleportService.cs`,第 108 行
**问题**
```csharp
_pendingSourceRoomId = sourceRoomId; // ← 赋值后从未读取
OnTeleportRequested?.Invoke(sourceRoomId, targetRoomId); // sourceRoomId 已直接传入
```
`_pendingSourceRoomId` 只被写入,永远不被读取,是无用的私有字段。
**修复**:删除 `_pendingSourceRoomId` 字段及赋值语句。
---
### N4低优先级MapLayoutEditorWindow.DrawExitLines 每帧 new HashSet
**文件**`MapLayoutEditorWindow.cs``DrawExitLines()` 方法(约第 453 行)
**问题**
```csharp
private void DrawExitLines(MapDatabaseSO db, ...)
{
var drawn = new HashSet<(string, string)>(); // ❌ 每次 OnGUI 都分配新对象
...
}
```
编辑器 `OnGUI` 以每秒多次频率调用,持续产生 GC 分配,可能导致编辑器卡顿。
**修复**:将 `drawn` 提升为类字段 `_drawnExitPairs`,在方法内仅调用 `Clear()`。
---
### N5低优先级MapPanel.OnMapUpdated 未标注 [Obsolete]
**文件**`MapPanel.cs`,第 313 行
**问题**
```csharp
private void OnMapUpdated(string roomId) { /* R12-N8 已废弃 */ }
```
方法已废弃但未加 `[Obsolete]` 标注,后续开发者可能误以为该方法仍有业务逻辑。
**修复**:添加 `[Obsolete("R12-N8: 由 OnExplorationChanged 统一处理,仅保留序列化兼容性。")]`。
---
## 架构亮点(保持优秀)
以下设计在本轮审查中仍被评定为业界优秀水平:
| 亮点 | 说明 |
|---|---|
| 接口 + ServiceLocator | 4 个服务接口完全解耦UI 层零具体类型依赖 |
| O(1) 空间索引 | `MapDatabaseSO.GetRoomIdAtCell` 惰性构建,`MinimapHUD` + `MapPlayerTracker` 共享 |
| 三重对象池 | `MapPanel`cell/pin/exit+ `MinimapHUD`cell/pin零 GC 渲染 |
| Dirty Flag 模式 | 面板关闭期间收到事件OnEnable 时应用——无事件遗漏 |
| `_servicesReady` 短路 | 三服务就绪后跳过 LateUpdate 的 ServiceLocator 查询 |
| `PinsVersion` 脏检查 | 无需事件订阅,整数比较即可判断 Pin 集合是否变化 |
| 可视化布局编辑器 | MapLayoutEditorWindow拖拽/吸附/缩放/搜索/Play 模式覆盖层 |
| MapRoomAutoRegister | AssetPostprocessor 自动注册新房间 SO零手动操作 |
| InputSystem 软绑定 | `throwIfNotFound: false` 防 InputActionAsset 缺失崩溃 |
| `HasCustomExitPos` 标志 | 消除 `Vector2Int.zero` 哨兵值歧义R12-N5R13-N1 已修复) |
---
## 修复优先级总表
| 编号 | 严重程度 | 文件 | 说明 |
|---|---|---|---|
| N1 | ★★★★★ 致命 | `TeleportService.cs` + `SaveData.cs` | ISaveable 签名错误导致编译失败 |
| N2 | ★★★★ 高 | `MapRoomDataSO.cs` + `MapPanel.cs` | 缺少 TeleportStation RoomType + MapPanel 传送 UI 集成 |
| N3 | ★★★ 中 | `TeleportService.cs` | `_pendingSourceRoomId` 死代码 |
| N4 | ★★ 低 | `MapLayoutEditorWindow.cs` | DrawExitLines HashSet 每帧分配 |
| N5 | ★ 极低 | `MapPanel.cs` | OnMapUpdated 缺 [Obsolete] |
---
## 修复后预估评分
| 维度 | 修复前 | 修复后 |
|---|---|---|
| 架构解耦 | 9.0 | 9.0 |
| 性能 | 9.0 | 9.5N4 修复) |
| 编辑器 UX | 9.0 | 9.0 |
| 数据模型 | 8.5 | 9.5N2 TeleportStation |
| 输入系统 | 8.5 | 8.5 |
| 功能完整性 | 6.5 | 9.0N2 传送 UI |
| 代码质量 | 8.5 | 9.0N3/N5 |
| 存档系统 | 5.0 | 9.5N1 修复) |
| 可扩展性 | 9.0 | 9.0 |
| **总分** | **81.1** | **≈ 92.3** |