Commit Graph

546 Commits

Author SHA1 Message Date
0fcb101c8b chore(07-13): sync machine-readable state after plan 13 2026-09-17 17:39:16 +08:00
d92e405dc2 docs(07-13): complete map invalidation boundaries plan 2026-09-17 17:38:23 +08:00
13234b762a fix(07-13): clear existing dynamic tiles before loading
- add private clearDynamics() that snapshots the managed dynamic tiles and drops each via the deleteDynamic semantics (syncStaticEvent + removeTile + onDeleteDynamic), without awaiting the hook
- call it as the first line of loadState so all three compression tiers and the missing-dynamicBlocks case start from a clean slate (#06-17-8)
- add regressions: mapLayer hook/instance witness and the three-tier repeated-load non-accumulation case
2026-09-17 17:27:09 +08:00
c1df1e0116 fix(07-13): prune deleted views and empty sourceless points
- deleteEnemy removes the deleted view from point.affectedBy and drops its point.damages entry so lazy refreshIndex never revisits a dead view (IN-01)
- deleteMapDamage removes the sourcelessDamage IPointInfo once both damages and affectedBy are empty, keeping markDirtyIndex
- add IN-01 regressions: dead-view witness (getDamageWithoutCheck not called) and the two arms of the sourceless empty-point cleanup
2026-09-17 17:23:01 +08:00
cff4291512 fix(07-13): #CR-02 mark removed indexes dirty and register empty view sets
removeEnemyAffecting collects removed coordinate indexes and markDirtyIndex each; refreshEnemyAndClearCache/refreshEnemy register enemyStore.set(view, set) before the empty-set return so later markEnemyDirty uses local refresh instead of refreshAll(). Adds a Chinese comment before each new it.
2026-09-17 16:56:33 +08:00
3da7863580 Merge branch 'refactor/data' of github.com:motajs/template into refactor/data
# Conflicts:
#	.planning/phases/07-data-fixes/07-12-SUMMARY.md
2026-09-17 16:53:23 +08:00
b37c218f2d docs(07-13): lock user adjudications for CR-02/IN-01/load-dynamics cleanup 2026-09-17 16:36:49 +08:00
674b325c55 docs(phase-07): update tracking after plan 07-12 2026-09-17 16:13:19 +08:00
4917baae08 docs(07-12): complete equipment/attribute save correctness plan
- WR-05/WR-06/compareEquip 索引已闭合,WR-04 登记为设计如此(零代码改动、零断言翻转)
- IN-02 测试对齐 ba60ef9(生产零改动),码 58 覆盖变化已登记
- D-44 门禁:eslint 0 错误、vue-tsc 文件级 0 命中、test:ci 729 通过 / 0 失败 / 1 跳过
- Phase 7 验证已失效,需重跑 /gsd-verify-work 7
2026-09-17 16:12:17 +08:00
954c3fcd8a docs(07-12): complete equipment/attribute save correctness plan
- WR-05/WR-06/compareEquip 索引已闭合,WR-04 登记为设计如此(零代码改动、零断言翻转)
- IN-02 测试对齐 ba60ef9(生产零改动),码 58 覆盖变化已登记
- D-44 门禁:eslint 0 错误、vue-tsc 文件级 0 命中、test:ci 729 通过 / 0 失败 / 1 跳过
- Phase 7 验证已失效,需重跑 /gsd-verify-work 7
2026-09-17 16:11:00 +08:00
3e68880e82 fix(07-12): compareEquip 在克隆属性上按对象定位删除目标(Q4 仅修 (i))
- 原属性索引为负或克隆槽位越界时不删除任何修饰器
- 删除目标改为克隆属性同槽位的自身对象,不再跨对象拼接索引
- 回归构造 rebuildModifiers 重建后的负索引路径,含触发机制断言
2026-09-17 16:06:53 +08:00
d8fb6f088c fix(07-12): loadState 用 disable/revert 包裹重新装备(WR-06)
- HeroEquipment.loadState 在重新装备循环外包一层录像禁用窗口,try/finally 保证恢复
- 录像桩补禁用计数语义,读档期间写入的指令被丢弃
- 回归覆盖:读档不产生录像指令、禁用与恢复配对平衡、读档后 equip/unequip 记录仍保留
2026-09-17 16:01:32 +08:00
ab18aa3ec7 fix(07-12): deleteModifierByIndex 委托 deleteModifier(WR-05)
- 按索引取出修饰器后委托 deleteModifier,删除簿记收敛为一份实现
- 返回被删修饰器;索引越界或为负返回 null 且不删除任何修饰器
- 回归覆盖:迭代器产出、索引解析、final 重算、重新挂载、存盘开关清理、越界
2026-09-17 15:56:50 +08:00
762bf2e95c docs(07-12): 记录装备加成事实源契约(WR-04 设计如此,零行为变更)
- types.ts 的 IEquipmentStateSave / IEquipmentState 补充契约注释
- 装备自身数值与百分比加成是事实源,存档持久化这两个表并由其重建装备修饰器
- 跨读档不保留旧修饰器引用属预期;运行时改加成须经装备自身而非改其修饰器
2026-09-17 15:56:26 +08:00
b99d040b11 test(07-12): 对齐空存档 nextUid 重置契约(IN-02,测试专用)
- saveLoad.test.ts 的码 58 用例改写为「空存档 → 随后 add 发号 0 且不产生码 58」
- 用例内注释登记码 58 分支只剩非空畸形数组可达,生产实现保持原样
- equipStore.ts 零改动(生产修复基线 ba60ef9)
2026-09-17 15:54:02 +08:00
7c04ed4a58 docs(07-12): lock user adjudications for WR-04/05/06 + compareEquip 2026-09-17 15:48:53 +08:00
fe63494b12 docs(07-12): fold IN-02 test-only contract alignment into plan 07-12 2026-09-17 15:11:03 +08:00
ba60ef99eb fix: equipStore 的 nextUid 在空存档下报错 2026-09-17 14:56:56 +08:00
b6d1976fc7 docs(phase-07): update tracking after plan 07-11 2026-09-17 14:07:00 +08:00
4481ee91f8 docs(07-11): complete container same-reference save/load plan 2026-09-17 14:05:27 +08:00
e4d392330c fix(07-11): #06-17-4/5/6 add top-level same-reference integration assertions
- CoreState 三档往返中断言装备实例、flag 字段与 follower 实例跨读档为同一实例
- 同时断言其数值/位置仍等于存档点(同引用不改变恢复结果)
- 新增 registerIdentityEquipment 夹具,既有夹具与断言未改动
2026-09-17 13:57:46 +08:00
78f6796915 fix(07-11): #06-17-6 preserve follower instances across loadState
- HeroFollowersController 新增 restoreFollowers 保留式恢复入口
- 同索引同图块数字原地 loadState 并保留实例;否则替换槽位并按既有语义触发增删钩子
- 存档中不存在的末尾跟随者按存档为准删除
- HeroState.loadState 改用 restoreFollowers,不再 removeAllFollowers 全量重建(保持同步)
- IHeroFollowersController 补声明与 jsDoc;新增同实例/替换/删除/补齐回归用例
2026-09-17 13:53:46 +08:00
9964326210 fix(07-11): #06-17-5 preserve flag field instances across loadState
- FlagSystem.loadState 按 key 复用现有 FlagCommonField 并用 fromStructured 原地写值
- 存档中不存在的字段一律删除(以存档为准)
- IFlagSystem.loadState jsDoc 补写同引用与删除语义
- 新增同实例保真、getOrInsert 复用、结构化值恢复、删除多余字段回归用例
- flag/saveLoad.test.ts 的「重建字段对象」断言按 Q1=A 裁决改为同实例保真
2026-09-17 13:50:09 +08:00
153f4a490a fix(07-11): #06-17-4 preserve equipment instances across loadState
- HeroEquipsStore.loadState 按 uid 复用现有 EquipmentState 原地读档
- 同 uid 但装备图块数字不同时才替换该实例
- 存档中不存在的装备实例一律删除(以存档为准)
- IHeroEquipsStore.loadState jsDoc 补写同引用与删除语义
- 新增同实例保真、删除多余实例、num 不同替换三条回归用例
2026-09-17 13:47:20 +08:00
94ceb50cfe refactor: 存档系统挪至渲染端 2026-09-17 13:29:34 +08:00
89434537c8 docs(07-11): record contract decisions Q1=A Q2=A Q3=A Q4=C 2026-09-17 13:23:38 +08:00
7121c93914 test: update replay command assertions after ReplayCode rename
49aacb0 renamed ReplayMoveCommand -> ReplayMove (and siblings); sync the two stale expectations in data-state/src/replay/commands.test.ts (constructor names + core.ts source assertions).
2026-09-17 13:15:30 +08:00
0551738708 docs(phase-07): update tracking after plan 07-10 2026-09-17 13:03:51 +08:00
95e424fff8 docs(07-10): complete ReplayArray index/stream/codec fixes plan 2026-09-17 13:03:15 +08:00
0c6812fcda test(07-10): 末步 set 用例改为断言 paramUsed 的外部可观测偏移
- paramUsed 为私有成员,其正确性只能通过下一条命令参数的写入偏移观测
- 增长与缩短两条末步用例补充参数缓冲区原始字节断言,使「末步起点回退」子缺陷在未修复时可直接失败
2026-09-17 12:59:24 +08:00
5b26539b00 docs(07-10): WR-03 录像参数格式改为类型码只增不改的追加式约定
- 按 Q6=B 不加格式版本字段:array.ts 的类型码表注释写明只增不改约定(新语义必须分配新码,禁止复用),并记录 5/6/7/8 与短字符串基址的一次性重新分配
- types.ts 的 IReplaySystemSave.paramArray 与 IReplayArray.getParamArray jsDoc 同步该约定,并写明不承诺读回旧格式录像
- array.test.ts 新增类型码映射锚定用例(5/6/7/8/9/短字符串基址 9)
- system.ts 无改动(未引入版本字段)
2026-09-17 12:55:50 +08:00
35d4ad6f1c fix(07-10): 编解码自洽 —— bigint 长度字节守卫与参数计数取截断后长度
- WR-01:normalizeParam 的 bigint 分支按长度字节的真实容量(255 字节 = 2^2040)判定,|值| >= 2^2040 触发告警 152 并丢弃该参数;normalizeParamList 过滤被丢弃项,不保留占位
- WR-02:add/insert/set 写入的命令参数计数一律取标准化后的 normalizeParam.length,与 normalizeParamList 的 255 截断一致
- logger.json 的 warn 152 文案改为与真实可表示范围(2^2040 - 1)一致,并写明溢出参数会被忽略
- array.test.ts 新增 bigint 长度字节边界往返、超界丢弃后命令计数/读流对齐、256/300 参数截断计数回归
2026-09-17 12:53:27 +08:00
1f9fb18cf5 fix(07-10): 写入路径越界校验与读流跨读档过期
- insert/delete/set 在 disabled 早退后、任何缓冲读写前校验 index,越界不修改任何缓冲区并告警新码 179(携带操作名/索引/当前长度)
- insert(index === length) 判为合法追加,按 add 语义写入(paramUsed 起、indexArray[length] = paramUsed),insert 合法区间变为 [0, length]
- setReplayArray 在 rebuildIndexArray 后补 expireStreams(),活跃读流跨 ReplaySystem.loadState 标记过期(#06-17-3 / 审计 H)
- types.ts 的 insert/delete/set jsDoc 写明合法区间与越界契约
- logger.json 新增 warn 179(当前最大 warn 码 178 之后)
- array.test.ts 新增 5 条边界回归(含越界前后逐字节不变量);saveLoad.test.ts 新增活跃读流跨读档告警 156 回归
2026-09-17 12:50:45 +08:00
9ae28c68cc fix(07-10): CR-01 ReplayArray.set 索引回退起点与末步终点对齐
- set() 改用 getParamRange(index) 取 [start, end),末步终点取 paramUsed,不再直读未初始化的 indexArray[index + 1]
- 索引回退循环起点由参数字节偏移 paramStart + 1 改为命令索引 index + 1,与 delete() 同口径
- types.ts 的 IReplayArray.set jsDoc 写明允许参数编码长度变化及其后步骤索引平移
- array.test.ts 新增 6 条 CR-01 回归:中间步增长/缩短、末步增长/缩短、读流遍历(IN-03 场景)
2026-09-17 12:42:48 +08:00
b299d348a7 docs(07-10): record contract decisions Q1=A..Q6=B 2026-09-17 12:34:41 +08:00
fe595b7983 refactor: 存档系统应处于渲染层 2026-09-16 21:54:12 +08:00
49aacb087a refactor: 调整录像命名 2026-09-16 21:51:19 +08:00
513a9c354c fix: 读档的 executor 未执行 2026-09-16 21:44:52 +08:00
d856e06b7d docs(phase-07): pin file-level vue-tsc gate command per RESEARCH Pitfall 4 2026-09-16 21:30:12 +08:00
a81e445497 docs(07-10): correct expireStreams call-site count to 5 2026-09-16 21:28:29 +08:00
10f88628cd docs(phase-07): plan plan set 07-10..07-14 for registered-not-fixed data defects 2026-09-16 21:27:10 +08:00
f97c76966b docs(phase-06): update tracking after plan 06-18 2026-09-16 20:43:16 +08:00
83ba914b4c docs(06-18): complete merged real-map scenario perf plan 2026-09-16 20:42:20 +08:00
5317b2f1e3 test(06-18): add whole-map critical timing and total/avg summary table
Adds a third metric that calls the real calculateCritical for every monster on
the merged map and fully consumes the generator, plus a second console.table
with monsters / total ms (sampled median of one full-map sweep) / avg ms.
avg ms equals total ms divided by the monster count.
2026-09-16 20:39:45 +08:00
c193c4e9a9 test(06-18): add merged real-map scenario perf for buildup and map damage
Merges the first 1/5/13 real 13x13 maps into one grid-tiled map
(13x13, 39x26, 52x52 with 11/79/204 monsters), builds the scene from a real
CoreState (real converters/reducer/calculator/final effect), assigns 12 real
Enemy prefabs (3 CommonAura ranges + GuardAura) via a seeded mulberry32, and
records buildup + map damage build timings with performance.mark/measure.
Zero assertions.
2026-09-16 20:33:18 +08:00
6c4d3709d3 test(06-18): migrate 5 existing perf files to performance.mark/measure
- measureCase sampling loop now pairs mark(startTag)/mark(endTag) with
  measure(measureName, startTag, endTag) and clears marks/measures per sample
- tag names derive from caseName+scale so they never collide across cases
- WARMUP_RUNS/SAMPLE_RUNS/median/min/p95/toFixed(3)/columns unchanged
2026-09-16 20:26:42 +08:00
0da0117cd4 docs(06-18): flag MainEnemyComparer as intentionally uncovered 2026-09-16 20:17:45 +08:00
7ad903f156 docs(06-18): create phase plan 2026-09-16 20:15:19 +08:00
b2626bd438 fix(07-09): keep hero attribute instance stable and clear generic variance
- HeroAttribute.loadState replaces its private base object; the HeroAttribute wrapper identity is preserved so equipment/combat references stay valid across load (#06-17-1/#06-17-2).

- Clone the incoming base attribute in the constructor so the shared HERO_DEFAULT_ATTRIBUTE is no longer mutated across CoreState instances.

- Use any for the hero position in combat handler/aura/enemy-view generics to clear the 45 new type errors introduced by HeroAttribute implementing ISaveableContent.
2026-09-16 19:35:54 +08:00
9a2f581c80 docs(phase-07): update tracking after plan 07-09 2026-09-16 18:50:23 +08:00