diff --git a/.planning/phases/07-data-fixes/.continue-here.md b/.planning/phases/07-data-fixes/.continue-here.md new file mode 100644 index 0000000..5213cda --- /dev/null +++ b/.planning/phases/07-data-fixes/.continue-here.md @@ -0,0 +1,45 @@ +# Phase 7 — 接力说明(07-16 暂缓,等数据端改完再启动) + +**更新:** 2026-09-17(晚) +**HEAD:** 见 `git log -1`(分支 `refactor/data`) + +## 当前状态:**Phase 7 暂缓** + +- `07-01..07-15` 全部已执行并提交。 +- `07-16`(寻路重构后的测试对齐)**已完成规划,但暂缓(DEFERRED)** —— 用户仍在手工重构数据端,接口/形状还会继续变,测试会持续报错。 + +## 为什么暂缓(用户原话) +> 「数据端还有很多内容需要我手动修改,还会导致大量的测试文件报错。所以此计划暂缓,等待我把数据端全部修改完毕后再进行。」 + +## 恢复时的第一件事(重要) +1. **重新测量**:跑一次 `pnpm test:ci`,得到**最新**的失败清单。 +2. **重新核对 / 重规划**: + - `07-VERIFICATION.md` 的 `### Post-Refactor Test Breakage`(2026-09-17 快照,**很可能已过期**) + - `07-16-PLAN.md`(很可能需要按新清单重规划,而不是直接执行) +3. 重规划走:`/gsd-plan-phase 7 --gaps`(必要时先更新缺口清单)。 +4. 执行走:`/gsd-execute-phase 7 --gaps-only`(Task 0 的 Q1..Q4/R1..R3 需用户逐条裁决)。 +5. 收尾走:`/gsd-verify-work 7` 重出验证。 + +## 已知的 07-16 规划要点(供重规划参考) +- 目标:把失败测试文件**对齐到已发布的接口**,**只改测试、不改生产代码**。 +- 已查明的真实替代接口(规划时从源码读出,非猜测): + - 寻路:`useMapState` 已删除且无替代(宽度改由 `MapGraphBuilder.useMapLayer` → `indexer.setWidth(layer.width)`);`useDirGroup(number)` → `useFaceHandler(IFaceHandler)`(`Dir4FaceHandler`/`Dir8FaceHandler`);builder `face` 默认改为 `null`,每个 `build()/find()` 需显式注入;`DefaultPassPredicateImpl(state.maps)` → `(state)`。 + - 录像:`ReplaySystem.array`;`onRecordCommand(code, array.length - 1, …)` → 首步索引期望 `1`→`0`;测试本地 `ReplaySystemStub` 的 `route` 需改 `array`。 + - 位置/楼层:`setFloor(map: IGameMap)` + 新增 `location.map`(`location.ts:24/49`);`IHeroChangeFloorInfo.target: IGameMap`;16 处残留 `setFloor()`。 + - `CoreState.initMapState` 已全仓删除(仅 `coreEventLayer.test.ts` 引用)→ 需裁决「改指向 `MapState.fromRaw` 还是退役」。 +- 07-16 初版 `files_modified`:17 个测试文件 + `data-state/test/fixtures/closed-loop.ts`(共 18 条,均已跟踪)。 + +## 仍待处理的遗留 +1. **07-15 的 CR-01 见证仍红**:唯一原因是你 `a2a8e6e` 把 `ReplaySystem.route` 改名 `array` 时漏了 `hero/equipment.test.ts` 的本地 `ReplaySystemStub`。生产修复(`53f067a`)已提交并经反向验证正确。**07-16 恢复时会顺带修好**。 +2. `07-VERIFICATION.md` 状态为 `gaps_found`(含已暂缓的测试缺口)→ Phase 7 最终必须 `/gsd-verify-work 7`。 +3. `ROADMAP.md` 的 Phase 7 进度行为 `15/16 · 暂缓 (Deferred)`。 + +## 未提交的用户在途改动(**禁止纳入任何提交**) +- 执行 `git status --short` 查看;当前可能含 `packages-user/data-state/src/core.ts`、`packages/common/src/dirtyTracker.ts` 等。 +- **提交时只 stage 计划声明的文件**,绝不 `git add -A` / `git commit -a` / `git stash`。 + +## 长期纪律(用户 2026-09-17) +- 并行改动导致的**类型错误**与**测试失败**,若不落在本计划声明的路径上:**不理会、不修、不登记**。 +- 不得 amend 已推送提交。 +- 任何方法/字段命名,执行前须经用户批准。 +- 执行任何计划前,先向用户汇报计划内容并取得确认。 diff --git a/packages-user/data-base/src/hero/follower.ts b/packages-user/data-base/src/hero/follower.ts index 16e0fe9..ac933b4 100644 --- a/packages-user/data-base/src/hero/follower.ts +++ b/packages-user/data-base/src/hero/follower.ts @@ -2,12 +2,12 @@ import { Hookable, HookController, IHookController, - logger + logger, + IFaceHandler } from '@motajs/common'; import { FaceDirection, IDataCommon, - IFaceHandler, IFacedTileLocator, SaveCompression } from '@user/data-common'; diff --git a/packages-user/data-base/src/hero/location.ts b/packages-user/data-base/src/hero/location.ts index 7f410f4..caca751 100644 --- a/packages-user/data-base/src/hero/location.ts +++ b/packages-user/data-base/src/hero/location.ts @@ -1,8 +1,12 @@ -import { Hookable, HookController, IHookController } from '@motajs/common'; +import { + Hookable, + HookController, + IHookController, + IFaceHandler +} from '@motajs/common'; import { FaceDirection, IDataCommon, - IFaceHandler, IFacedTileLocator } from '@user/data-common'; import { HeroMover } from './mover'; diff --git a/packages-user/data-base/src/hero/mover.ts b/packages-user/data-base/src/hero/mover.ts index 1ed7873..8e3f10e 100644 --- a/packages-user/data-base/src/hero/mover.ts +++ b/packages-user/data-base/src/hero/mover.ts @@ -1,7 +1,6 @@ -import { ITileLocator, logger } from '@motajs/common'; +import { ITileLocator, logger, IFaceHandler } from '@motajs/common'; import { FaceDirection, - IFaceHandler, IMoverController, ObjectMoveStep, ObjectMover, diff --git a/packages-user/data-base/src/hero/state.ts b/packages-user/data-base/src/hero/state.ts index b48c8d8..443f80e 100644 --- a/packages-user/data-base/src/hero/state.ts +++ b/packages-user/data-base/src/hero/state.ts @@ -20,11 +20,15 @@ import { import { FaceDirection, IDataCommon, - IFaceHandler, IFacedTileLocator, SaveCompression } from '@user/data-common'; -import { Hookable, HookController, IHookController } from '@motajs/common'; +import { + Hookable, + HookController, + IHookController, + IFaceHandler +} from '@motajs/common'; export class HeroState extends Hookable diff --git a/packages-user/data-base/src/hero/types.ts b/packages-user/data-base/src/hero/types.ts index 4f7cd4c..54abe15 100644 --- a/packages-user/data-base/src/hero/types.ts +++ b/packages-user/data-base/src/hero/types.ts @@ -1,8 +1,12 @@ -import { IHookBase, IHookable, ITileLocator } from '@motajs/common'; +import { + IHookBase, + IHookable, + ITileLocator, + IFaceHandler +} from '@motajs/common'; import { FaceDirection, IDataCommonExtended, - IFaceHandler, IFacedTileLocator, IItemRawData, IObjectMovable, diff --git a/packages-user/data-common/src/common/faceManager.ts b/packages-user/data-common/src/common/faceManager.ts index 66df2b0..d46c362 100644 --- a/packages-user/data-common/src/common/faceManager.ts +++ b/packages-user/data-common/src/common/faceManager.ts @@ -1,3 +1,4 @@ +import { IFaceDescriptor, IFaceHandler } from '@motajs/common'; import { FaceDirection } from './types'; //#region 接口与枚举 @@ -9,60 +10,6 @@ export const enum FaceGroup { Dir8 } -export interface IFaceDescriptor { - /** 横坐标增量 */ - readonly x: number; - /** 纵坐标增量 */ - readonly y: number; -} - -export interface IFaceHandler { - /** - * 将任意朝向值降级为本组支持的方向。 - * 对于无法合理降级的方向(包括 `Unknown`),返回 `FaceDirection.Unknown` - * @param dir 任意朝向值 - */ - degrade(dir: number): T; - - /** - * 获取指定方向的单步坐标偏移量,输入先经过 `degrade` - * @param dir 朝向 - */ - movement(dir: number): IFaceDescriptor; - - /** - * 获取指定方向走 `count` 步的坐标偏移量,等价于 `movement * count`。 - * `count` 允许为负数,表示反向位移,输入先经过 `degrade` - * @param dir 朝向 - * @param count 步数,允许为负 - */ - move(dir: number, count: number): IFaceDescriptor; - - /** - * 获取本组内的反方向,输入先经过 `degrade`,`Unknown` 返回 `Unknown` - * @param dir 朝向 - */ - opposite(dir: number): T; - - /** - * 在本组方向集合内顺时针(默认)或逆时针旋转一步,输入先经过 `degrade`, - * `Unknown` 返回 `Unknown` - * @param dir 朝向 - * @param anticlockwise 是否逆时针,默认顺时针 - */ - next(dir: number, anticlockwise?: boolean): T; - - /** - * 迭代本组支持的所有朝向,包含 `Unknown` - */ - mapDirection(): Iterable; - - /** - * 迭代本组所有朝向及其对应的坐标描述器,包含 `Unknown`(对应 `{ x: 0, y: 0 }`) - */ - mapMovement(): Iterable<[T, IFaceDescriptor]>; -} - export interface IFaceManager { /** * 以数字 key 注册一个 handler diff --git a/packages-user/data-common/src/common/mover.ts b/packages-user/data-common/src/common/mover.ts index 23b2264..843b751 100644 --- a/packages-user/data-common/src/common/mover.ts +++ b/packages-user/data-common/src/common/mover.ts @@ -4,10 +4,10 @@ import { IHookable, IHookBase, IHookController, - ITileLocator + ITileLocator, + IFaceHandler } from '@motajs/common'; import { FaceDirection } from './types'; -import { IFaceHandler } from './faceManager'; //#region 对象移动 diff --git a/packages-user/data-state/src/core.ts b/packages-user/data-state/src/core.ts index 2f9b476..168007f 100644 --- a/packages-user/data-state/src/core.ts +++ b/packages-user/data-state/src/core.ts @@ -1,4 +1,4 @@ -import { DirectionMapper, IDirectionMapper, logger } from '@motajs/common'; +import { logger } from '@motajs/common'; import { ILoadProgressTotal, LoadProgressTotal } from '@motajs/loader'; import { IRoleFaceBinder, @@ -79,7 +79,6 @@ export class CoreState implements ICoreState { readonly itemStore: IItemStore; readonly mapStore: IMapStore; readonly eventStore: IGameEventStore; - readonly directionMapper: IDirectionMapper; readonly replaySystem: IReplaySystem; // Layer 1 数据层,所有可存档内容都在这,一般用于数据存储 @@ -128,7 +127,6 @@ export class CoreState implements ICoreState { this.mapStore = new MapStore(); // 游戏事件 this.eventStore = new GameEventStore(); - this.directionMapper = new DirectionMapper(); //#endregion diff --git a/packages-user/data-state/src/enemy/mapDamage.ts b/packages-user/data-state/src/enemy/mapDamage.ts index 4e876bb..6b5a152 100644 --- a/packages-user/data-state/src/enemy/mapDamage.ts +++ b/packages-user/data-state/src/enemy/mapDamage.ts @@ -7,7 +7,8 @@ import { RayRange, RectRange, ITileLocator, - IDirectionDescriptor + IFaceHandler, + IFaceDescriptor } from '@motajs/common'; import { IEnemyContext, @@ -26,7 +27,7 @@ import { import { IZoneValue } from './special'; import { MapDamageType } from './types'; import { IHeroAttr, IEnemyAttr } from '@user/data-common'; -import { IFaceHandler, FaceGroup } from '@user/data-common'; +import { FaceGroup } from '@user/data-common'; const RECT_RANGE = new RectRange(); const MANHATTAN_RANGE = new ManhattanRange(); @@ -153,7 +154,7 @@ export class RepulseDamageView extends BaseMapDamageView { export class LaserDamageView extends BaseMapDamageView { /** 激光方向列表 */ - private readonly dirs: IDirectionDescriptor[]; + private readonly dirs: IFaceDescriptor[]; constructor( context: IEnemyContext, diff --git a/packages-user/data-system/src/path/finder.ts b/packages-user/data-system/src/path/finder.ts index 9a02adc..64be77b 100644 --- a/packages-user/data-system/src/path/finder.ts +++ b/packages-user/data-system/src/path/finder.ts @@ -1,4 +1,4 @@ -import { ITileLocator, logger } from '@motajs/common'; +import { ITileLocator, logger, IFaceHandler } from '@motajs/common'; import { IMapLayer, IPassPredicate, IStateBase } from '@user/data-base'; import { isNil } from 'lodash-es'; import { MapGraphBuilder } from './graph'; @@ -11,7 +11,6 @@ import { IPathfindingResult, PathfindingStatus } from './types'; -import { IFaceHandler } from '@user/data-common'; interface IDistanceHeapEntry { /** 条目的键值,堆中键值最小的条目最先取出 */ diff --git a/packages-user/data-system/src/path/graph.ts b/packages-user/data-system/src/path/graph.ts index 147d137..f89211c 100644 --- a/packages-user/data-system/src/path/graph.ts +++ b/packages-user/data-system/src/path/graph.ts @@ -1,9 +1,5 @@ -import { ITileLocator, logger } from '@motajs/common'; -import { - IFaceHandler, - ILocationIndexer, - MapLocIndexer -} from '@user/data-common'; +import { ITileLocator, logger, IFaceHandler } from '@motajs/common'; +import { ILocationIndexer, MapLocIndexer } from '@user/data-common'; import { ILayerLocation, IMapLayer, diff --git a/packages-user/data-system/src/path/types.ts b/packages-user/data-system/src/path/types.ts index 0bbe769..ba4de7f 100644 --- a/packages-user/data-system/src/path/types.ts +++ b/packages-user/data-system/src/path/types.ts @@ -1,4 +1,4 @@ -import { ITileLocator } from '@motajs/common'; +import { ITileLocator, IFaceHandler } from '@motajs/common'; import { IDataBaseExtended, ILayerLocation, @@ -6,7 +6,6 @@ import { IPassPredicate } from '@user/data-base'; import { - IFaceHandler, ILocationHelper, IMoverController, IObjectMovable, diff --git a/packages/common/src/dirtyTracker.ts b/packages/common/src/dirtyTracker.ts index 4ca0ce6..cde55e2 100644 --- a/packages/common/src/dirtyTracker.ts +++ b/packages/common/src/dirtyTracker.ts @@ -41,9 +41,9 @@ export class PrivateBooleanDirtyTracker implements IDirtyTracker { /** * 列表的脏标记追踪器。当传入 `dirtySince` 的标记不属于当前的追踪器时,会返回空集合 */ -export class PrivateListDirtyTracker - implements IDirtyTracker> -{ +export class PrivateListDirtyTracker implements IDirtyTracker< + Set +> { /** 标记映射,键表示在索引,值表示其对应的标记数字 */ private readonly markMap: Map = new Map(); /** 标记 symbol 映射,值表示这个 symbol 对应的标记数字 */ @@ -89,9 +89,9 @@ export class PrivateListDirtyTracker } } -export class PrivateMapDirtyTracker - implements IDirtyTracker> -{ +export class PrivateMapDirtyTracker implements IDirtyTracker< + Record +> { /** 标记映射,键表示名称,值表示其对应的标记数字 */ private readonly markMap: Map = new Map(); /** 标记 symbol 映射,值表示这个 symbol 对应的标记数字 */ diff --git a/packages/common/src/utils/dir.ts b/packages/common/src/utils/dir.ts deleted file mode 100644 index 8fc979d..0000000 --- a/packages/common/src/utils/dir.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { - IDirectionDescriptor, - IDirectionMapper, - InternalDirectionGroup -} from './types'; - -export class DirectionMapper implements IDirectionMapper { - private readonly groups: Map = new Map(); - - constructor() { - this.registerGroup(InternalDirectionGroup.Dir4, [ - { x: 0, y: -1 }, - { x: 0, y: 1 }, - { x: -1, y: 0 }, - { x: 1, y: 0 } - ]); - this.registerGroup(InternalDirectionGroup.Dir8, [ - { x: 0, y: -1 }, - { x: 0, y: 1 }, - { x: -1, y: 0 }, - { x: 1, y: 0 }, - { x: -1, y: -1 }, - { x: 1, y: -1 }, - { x: -1, y: 1 }, - { x: 1, y: 1 } - ]); - } - - registerGroup(group: number, dir: Iterable): void { - this.groups.set(group, [...dir]); - } - - map(group: number): Iterable { - return this.groups.get(group) ?? []; - } -} diff --git a/packages/common/src/utils/index.ts b/packages/common/src/utils/index.ts index 69432d0..ce636b2 100644 --- a/packages/common/src/utils/index.ts +++ b/packages/common/src/utils/index.ts @@ -1,4 +1,3 @@ -export * from './dir'; export * from './func'; export * from './range'; export * from './types'; diff --git a/packages/common/src/utils/range.ts b/packages/common/src/utils/range.ts index f48c35b..6eb43d1 100644 --- a/packages/common/src/utils/range.ts +++ b/packages/common/src/utils/range.ts @@ -1,11 +1,11 @@ import { clamp } from 'lodash-es'; import { - IDirectionDescriptor, IManhattanRangeParam, IRangeHost, IRange, IRayRangeParam, - IRectRangeParam + IRectRangeParam, + IFaceDescriptor } from './types'; export abstract class BaseRange implements IRange { @@ -156,7 +156,7 @@ export class RayRange extends BaseRange { private isPointOnRay( x: number, y: number, - direction: IDirectionDescriptor, + direction: IFaceDescriptor, param: Readonly ): boolean { if (direction.x === 0 && direction.y === 0) { diff --git a/packages/common/src/utils/types.ts b/packages/common/src/utils/types.ts index 39784d6..acc6c90 100644 --- a/packages/common/src/utils/types.ts +++ b/packages/common/src/utils/types.ts @@ -128,7 +128,7 @@ export interface IRayRangeParam { /** 中心点纵坐标 */ cy: number; /** 方向列表 */ - dir: IDirectionDescriptor[]; + dir: IFaceDescriptor[]; } //#endregion @@ -142,33 +142,58 @@ export interface ITileLocator { y: number; } -export const enum InternalDirectionGroup { - /** 上下左右四方向 */ - Dir4, - /** 上下左右+左上+右上+左下+右下八方向 */ - Dir8 -} - -export interface IDirectionDescriptor { +export interface IFaceDescriptor { /** 横坐标增量 */ readonly x: number; /** 纵坐标增量 */ readonly y: number; } -export interface IDirectionMapper { +export interface IFaceHandler { /** - * 注册一个方向组别 - * @param group 方向组别 - * @param dir 方向锁包含的描述器 + * 将任意朝向值降级为本组支持的方向。 + * 对于无法合理降级的方向(包括 `Unknown`),返回 `FaceDirection.Unknown` + * @param dir 任意朝向值 */ - registerGroup(group: number, dir: Iterable): void; + degrade(dir: number): T; /** - * 根据指定方向组别进行遍历 - * @param group 方向组别 + * 获取指定方向的单步坐标偏移量,输入先经过 `degrade` + * @param dir 朝向 */ - map(group: number): Iterable; + movement(dir: number): IFaceDescriptor; + + /** + * 获取指定方向走 `count` 步的坐标偏移量,等价于 `movement * count`。 + * `count` 允许为负数,表示反向位移,输入先经过 `degrade` + * @param dir 朝向 + * @param count 步数,允许为负 + */ + move(dir: number, count: number): IFaceDescriptor; + + /** + * 获取本组内的反方向,输入先经过 `degrade`,`Unknown` 返回 `Unknown` + * @param dir 朝向 + */ + opposite(dir: number): T; + + /** + * 在本组方向集合内顺时针(默认)或逆时针旋转一步,输入先经过 `degrade`, + * `Unknown` 返回 `Unknown` + * @param dir 朝向 + * @param anticlockwise 是否逆时针,默认顺时针 + */ + next(dir: number, anticlockwise?: boolean): T; + + /** + * 迭代本组支持的所有朝向,包含 `Unknown` + */ + mapDirection(): Iterable; + + /** + * 迭代本组所有朝向及其对应的坐标描述器,包含 `Unknown`(对应 `{ x: 0, y: 0 }`) + */ + mapMovement(): Iterable<[T, IFaceDescriptor]>; } //#endregion