docs(02-03): complete L3 pathfinding plan

This commit is contained in:
unanmed 2026-09-09 21:28:09 +08:00
parent 7a3b6e35c1
commit cdadd3870c
8 changed files with 255 additions and 29 deletions

View File

@ -15,8 +15,8 @@ Requirements for the engine's completion. Each maps to roadmap phases.
### 寻路Pathfinding
- [ ] **PATH-01**: 引擎支持自动寻路
- [ ] **PATH-02**: 移动端通过点击地图触发自动寻路移动
- [x] **PATH-01**: 引擎支持自动寻路
- [x] **PATH-02**: 移动端通过点击地图触发自动寻路移动
### 数据端Data
@ -55,8 +55,8 @@ Which phases cover which requirements. Updated during roadmap creation.
| EVT-01 | Phase 1 | Complete |
| EVT-02 | Phase 1 | Complete |
| EVT-03 | Phase 1 | Complete |
| PATH-01 | Phase 2 | Pending |
| PATH-02 | Phase 2 | Pending |
| PATH-01 | Phase 2 | Complete |
| PATH-02 | Phase 2 | Complete |
| DATA-01 | Phase 3 | Pending |
| REND-01 | Phase 4 | Pending |
| REND-02 | Phase 4 | Pending |

View File

@ -80,13 +80,13 @@ Plans:
2. 移动端点击地图上的可达格时,角色自动寻路移动到该格
3. 寻路正确避开不可通行格(碰撞/障碍/墙体)
**Plans**: 2/3 plans executed
**Plans**: 3/3 plans executed
**UI hint**: yes
Plans:
- [x] 02-01-PLAN.md — 接口草案 + mover.ts:651 缺陷调查 + 回归脚手架 + D-07 用户拍板关卡checkpoint
- [x] 02-02-PLAN.md — L0 坐标回写缺陷修复 + L2 寻路核心(有向图 + 最小损失 + 仅取路径 + 回退策略槽位)
- [ ] 02-03-PLAN.md — L3 接线(逐步/瞬移/回退默认策略/D-08 双语义/打断接管)+ barrel/logger 装配 + 阶段门禁
- [x] 02-03-PLAN.md — L3 接线(逐步/瞬移/回退默认策略/D-08 双语义/打断接管)+ barrel/logger 装配 + 阶段门禁
**Wave 1**
@ -94,11 +94,11 @@ Plans:
**Wave 2** *(blocked on Wave 1 用户拍板)*
- [ ] 02-02-PLAN.md — L0 修复 + L2 寻路核心
- [x] 02-02-PLAN.md — L0 修复 + L2 寻路核心
**Wave 3** *(blocked on Wave 2)*
- [ ] 02-03-PLAN.md — L3 接线与阶段门禁
- [x] 02-03-PLAN.md — L3 接线与阶段门禁
### Phase 3: 数据端完成
@ -165,7 +165,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
| 1. 事件系统 | 13/13 | In Progress| |
| 2. 寻路系统 | 2/3 | In Progress| |
| 2. 寻路系统 | 3/3 | In Progress| |
| 3. 数据端完成 | 0/TBD | Not started | - |
| 4. 渲染适配与双布局 | 0/TBD | Not started | - |
| 5. Legacy 移植 | 0/TBD | Not started | - |

View File

@ -3,17 +3,17 @@ gsd_state_version: "1.0"
milestone: v1.0
current_phase: 02
current_phase_name: 寻路系统
status: executing
stopped_at: Phase 2 paused after Wave 2 (02-02) - user code review before Wave 3 (02-03)
last_updated: "2026-09-09T09:48:36.334Z"
status: verifying
stopped_at: Completed 02-03-PLAN.md
last_updated: "2026-09-09T13:26:49.286Z"
last_activity: 2026-09-09
last_activity_desc: Phase 02 execution started
state_head: b6b4b3320a1271d5a7fcc46c12ce90f8659a8d14
state_head: 7a3b6e35c1dfce17e605ba870a023524acba8eec
progress:
total_phases: 6
completed_phases: 0
total_plans: 16
completed_plans: 15
completed_plans: 16
milestone_name: milestone
---
@ -30,7 +30,7 @@ See: .planning/PROJECT.md (updated 2026-09-07)
Phase: 02 (寻路系统) — EXECUTING
Plan: 3 of 3
Status: Ready to execute
Status: Phase complete — ready for verification
Last activity: 2026-09-09 — Phase 02 execution started
Progress: [█████████░] 92%
@ -71,6 +71,7 @@ Progress: [█████████░] 92%
| Phase 01 P13 | 30 | 3 tasks | 11 files |
| Phase 02 P01 | 25min | 3 tasks | 2 files |
| Phase 02 P02 | 29min | 3 tasks | 10 files |
| Phase 02 P03 | 30 min | 4 tasks | 9 files |
## Accumulated Context
@ -110,6 +111,9 @@ Recent decisions affecting current work:
- [Phase 02]: [Phase 02]: 02-02 L2 经结构化守卫 hasMover 取移动器(零 asmover.start() 返回 null 即已有移动进行中契约检测点
- [Phase 02]: [Phase 02]: 02-02 终端节点canPass 且 shouldHit在搜索层约束可作终点不可穿越D-08 情形 1 由 02-03 直接 find() 判定相邻格
- [Phase 02]: [Phase 02]: 02-02 moveTo 恒逐步,回退策略仅作用于 teleportTo 且 null 默认必定逐步(与用户 types.ts jsdoc 逐字对齐)
- [Phase 02]: L3 HeroPathfinding 注入 DefaultHeroMoveTopImpl 的 IPassPredicateL2 图搜索与 hero mover 共享同一通行性语义。
- [Phase 02]: D-08 no-pass 目标采用可达相邻格 + 面朝目标 + source-aware OnTouch 直派;无相邻可达格返回空路径。
- [Phase 02]: 同步寻路接口通过 queued controller 实现 stop 后 await再从最新坐标重算并启动新路径。
### Pending Todos
@ -132,6 +136,6 @@ None yet.
## Session Continuity
Last session: 2026-09-09T09:48:36.226Z
Stopped at: Phase 2 paused after Wave 2 (02-02) - user code review before Wave 3 (02-03)
Resume file: .planning/phases/02-pathfinding/02-02-SUMMARY.md
Last session: 2026-09-09T13:26:49.198Z
Stopped at: Completed 02-03-PLAN.md
Resume file: None

View File

@ -1,10 +1,10 @@
---
schema_version: 1
open_count: 4
open_count: 3
waived_count: 0
fixed_count: 1
fixed_count: 2
total_count: 5
last_updated: 2026-09-09T09:34:59.707Z
last_updated: 2026-09-09T13:24:24.755Z
---
# Broken Windows Ledger
@ -19,7 +19,7 @@ last_updated: 2026-09-09T09:34:59.707Z
| 2 | 01 | unrun-verify | .planning/phases/01-event/01-05-SUMMARY.md | | Downstream implementation verification was not run because the user explicitly prohibited downstream plan execution. | open | | 2026-09-08T15:37:54.227Z | |
| 3 | 01 | deviation | packages-user/data-base/src/map/mapLayer.ts | | Replaced unsupported Map upsert runtime calls so the raw map event path runs under Node Vitest. | open | | 2026-09-08T15:54:23.173Z | |
| 4 | 02 | skipped-test | packages-user/data-common/src/common/mover.test.ts | | 4 个 it.skip 坐标回写回归用例x/y 正交、斜向、传送),待 02-02 修复 mover.ts:651 后翻绿 | fixed | | 2026-09-09T07:51:25.555Z | 2026-09-09T09:34:39.843Z |
| 5 | 02 | stub | packages-user/data-system/src/path/system.ts | 254 | interrupt() is an intentional placeholder that only stops the in-flight move; takeover sequencing (stop-then-await per approved option 1) is implemented by 02-03 Task 4 | open | | 2026-09-09T09:34:59.707Z | |
| 5 | 02 | stub | packages-user/data-system/src/path/system.ts | 254 | interrupt() is an intentional placeholder that only stops the in-flight move; takeover sequencing (stop-then-await per approved option 1) is implemented by 02-03 Task 4 | fixed | | 2026-09-09T09:34:59.707Z | 2026-09-09T13:24:24.755Z |
````json
[
@ -78,10 +78,10 @@ last_updated: 2026-09-09T09:34:59.707Z
"file": "packages-user/data-system/src/path/system.ts",
"line": 254,
"description": "interrupt() is an intentional placeholder that only stops the in-flight move; takeover sequencing (stop-then-await per approved option 1) is implemented by 02-03 Task 4",
"status": "open",
"status": "fixed",
"reason": "",
"recorded_at": "2026-09-09T09:34:59.707Z",
"resolved_at": null
"resolved_at": "2026-09-09T13:24:24.755Z"
}
]
````

View File

@ -1,6 +1,6 @@
{
"phase": "02",
"session": "wt-session-eb4daf98-f578-4749-8d80-f7dea0a4346b",
"pid": 137500,
"updated_at": 1788946631198
"pid": 111848,
"updated_at": 1788960403962
}

View File

@ -0,0 +1,217 @@
---
phase: 02-pathfinding
plan: 03
subsystem: pathfinding
tags: [pathfinding, hero-mover, pass-predicate, teleport, interruption, events]
# Dependency graph
requires:
- phase: 02-pathfinding (plan 02)
provides: L2 PathfindingSystem、IPathfindingStep、usePassPredicate/useFallbackPolicy 接线槽位与 mover 控制器契约
- phase: 01-event-system
provides: source-aware enter/leave/touch 事件执行链与地图事件层
provides:
- DefaultHeroMoveTopImpl predicate() 通行性实现与 HeroMover 新 IPassPredicate 调用链
- HeroPathfinding L3 数据端入口,支持逐步移动、瞬移、事件路径回退与 D-08 相邻格触碰
- 新寻路/interrupt 的 stop-then-await 接管时序、CoreState/barrel 装配与路径日志码
affects: [phase-04-rendering, PATH-01, PATH-02]
# Actuals (#2632)
actuals:
tokens: 9881
tasks: 4
commits: 4
plan_head_before: 3770e56c4d6e589c565172800565ff28c9f5159b
commits: 4
# Tech tracking
tech-stack:
added: []
patterns:
- "L3 通过 IPassPredicate 注入 L2HeroMover 与寻路图共享同一通行性语义"
- "事件路径默认回退逐步移动;无事件路径使用 Teleport 步骤"
- "D-08 采用相邻格移动完成后直接构造 source-aware OnTouch invocation"
- "接管控制器先停止并等待旧 mover再从最新坐标重算新路径"
key-files:
created:
- packages-user/data-state/src/path/heroPathfinding.ts
- packages-user/data-state/src/path/heroPathfinding.test.ts
- packages-user/data-state/src/path/index.ts
modified:
- packages-user/data-state/src/hero/moverImpl.ts
- packages-user/data-base/src/hero/mover.ts
- packages-user/data-state/src/core.ts
- packages-user/data-state/src/index.ts
- packages/common/src/logger.json
- .planning/phases/02-pathfinding/deferred-items.md
key-decisions:
- "通行性判定从 DefaultHeroMoveTopImpl 提取为 IPassPredicate反向方向由 FaceDirection 映射计算,不再依赖 handler.face"
- "D-08 no-pass 目标沿可达相邻格完成移动后直接派发 OnTouch并让勇士面朝目标"
- "新寻路调用通过 queued controller 实现 stop 后 await再从旧步兑现后的坐标接管"
- "路径错误启动增加 error 65已有寻路告警继续使用 warn 173/174保持数字码集中登记"
requirements-completed: [PATH-01, PATH-02]
# Coverage metadata (#1602)
coverage:
- id: D1
description: "Hero mover 通行性判断重构为 IPassPredicatePhase 1 enter/leave/hit 行为保持"
requirement: PATH-01
verification:
- kind: unit
ref: "packages-user/data-state/src/coreEventLayer.test.ts (1 passed)"
status: pass
- kind: unit
ref: "packages-user/data-base/src (16 passed)"
status: pass
human_judgment: false
- id: D2
description: "HeroPathfinding 逐步移动沿最小路径执行,途经 OnEnter/OnLeave 事件链自然触发"
requirement: PATH-01
verification:
- kind: integration
ref: "packages-user/data-state/src/path/heroPathfinding.test.ts#moves the hero to the target and triggers the traversed event"
status: pass
human_judgment: false
- id: D3
description: "瞬移、路径事件默认回退、D-08 相邻格 OnTouch/面朝与不可达空路径语义"
requirement: PATH-01
verification:
- kind: integration
ref: "packages-user/data-state/src/path/heroPathfinding.test.ts (7 passed: teleport/fallback/D-08)"
status: pass
human_judgment: false
- id: D4
description: "新寻路与显式 interrupt 采用 stop-then-await 接管,旧移动停止后可再次启动"
requirement: PATH-01
verification:
- kind: integration
ref: "packages-user/data-state/src/path/heroPathfinding.test.ts#hands over a moving path to a new target"
status: pass
- kind: integration
ref: "packages-user/data-state/src/path/heroPathfinding.test.ts#leaves the mover restartable after explicit interruption"
status: pass
human_judgment: false
- id: D5
description: "CoreState/barrel 装配、logger 数字码与阶段质量门禁"
requirement: PATH-02
verification:
- kind: other
ref: "logger.json enumeration: warn 173/174 and error 65 unique; check:circular path filter empty"
status: pass
- kind: other
ref: "target-file eslint: 0 problems; full vitest: 11 files, 65 tests passed"
status: pass
human_judgment: true
rationale: "Repository-wide type gate retains two pre-existing CoreState TileStore diagnostics and lint:user retains unrelated client/legacy diagnostics; both are recorded in deferred-items.md."
# Metrics
duration: 30min
completed: 2026-09-09
status: complete
---
# Phase 02 Plan 03: L3 寻路接线 Summary
**HeroPathfinding 数据端闭环:共享 IPassPredicate 的逐步/瞬移执行、事件回退、D-08 相邻格触碰与可接管中断控制器**
## Performance
- **Duration:** 30 min
- **Started:** 2026-09-09T12:55:00Z
- **Completed:** 2026-09-09T13:24:37Z
- **Tasks:** 4
- **Files modified:** 9 implementation/test/config files plus planning ledgers
## Accomplishments
- Task 1 将 `DefaultHeroMoveTopImpl` 的掩码与 `eventPass` 判定提取为 `IPassPredicate`HeroMover 改为构造 `IPassCheckHandler` 调用 predicate既有事件回归全绿
- Task 2 新建并装配 `HeroPathfinding`,将 hero predicate、地图事件层和 mover 绑定到 L2逐步路径真实执行并触发途经事件
- Task 3 实现无事件路径瞬移、事件路径默认逐步回退、D-08 no-pass 相邻格 + OnTouch + 面朝,以及四邻不可达空路径
- Task 4 实现 queued controller 接管与显式 interrupt登记 error 65并完成 65 个全量 Vitest 测试与路径循环依赖门禁
## Task Commits
Each task was committed atomically:
1. **Task 1: moverImpl 通行性判断重构为 IPassPredicate** - `68a1508` (refactor)
2. **Task 2: 逐步自动寻路端到端接线** - `2759df5` (feat)
3. **Task 3: 瞬移、回退策略与 D-08 相邻格触碰** - `6cde84e` (feat)
4. **Task 4: 打断接管、logger 码与阶段门禁** - `7a3b6e3` (fix)
## Files Created/Modified
- `packages-user/data-state/src/hero/moverImpl.ts` - 共享 hero 通行性 predicate 与原有事件 hooks
- `packages-user/data-base/src/hero/mover.ts` - predicate 调用点与完整 pass-check handler
- `packages-user/data-state/src/path/heroPathfinding.ts` - L3 寻路、回退、D-08、接管控制器
- `packages-user/data-state/src/path/heroPathfinding.test.ts` - 逐步、瞬移、回退、D-08、interrupt 集成测试
- `packages-user/data-state/src/core.ts` - CoreState 寻路系统初始化
- `packages-user/data-state/src/index.ts` / `path/index.ts` - data-state barrel 导出
- `packages/common/src/logger.json` - error 65合并已有 warn 173/174
- `.planning/phases/02-pathfinding/deferred-items.md` - 记录未触碰的 CoreState 泛型与 legacy lint 基线
## Decisions Made
- 延续用户拍板的方案 AD-08 触碰事件在相邻格移动完成后通过 `IGameEventInvocation` 直接执行
- 由于接口是同步返回 controller接管使用 queued controller 暴露稳定的 `onEnd`,内部仍严格 stop → await → 重算 → start
- 渲染端点击接线保持延后至 Phase 4本计划只暴露并验证数据端入口
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 1 - Bug] 补齐 IPassCheckHandler 的 state 字段**
- **Found during:** Task 2 type gate
- **Issue:** predicate 契约继承 `IDataCommonExtended`,初始调用对象缺少 `state`,阻塞严格类型检查
- **Fix:** 从既有 hero handler 转发 `state`,保持 predicate 所需完整契约
- **Files modified:** `packages-user/data-base/src/hero/mover.ts`
- **Verification:** path 集成测试、全量 Vitest 与目标 ESLint 通过
- **Committed in:** `2759df5`
**2. [Rule 2 - Missing Critical] 为 mover 已激活竞争登记 logger error 65**
- **Found during:** Task 4 logger gate
- **Issue:** L3 启动路径在底层 mover 仍激活时只能静默返回 null缺少数字码诊断
- **Fix:** 登记并调用 error 65warn 173/174 与既有寻路诊断保持不变
- **Files modified:** `packages-user/data-state/src/path/heroPathfinding.ts`, `packages/common/src/logger.json`
- **Verification:** logger enumeration confirms unique warn 173/174 and error 65
- **Committed in:** `7a3b6e3`
---
**Total deviations:** 2 auto-fixed (1 bug, 1 missing critical diagnostic)
**Impact on plan:** Both fixes are directly required for strict predicate correctness and observable mover handoff failures; no architectural scope expansion.
## Issues Encountered
- `pnpm check:type` still reports the two pre-existing `data-state/src/core.ts` TileStore generic diagnostics; the new path files and mover predicate call chain add no diagnostics. Recorded in `deferred-items.md`.
- `pnpm lint:user` still reports 52 errors in untouched `client-modules` and `legacy-plugin-*` files; plan-owned files pass ESLint and the baseline is recorded in `deferred-items.md`.
- Existing CoreState serialized event registration TODO remains intentionally deferred from Phase 1 and is already tracked in `WINDOWS.md` entry 1; it is unrelated to this plan.
## Known Stubs
| File | Location | Reason |
| ---- | ---- | ---- |
| `packages-user/data-state/src/core.ts` | line 156 | Pre-existing serialized event registration/map-id binding TODO from Phase 1; not part of pathfinding and already tracked in the broken-windows ledger |
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- PATH-01 data端自动寻路闭环已具备 Node 验证PATH-02 的渲染端点击接线仍按 D-11 留给 Phase 4
- Phase 02 plans are complete and ready for phase-level verification/transition
- Repository-wide type/lint baseline issues remain open as documented; they do not affect the plan-owned pathfinding tests, circular dependency scan, or target-file lint
---
*Phase: 02-pathfinding*
*Completed: 2026-09-09*
## Self-Check: PASSED
- All three created path files exist; all four task commits (`68a1508`, `2759df5`, `6cde84e`, `7a3b6e3`) are present in git history
- Verification rerun: full Vitest 11 files / 65 tests passed; core event regression 1 passed; data-base tests 16 passed; path circular filter empty; target-file ESLint 0 problems
- `requirements-completed` copies `[PATH-01, PATH-02]`; shared requirement status is advanced only after this SUMMARY is present
- Known pre-existing type/lint issues are explicitly recorded in `deferred-items.md`; no untracked generated files remain

View File

@ -16,3 +16,8 @@
**What:** `CoreState` 原有 `TileStore<LegacyTileData>` 装配在 `this.tileStore``MapState` 构造处
被仓库当前接口泛型诊断命中;本计划仅在同一构造器追加寻路接线,不改变既有 TileStore 契约,
按范围边界规则留给后续数据层类型收口。
- packages-user/ 下的既有 lint:user 诊断52 errors集中在 client-modules 与 legacy-plugin-*
status: open
**What:** 阶段门禁 `pnpm lint:user` 仍被本计划未修改的渲染与 legacy 文件阻塞;计划归属文件的
ESLint 检查为 0 problems按范围边界规则不修复无关基线问题。

View File

@ -36,8 +36,8 @@
],
"next": {
"command": "/gsd:progress --next",
"label": "Advance to the next step",
"reason": "Phase 02 of 6 · executing"
"label": "Advance to the next step (verify)",
"reason": "Phase 02 of 6 · ready to verify"
},
"updated_at": "2026-09-09T09:37:11.395Z"
"updated_at": "2026-09-09T13:26:44.161Z"
}