mirror of
https://github.com/motajs/template.git
synced 2026-09-24 18:50:24 +08:00
docs(06-18): flag MainEnemyComparer as intentionally uncovered
This commit is contained in:
parent
7ad903f156
commit
0da0117cd4
@ -64,7 +64,7 @@ must_haves:
|
||||
- "**`resize` 必须在放置怪物之前**(`context.ts` L105–111 → `clear()` L897–914):`resize` 会清空全部怪物、`damageSystem.markAllDirty()` 并 `mapDamage.refreshAll()`;CoreState 默认 `resize(13,13)` 必须被覆盖成合并尺寸,否则 `52×52` 的坐标会算出越界索引。"
|
||||
- "**`setEnemyAt` 会触发 `MapDamage` 全量刷新**(`context.ts` L291–296 → `mapDamage.markEnemyDirty(view)`;`mapDamage.ts` L135–148 对新视图走 `refreshAll()`):放置 N 只怪的夹具构建成本约为 O(N²) 的点级刷新(N=204 时约 2 万次),这是**夹具构建**成本、不计入耗时,但它是 9 个 `it` 各自建一次夹具的主要开销来源;若某 `it` 逼近 `testTimeout`(30000ms),按 D-07 暂停汇报,**不得**改规模或超时。"
|
||||
- "**`enemyManager.createEnemy(code)` 可能返回 `null`**(`data-base/src/enemy/manager.ts` L119–123):夹具用 `if (!enemy) throw new Error('性能夹具:找不到怪物模板 ' + code)` 作**夹具完整性**保护(与 `enemyCombination.test.ts` L214–215 的 `if (!enemy) throw new Error(...)` 同构);这是夹具自检、不是性能断言,不违反「零断言」。"
|
||||
- "**`EnemyManager.compareWith` 本计划不调用**:不做存读档,`hasReference` 为假时 `updateDirty` 直接返回(`manager.ts` L276–289),故不会出现 `warn(117)`、也不会把怪物写进存档;**不要**为「更真实」补 `compareWith`(会引入与本计划无关的存档语义)。"
|
||||
- "**`EnemyManager.compareWith` 本计划不调用**:不做存读档,`hasReference` 为假时 `updateDirty` 直接返回(`manager.ts` L276–289),故不会出现 `warn(117)`、也不会把怪物写进存档;**不要**为「更真实」补 `compareWith`(会引入与本计划无关的存档语义与 dirty 集合语义)。**相应后果须如实记录**:用户批准设计里列出的 `MainEnemyComparer` 在本场景中**不会被触达**(它只在 `EnemyManager.compareWith` 的 `updateDirty`/`refreshDirty` 里被调用,`manager.ts` L237–243 / L294–311),SUMMARY 必须把这一条按「未覆盖 + 原因」写进实现风险;若用户要求覆盖它,需在夹具里对 `state.enemyManager` 调用一次 `compareWith(参考模板表)`(CoreState 已 `attachEnemyComparer`,首次调用不告警,但会带来存档 dirty 语义),按 D-07 先确认再改。"
|
||||
- "**`registerSpecials` 的解释口径(须如实记录,不得含糊)**:CoreState 构造函数已调用 `registerSpecials(enemyManager)`(`data-state/src/enemy/special.ts` L51),本计划**不**再走 `fromLegacyEnemy` 的 legacy 转换路径来生成特殊属性(仓库内无任何测试先例,且 legacy `Enemy` 类型字段繁多,`src/types/declaration/enemy.d.ts`);特殊属性改用既有集成测试 `enemyCombination.test.ts` L55–74 的**内联 `createSpecial`** 写法,配 `enemyManager.addPrefab(prefab)` + `createEnemy(code)` 的真实 `EnemyManager` 路径。即:`registerSpecials` 的**注册**确实发生,但模板的特殊属性实例是内联构造的——SUMMARY 必须写明这一点,不得表述为「经 legacy 转换注册」。"
|
||||
- "**计时口径变更会作废既有表述**:06-16/06-17 SUMMARY 里「计时源 `globalThis.performance.now()`」对**改造后**的 lane 不再成立;按 06-16/06-17 的禁令**不修改**这两个 SUMMARY,只在 `06-18-SUMMARY.md` 中显式说明「45 行既有数字为 mark/measure 改造**之前**的口径,不可与本次新增 9 行直接对比」,并记录本次全 lane 运行的实测结果。"
|
||||
- "**临界项必须完整消费生成器**:`for (const _critical of damageSystem.calculateCritical(view, 'atk')) { /* 完整消费临界枚举 */ }`——只取生成器不迭代则测不到二分枚举的真实开销(06-16 ② 的既有写法与注释形态);`_` 前缀用于通过 `@typescript-eslint/no-unused-vars` 的 `varsIgnorePattern: '^_'`。若 eslint 对解构出的 `_` 仍报未使用,改用 `for (const entry of state.enemyContext.iterateEnemy())` + `const view = entry[1];` 的写法(保持「只用到的变量才声明」)。"
|
||||
@ -347,7 +347,7 @@ Output: `packages-user/data-state/test/mapScenario.perf.ts`(9 行主表 + 3
|
||||
`bindHero` + `buildup()`;`bindHero` 会顺带执行 `damageSystem.bindHeroStatus`(清伤害缓存)与 `mapDamage.refreshAll()`(全量地图伤害重建),因此 ① **不是**裸 `buildup()`,而是「光环拓扑重建 + 光环施加 + 最终效果 + 伤害缓存清空 + 一次地图伤害重建」;若用户要裸 `buildup()`,按 key_links 第 3 条的替代方案另行裁决。
|
||||
- **② 的样本组成**:`mapDamage.refreshAll()` + 对每个怪物坐标 `getSeparatedDamage` / `getReducedDamage`(含真实 reducer 合并);说明 `refreshAll()` 会清空来源状态与缓存,故每个样本都是完整的重建而非缓存命中。
|
||||
- **③ 的样本组成与汇总口径**:每只怪一次 `calculateCritical(view, 'atk')` 并完整消费生成器;`total ms` / `avg ms` 的定义与「中位总量 / 怪物数 = 单怪平均中位数」的等价性;说明 `getDamageInfo` 未单独计时(`calculateCritical` 内部即 `calculator.calculate(handler)`)。
|
||||
- **实现解释口径(必须如实写,不得表述为经 legacy 转换)**:`registerSpecials(enemyManager)` 由 `CoreState` 构造函数调用(**注册确实发生**),但 12 个模板的特殊属性实例是**内联 `createSpecial`** 构造的(镜像既有集成测试 `enemyCombination.test.ts`),本计划**未**走 `fromLegacyEnemy` 的 legacy 转换路径(仓库内无先例、legacy `Enemy` 类型字段繁多);真实被驱动的是 `CommonAuraConverter` / `GuardAuraConverter` / `MainEnemyFinalEffect` / `MainDamageCalculator` / `MainMapDamageConverter` / `MainMapDamageReducer` 这几个**真实实现**。
|
||||
- **实现解释口径(必须如实写,不得表述为经 legacy 转换)**:`registerSpecials(enemyManager)` 由 `CoreState` 构造函数调用(**注册确实发生**),但 12 个模板的特殊属性实例是**内联 `createSpecial`** 构造的(镜像既有集成测试 `enemyCombination.test.ts`),本计划**未**走 `fromLegacyEnemy` 的 legacy 转换路径(仓库内无先例、legacy `Enemy` 类型字段繁多);真实被驱动的是 `CommonAuraConverter` / `GuardAuraConverter` / `MainEnemyFinalEffect` / `MainDamageCalculator` / `MainMapDamageConverter` / `MainMapDamageReducer` 这几个**真实实现**;**`MainEnemyComparer` 未被触达**(只在 `EnemyManager.compareWith` 里被调用,本计划不建存档基线),须按「未覆盖 + 原因」如实记录。
|
||||
- **全局 `core` stub**:因为 `BetweenDamageView` 读 `core.flags.betweenAttackMax`,本文件在 `vi.hoisted` 里 stub 了 `core`(`{ flags: { betweenAttackMax: false } }`,与 `mapDamage.test.ts` L21 同构);如实的含义是「该分支在 Node 下必须由外部注入 `core`」。
|
||||
- **测量参数表**:预热 3 不计时、采样 20、下中位数/`min`/`p95` 口径、`toFixed(3)`、计时源 `globalThis.performance.mark/measure`(含标记命名与清理规则)、`testTimeout` 30000ms 与是否有 case 逼近它(**D-07 判据**:记录最慢 case 的 median/p95 及占超时预算的比例)。
|
||||
- **运行环境**:Node 版本 / 平台(实测 `node v22.18.0` / `win32`)/ `pnpm` 版本 / vitest 版本(devDependencies 写的是 `^4.0.18`,以实际运行为准)/ CPU 型号(如可得)。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user