troytt
97ab449231
feat(preset): 统一 35 个预设关卡流水线与 8×8 Room 几何装配切片 (Issue #74 )
...
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 07:00:53 +00:00
troytt
ea61823e60
feat(wilderness): 完善地表边缘过渡瓦片(Auto-Tiling)与 DRLGROOMTILE_GetTileCache 权重混合 (Issue #70 )
...
- 实现 DRLGROOMTILE_GetTileCache:基于 dwDt1Mask、稀有度字段(rarityFrameIndex/rarity/Rarity)与权重累加的瓦片筛选和轮盘赌采样
- 增强 deriveGroundTilesFromDt1Libraries:按权重降序排列并完整提取 DT1 瓦片稀有度及索引元数据
- 导出 8 邻域位掩码常量(NEIGHBOR_MASK_NE/E/SE/N/S/NW/W/SW)与 NEIGHBOR_OFFSETS
- 实现 computeNeighborMask(DRLGROOMTILE_ComputeNeighborMask 别名):对野外地块进行安全邻域状态位掩码计算
- 导出 WATER_EDGE_TILE_LUT(256 元素表):深水 24 位于 0xFF,边缘过渡序列 0..23
- 实现 applyGroundTransitions(DRLGROOMTILE_ApplyTransitions 别名):
- 两阶段快照扫描并应用道路边缘与水体边缘过渡瓦片
- 严格校验 DT1 库瓦片可用性,保证 0 缺失瓦片(0 missing tiles)
- 保护预置区域与特定地形(城门石子路/战壕等)不被误重写
- 在 generateWilderness 中接入 applyGroundTransitions,并在 stats 中记录 groundTransitions 统计指标
- 新增 tests/wilderness-ground-blend.test.ts 18 项测试用例,全方位验证邻域掩码、缓存采样、过渡拼接与全关卡无缺失
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 04:05:01 +00:00
troytt
2274e2fe0b
feat(wilderness): 实现相邻野外关卡接缝空间对齐与出入口坐标咬合 (Issue #69 )
...
- 支持在 PlannedGate 中指定精确边界块坐标 blockCoord 与瓦片坐标 tileCoord
- 增加并导出 SeamConstraint 与 GateOpening 接口
- 在 WildernessRequest 中添加可选的 seamConstraints 配置
- 增强 getPerimeterOpenings 与 DRLGOUTPLACE_PlaceAct1245OutdoorBorders,支持 seamConstraints 及 blockCoord/tileCoord 坐标咬合与平滑边界夹紧
- 增强 planAct1OutdoorLevel 中的边界出入口与道路锚点计算,根据前驱/相邻关卡的接缝约束锁定 anchorCell 与 interiorCell
- 在 WildernessStats 与 WildernessResult.stats 中记录并返回 gateOpenings
- 新增 tests/wilderness-seams.test.ts 全套单元测试与集成测试
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 03:29:18 +00:00
troytt
d7defd8da3
feat(wilderness): 还原 DRLGOUTDOORS_SpawnAct12Waypoint 小站与神殿拓扑放置算法 ( #68 )
...
- 在 src/game/wilderness.ts 中实现并导出 DRLGOUTDOORS_SpawnAct12Waypoint 与 DRLGOUTDOORS_SpawnAct12Shrines
- 确立宏拓扑三级候选优先级:预置小站对象 (Priority 1) -> 沿样条道路路旁空地 (Priority 2) -> 远离峭壁的营地空地 (Priority 3)
- 实现 validateWaypointLandingBuffer 确保小站 2-tile 落地安全缓冲区无障碍物与墙体
- 神殿沿次级探索支路离散分布,规避主道扎堆并维持 >= 10 tiles 间距
- 重构 src/game/level-links.ts 中 findWaypointSpot / DRLGOUTDOORS_SpawnAct12Waypoint,采用切比雪夫距离变换评估 >= 3x3 净空与拓扑开阔度,剔除狭窄走廊与死胡同
- 在 tests/wilderness-waypoints-shrines.test.ts 补充拓扑选址与落地安全区验证测试
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 03:09:19 +00:00
troytt
0e8778f31a
feat(wilderness): 还原 DRLGOUTPLACE_PlaceAct1245OutdoorBorders 边界峭壁与门洞状态机
...
- 扩展 classifyBorderPiece 支持 1~5 幕所有预置边界切片命名(1..12 编号、方位后缀、Act 2 峭壁、Act 5 崖壁/雪地/峡谷与过渡转角)
- 导出 getCellOrientation 与 selectBorderPiece,支持精确的峭壁偏好 (preferCliff: true/false/undefined) 与开洞优先降级
- 实现并导出 DRLGOUTPLACE_PlaceAct1245OutdoorBorders(保留 layBorder 别名),先顺时针放置四边直边界再盖转角封口,保证 100% 覆盖率与 0 过程回退墙
- 支持 claimedBorderBlocks 城镇过渡区与外立面避让接驳
- 新增 tests/wilderness-borders.test.ts 完整测试全 5 幕边界识别、开闭门洞选择、外圈覆盖与接驳避让
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 02:51:30 +00:00
troytt
939ada6e4c
feat(wilderness): 用基于控制顶点图 (DRLGVER) 的 Catmull-Rom 样条道路取代栅格化 A* 道路 ( #66 )
...
- 实现控制顶点图算法 createDrlgVertices / DRLGVER_CreateVertices,提取城门/关卡出口、中央路口枢纽、特异预设(石块荒野巨石阵、遗忘之塔、邪恶洞窟等)及自然拐点宏控制顶点
- 引入 Catmull-Rom 样条平滑插值算法 catmullRomPoint 与 sampleCatmullRomSpline,生成平滑曲率的自然蜿蜒小径,摆脱死板的 45°/90° 网格折线
- 实现栅格化样条小径 rasterizeDirtPathSegment / generateDirtPaths(2-3 格宽度),无缝对齐 8 邻域 LUT 贴图码表 (DIRT_PATH_TILE_LUT)
- 样条道路与光栅化避障支持:严格避开 roadObstacleBlocks(墓园围墙、遗迹废墟、房屋边界),保护预设建筑阻隔完整性
- 重构 stampThemedRoads:南北向与东西向主道、城门引道及景观支路均通过平滑样条连通,清理道路中轴覆盖的杂物地块
- 新增 tests/wilderness-spline-roads.test.ts,全量覆盖样条数学与曲率、控制顶点图生成、避障光栅化及第一幕野外端到端验证
Closes #66
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 02:32:14 +00:00
troytt
11e8a39e4e
fix(render): 还原原版暗黑2建筑与城门屋顶过道遮挡消失机制 ( #72 )
...
- roofs.ts: 将默认最低透明度 DEFAULT_MIN_ROOF_ALPHA 设为 0.0,还原原版遮挡完全隐形机制
- roofs.ts: getRoofBounds 引入 roofHeight 等距高程投影补偿,将悬空屋顶包围盒延伸至地面投影视野
- roofs.ts: 将 DEFAULT_CLUSTER_CELL_DISTANCE 增至 4,并在 clusterRoofs 中自动插值补全城门与建筑群间隙走廊网格单元
- act-scene.ts & d2map.ts: 在 Drawable 和 IsoDraw 中接线传递 DT1 roofHeight 高程属性
- tests/roofs.test.ts: 补充高程下投、哈洛加斯西门跨过道聚类遮挡及拱梁/上墙全消失测试
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 02:12:37 +00:00
troytt
d0efb04395
refactor(wilderness): 移除凭空发明的程序化十字矮石墙网络,回归原版自然地貌阻隔 ( #65 )
...
- 将 stampThemedDividers 重构为兼容性 no-op,完全废弃人为硬编码的十字切分矮石墙
- generateWilderness 移除 stampOutdoorDividers 调用,回归原版 Act 1-5 依据 DS1 预设边界及地形生成的自然阻隔机制
- 更新 wilderness 单元与多幕道路测试,验证 0 人造矮石墙及真实地貌阻隔保留
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-18 01:38:00 +00:00
troytt
83f855597b
fix(monsters): eliminate unwired columns, dead logic, and wire elite modifier scaling
...
- Support up to mon25 columns in monsterColumns stopping if column does not exist
- Weight normal pack type selection by kind.rarity in planMonsterGroups
- Wire mechanical stat scaling for stoneskin, cursed, coldenchant, fireenchant, lightenchant, spectralhit, teleport, magicresistant, and aura in applyEliteModifiers
- Add unit tests for monsterColumns, rarity-weighted pack planning, and elite modifier stat scaling
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:56:33 +00:00
troytt
cbcf71a731
fix(engine): fix logical tautologies, edge conditions, and argument defaults
...
- Fix isRoad out-of-bounds boundary check to return false instead of true
- Fix rack candidate room selection to strictly prioritize corridor rooms (degree === 2)
- Fix candidateRooms fallback in allocatePacksToRooms to not place monsters in safe zones
- Fix default cellHeight in partitionMapIntoRooms to 40 px for 80x40 isometric tiles
- Throw explicit error in parseTable on empty table data and add provenance comment for temptile.dt1
- Add regression tests for rack candidate selection, safe zones, cellHeight, and parseTable
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:46:49 +00:00
troytt
6de9fce610
fix(wilderness): add seed diversity to Bloody Foothills obstacle placement
...
- Apply RNG jitter to obstacle placement coordinates and lengths across frontline zones
- Preserve the unblocked central corridor along y=24
- Track procedural walls and roads in siege topography stats
- Add unit test in tests/wilderness-siege-strips.test.ts verifying seed-based obstacle variance
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:25:45 +00:00
troytt
53d6cdd08c
feat(wilderness): track procedural passes in telemetry stats
...
- Add proceduralRoadCells, proceduralDividerCells, proceduralWaterCells, proceduralWallCells to WildernessTelemetry and WildernessStats
- Measure actual painted cells in stampThemedRoads, stampThemedDividers, generateDirtPaths, and act outdoor level topography passes
- Add unit tests in tests/wilderness-telemetry.test.ts verifying counted telemetry against canvas state
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:23:31 +00:00
troytt
fa307bff46
fix(wilderness): prevent destructive wiping of walls and presets in roads and bridges
...
1. Protect placed presets and preset walls from being wiped in stampThemedRoads:
check placedRects in paintRoadTile, ensuring preset walls are never cleared.
2. Protect preset floors and walls in stampAct3KurastCauseway so artist DS1
tiles are not overwritten by procedural causeway passes; wire specialPlacedRects.
3. Protect placed preset walls and floors in synthesizeBridgePlanks in Act 3 jungles,
recording placedRects for all jungle pieces.
4. Add unit tests for Causeway preset preservation and road preset wall preservation.
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:10:59 +00:00
troytt
a7a3ce13d4
feat(game): document and validate object pools and LvlPrest piece families (Issue #61 Step 4)
...
- Document the 3-tier lookup relation across Levels.txt, LvlTypes.txt, and LvlPrest.txt
- Explain why Catacombs/Sewers index pieces via Def / LevelId = 0 / first levelId
- Explain why composite themes have sub-families (Corrupt Harem, Mephisto, Temple, Bridge, ThroneRoom)
- Implement discoverMazePieceFamilies with optional LvlPrest table and update classifyMazePieceName
- Add Objects.txt mapping validation (validateDungeonObjectPools, validateActPopulationConfig, resolveObjectsTxtId)
- Add comprehensive unit tests in tests/maze-objects.test.ts
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 14:39:13 +00:00
troytt
94305b03dd
Resolve outdoor waypoints and act mapping dynamically from Levels.txt
...
- Add dynamic hasOutdoorWaypoint(levelId, levelsTable) reading Levels.txt Waypoint column (!= 255)
- Unify actOfLevel in acts.ts as canonical source of truth supporting Levels.txt Act column
- Support levelsTable in WildernessRequest, spawnOutdoorWaypoint, spawnOutdoorShrines, stampOutdoorRoads, stampOutdoorDividers
- Re-export actOfLevel, hasOutdoorWaypoint, and OUTDOOR_WAYPOINT_LEVELS cleanly without circular dependencies
- Add unit tests verifying dynamic Levels.txt resolution and fallbacks
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 14:27:54 +00:00
troytt
7efdad4693
feat(game): decode level names from string.tbl with graceful fallback
...
- Implement decodeLevelNamesFromTbl supporting D2Tbl/Map and Levels.txt
- Add CANONICAL_LEVEL_NAME_KEYS and active decoded level names cache
- Support graceful fallback to LEVEL_NAMES_ZH and English name keys
- Add comprehensive test coverage in tests/tbl.test.ts
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 14:14:15 +00:00
troytt
fea677b0b4
fix(wilderness): prevent sealed borders on outdoor levels and track preset failures
...
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 13:43:51 +00:00
troytt
b8810072ce
fix(maze): use PRNG stream in special passes and fix Act 5 temple NE waypoint generation
...
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 13:36:02 +00:00
troytt
a3a3e44838
refactor(acts): unify ACT_TOWNS and townLevelForAct single source of truth
...
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 13:31:07 +00:00
troytt
27e0db38c8
fix(level-links): prevent infinite teleport bounce at seam arrival
...
Eliminate fallback to trigger tile (x, y) when no walkable tile is found
within initial radius. Expand search to full grid extent and guarantee that
the arrival destination is strictly offset inward away from the seam trigger box.
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 13:27:27 +00:00
troytt
bf101dae66
fix(monsters): wire meleeRange from MonsterArt into reach and reference MonUMod constants
...
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 13:03:21 +00:00
troytt
fd0f48c391
fix(monsters): derive superunique specs from SuperUniques table and eliminate fallen1 fallback
...
- Replace static CANONICAL_SUPER_UNIQUES_BY_LEVEL mapping with buildSuperUniqueLandmarkSpecs
- Parse canonical SuperUniques from game data table CANONICAL_SUPERUNIQUES_TABLE
- Export lookupSuperUnique helper to search SuperUniques by id or nameKey
- Support optional tables.superuniques in planLevelMonsters
- Remove dangerous fallback to fallen1/first monster, gracefully skipping missing boss kinds
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 12:54:09 +00:00
troytt
2e73d7b02f
fix(monster-mapping): update hellbovine token to EC, remove XX tokens, and eliminate startsWith fallback
...
- Update hellbovine token from CW to EC in MONSTER_ART_MAP
- Remove invalid XX cut monster entries from MONSTER_ART_MAP and ACT_MONSTER_SPECS
- Replace startsWith iteration in resolveMonsterArtSpec with deterministic O(1) exact and base lookup
- Prevent XX tokens from leaking into art requests
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 12:42:44 +00:00
troytt
04d562a99c
fix(monsters): include superunique and minion monster IDs in PlannedLevel types
...
Ensure monster art is loaded for all superunique bosses and their
minions to prevent red placeholder boxes when they spawn.
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 12:36:42 +00:00
troytt
ae2672dd9e
fix(wilderness): 让遥测数据反映真实计数
...
Issue #58 第 6 条列出的 4 处伪造遥测(第 5 处 unimplementedPasses
已在 5b3a9db 修复)。这些数字是 verify:generators 与 HUD 判断
"这一关是否生成成功"的唯一依据,而它们是字面常量或恒等式:
- wilderness-jungles.ts: junglePathCells 恒为 100、riverBridges 恒
至少为 2。改为扫描画布实测:新增 measureJungleTopography(),按
宏格网把已绘制的地板分成"丛林地面"与"河道水面"(桥面板属于桥,
不计入两者);riverBridges = 实际摆放的桥 + 真正画出来的定制
跨河桥(画布太短时第二条桥画不出来,就不再算数)。并补一条
notes 说明实测值。
- wilderness-acts.ts: 第四幕 104/106 的"玄武岩高原"分支只递增
plateauCells 却一格都不画。改为不再把踏勘当成果,计为候选点并
在 notes 里明说该 pass 未实现。
- wilderness.ts:5049: 特殊预置返回路径恒报 subTheme: 0,改为与主
路径一致的 clamp(floor(request.subTheme), 0, 4)。
- wilderness.ts applySubstitutions: BordType 0 的"整关仅一个"预算
从 Infinity 起算,min(1, Infinity) 恒为 1、减法也永远减不动,
实际退化成"每行一个"。预算改为从 1 起算,上限真正生效。
新增 tests/wilderness-telemetry.test.ts(8 个用例)。在改动前
其中 6 个失败,改动后全部通过。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:55:55 +00:00
troytt
5956b00e72
fix(scene): 删除 DEMO_MONSTERS 假刷怪路径
...
关卡怪物计划为空时,act 场景会塞进 12 个手写的 DEMO_MONSTERS,
并且判断是否为城镇靠的是显示名里有没有英文子串 "town"。
于是:换个名字或换种语言的城镇会凭空冒出 12 只怪;真正的数据
失败(monsters 表读不出来、计划为空)也会伪装成"有内容"。
更糟的是 demo-* id 不在任何美术表里,画出来是红方块,和美术
加载失败的表现一模一样。
改为:
- 删掉 demo-data.ts 里的 DEMO_MONSTERS 与 act-scene.ts 里的
PLACEHOLDER_MONSTER_COUNT、monsterStats/monsterCount 字段,
以及切关时 `next.monsterCount > 0` 的兜底 spawnMonsters 调用;
引擎选项显式传 stats: [] / monsterCount: 0。
- 新增 ActSceneState.monstersPlanned 与 monsterPlanStatusText(),
开机与切关后各调用一次 reportMonsterPlan(),HUD 上如实显示
"本关未规划到怪物",而不是拿假数据盖住。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:45:46 +00:00
troytt
d890f558b1
fix(scene): 让怪物美术加载失败可观测,不再静默变红方块
...
三层 catch 把「整个美术系统崩溃」变成「场景就绪 + 全场红方块」,只留一句
console.warn:
- `monster-art.ts` 逐 COF 层的 `catch` 直接丢层,怪物缺头缺臂而无任何日志。
现在每一层失败都产出 `MonsterLayerFailure`(unknown-component / no-member /
decode),`console.error` 输出,并随 `MonsterAnimationSheet.layerFailures`
与 `LoadedMonsterArt.layerFailures` 返回。
- `loadMonsterArtMap` 改为返回 `MonsterArtLoad{ map, missing, errors,
layerFailures }`:整函数 catch 与逐 spec catch 都计数并降级为 console.error,
预烘焙资源 fetch 失败也不再完全无声。
- `ActSceneState` 新增 `missingMonsterArt` / `monsterArtErrors` /
`monsterArtLayerFailures`,由 `recordMonsterArtLoad` 在两处加载点写入;
HUD 追加 `monsterArtStatusText` 片段。
- 红方块绘制点自己上报 id(流式刷怪可能刷出加载时未知的类型)。
新增 tests/monster-art-diagnostics.test.ts(5 例):逐层 no-member / decode
失败的计数与日志,以及 `missingMonsterArtIds` / `monsterArtStatusText`。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:40:05 +00:00
troytt
952ad00429
fix(monsters): MonLvl 缺行时告警而非静默返回 UNSCALED
...
缩放公式是 `原始表值 × scale ÷ 100`,回退到 `UNSCALED`(全 100)等于直接使用
`MonStats.txt` 的原始值:一只堕落者拿到 21-61 HP 而不是约 3 HP,约 20 倍。
原来这一步完全静默。
- `monsterScaleFor` 缺行时 `console.warn`(按 level 去重,避免每只怪刷一行),
并新增 `setMonsterScalingStrict(true)` 让烘焙 / 校验脚本直接 throw。
- 新增 `monsterScaleLookup`,返回 `{ scale, missing }`,供调用方在不读 console
的前提下自行判断。
- `PlannedLevel` 新增 `missingScalingLevels`,`planLevelMonsters` 把本关所有
缺行的 level 汇总上报,烘焙方因此可以拒绝一个「怪物强度是假的」的关卡。
新增 4 个用例:告警一次、strict 抛错、lookup 不写 console、
`planLevelMonsters` 在 MonLvl 抽掉 level 1 行时报告 `[1]`。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:35:13 +00:00
troytt
e817ace5ef
fix(maze-objects): 删掉 isOpenFloor 里恒真的 `|| true`
...
`hasFloor` 的内容检测写成 `(f.prop1 !== 0 || f.style !== 0 || f.sequence !== 0
|| true)`,末尾的 `|| true` 让整个条件恒为真:DS1 每个格子的每一层地板都有一条
记录,未绘制处是全零槽位,于是「没有地板美术的空格」也被判定为可放物件的地面。
删除 `|| true` 后,全零地板槽位不再算作地面;新增 6 个回归用例覆盖
painted / 全零 / 仅 style / 仅 sequence / hidden / 多层,以及「整关地板全为空槽
时不生成任何动态物件」。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:30:47 +00:00
troytt
5b3a9db986
fix(maze): 让 UNIMPLEMENTED_PASSES 反映真实缺口
...
`UNIMPLEMENTED_PASSES` 此前被硬编码为 `[]`,注释声称 11 个核心地牢 pass 全部
实现,于是 `stats.unimplementedPasses` 在每一关都无条件报告「零缺口」——包括
那些 `specials` 表为空、根本不生成楼梯房间的 level type。
改为从 `MAZE_LEVEL_TYPE_PROFILES` 实测推导:
- 新增 `unimplementedPassesFor(levelTypeName)`,按 level type 返回缺口:
没有 profile 行,或 `specials` 为空且不是 `singleRoom` 定制关。
- `UNIMPLEMENTED_PASSES` 改为所有 level type 缺口的并集,因此非空。
- `generateMaze` 的 `stats.unimplementedPasses` 改报本关自己的缺口,
而不是全局常量;`unresolvedRoles` / `notes` 本来就已随 stats 返回。
同时修正两处已经与代码不符的注释:`maze.ts` 里「per-act 装饰 pass 均未复现」
(它们已在 `maze-special-passes.ts` 中实现),以及 `pack-act-assets.ts` 里
「第二幕下水道 / 墓穴 / 第三幕地牢 specials 为空」(这三者现在都有 specials,
真正为空的是 Harem、Basement、Spider、Act 5 Lava)。
测试:原 `UNIMPLEMENTED_PASSES is completely empty` 断言的是被修正的错误行为,
改为断言它恰好列出所有 `specials` 为空的 level type;另加 4 个用例覆盖
按 level type 查询与 `generateMaze` 的 stats 透出。
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 11:29:06 +00:00
troytt
4ece5aa3c1
feat(scene): acts.html 接入房间级惰性刷怪与休眠/唤醒流式加载
...
把已合入 main 但从未被生产代码调用的两块能力接到 acts.html 的
act-scene 上,按 D2Game.dll 的做法组织怪物生命周期:
- act-scene:新增 buildStreamingRooms(),把关卡切成房间并把怪物群
分配给房间,交给 GameEngine 的 roomPacks。房间按「场景像素空间」
切分而不是格子空间——一块矩形格子投影出来是菱形,相邻矩形的
AABB 几乎完全重叠,那样切会让全图房间同时「靠近玩家」,流式加载
就没有意义了。落在菱形外、没有任何可走地面的房间直接丢弃,否则
分到它头上的怪物群会被静默吞掉。
- monster-streaming:populateRoom 改用 monster-rooms 的
spawnPacksInRoom,怪物在房间内抱团成营地,而不是沿用旧的全局
螺旋撒点。这把 feat/monster-streaming 和 feat/monster-room-placement
两条分支真正合到了一起。落进安全区(传送点/关卡入口)的个体会被
推到安全区边缘。
- 重新打开怪物仇恨。它当初被关掉是因为全图怪物同时醒着,会被拖成
一条长队;现在玩家没走近的怪物要么还没实例化、要么在睡眠中。
- swapLevel 过图时重建房间表,而不是在门口一次性刷完整张图。
tests/wilderness-roads:角落断言改为按槽位号统计。这条断言早于
6b9c3d3(Act 1 北/西/三个角改用岩壁边界),岩壁族还带字母后缀
(Wild Cliff Border 6A),按全名查表就落空了。
Verified: typecheck + 923 tests pass;另用真实烘焙数据回放,
冰冷之原 45 群 57 只怪 → 45 个房间,出生点只实例化 18 房 26 只,
走遍全图后恰好 45 房 57 只,无遗漏、无重复。
2026-09-17 11:14:26 +00:00
troytt
4c2e399e1d
test(loop): expand timeout tolerance to 120ms to prevent jitter in concurrent runs
2026-09-17 09:16:48 +00:00
troytt
274ffae71e
Merge branch 'feat/monster-room-placement'
2026-09-17 09:11:24 +00:00
troytt
5aba7487f3
Merge branch 'fix/issue-16' into main
2026-09-17 09:10:59 +00:00
troytt
3951e70ef4
Merge branch 'fix/issue-20'
2026-09-17 09:09:01 +00:00
troytt
6f01c8de89
Merge branch 'fix/issue-19' into main
2026-09-17 09:08:46 +00:00
troytt
db3d6ffa84
Merge branch 'fix/issue-57' into main
2026-09-17 09:07:38 +00:00
troytt
12718ebcd6
Merge branch 'fix/issue-56' into main
2026-09-17 09:03:15 +00:00
troytt
74d2d1e36f
test(wilderness): reconcile caravan and avenue floor style check with act topography passes
2026-09-17 09:02:05 +00:00
troytt
dfce2f6cef
Merge branch 'fix/issue-55'
2026-09-17 08:58:45 +00:00
troytt
a6ab21881d
Merge branch 'fix/issue-54'
...
# Conflicts:
# src/game/wilderness.ts
2026-09-17 08:58:22 +00:00
troytt
2de9835b34
Merge branch 'fix/issue-53'
...
# Conflicts:
# src/game/wilderness.ts
2026-09-17 08:56:41 +00:00
troytt
3ab024d12f
Merge branch 'fix/issue-52'
2026-09-17 08:51:58 +00:00
troytt
334b957ab6
Merge branch 'fix/issue-51'
...
# Conflicts:
# src/game/wilderness.ts
2026-09-17 08:51:55 +00:00
troytt
4f8e077bbb
Merge branch 'fix/issue-50'
...
# Conflicts:
# src/game/maze.ts
2026-09-17 08:50:47 +00:00
troytt
4c584db273
Merge branch 'fix/issue-49'
...
# Conflicts:
# src/game/maze.ts
2026-09-17 08:49:32 +00:00
troytt
893e9b8550
Merge branch 'fix/issue-48'
...
# Conflicts:
# src/game/maze.ts
2026-09-17 08:41:40 +00:00
troytt
e1163b1253
Merge branch 'fix/issue-47'
...
# Conflicts:
# src/game/maze.ts
2026-09-17 08:40:55 +00:00
troytt
80b2fd0f71
Merge branch 'fix/issue-45'
2026-09-17 08:40:15 +00:00
troytt
c83499c591
Merge branch 'fix/issue-44'
...
# Conflicts:
# src/scene/act-scene.ts
2026-09-17 08:40:10 +00:00