Files
mtgodot-poc/audit/contracts/world.environment-weather.md
T
shenleiandClaude Opus 5 a989b8f19b chore: delete 106 unreachable *_system.gd and their parity tests
These files were loaded only by their own test_*_parity.gd and never by
the runtime (transitively checked, incl. client_phase_integration_system).
Removes 76 manifest implementation/evidence references across 18
contracts; contract docs get a note that conclusions based on them are
void. Live systems kept: chest, consumable, item_attr, metin_socket,
whisper_chat.

Full headless suite: no new failures (7 failing + 5 headless-hanging
render tests are identical before the deletion).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 17:51:52 +09:00

109 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# world.environment_weather —— 天空、环境、光照、昼夜、雪和天气
状态:`PARTIAL`
本合同检查 40250 的 `.msenv` 环境加载、背景/角色光照、线性雾、天空六面、云层、滤色、lens flare、风、雪粒子和地图环境生命周期。判断标准是同一份环境数据是否经过同一类调用链、在同一时序产生相同的可见状态和清理副作用;“字段已解析”或“测试能创建粒子”不能代替渲染与正式场景接入等价。
## 40250 参考调用链
- `GameLib/MapOutdoorRender.cpp` / `MapOutdoorRenderHTP.cpp` / `MapOutdoorRenderSTP.cpp`
- `OnSetEnvironmentDataPtr` 将环境数据分派到 screen filter、SkyBox 和 lens flare;渲染顺序是天空、云、环境开始、地形/角色/水/雪/特效、环境结束和 lens flare。
- `OnBeginEnvironment``.msenv` 的 fog near/far/color、背景方向光和角色方向光分别应用到 SpeedTree、terrain patch 和角色渲染;风强度进入森林渲染器。
- `SetEnvironmentSkyBox` 使用 scale、gradient、texture render mode、六面纹理、云纹理、云高度/缩放/颜色/滚动速度,并通过 SkyBox transition 更新环境。
- `GameLib/SnowEnvironment.cpp` / `SnowParticle.cpp`
- 雪环境由专用粒子池、相机/世界范围、风/重力和粒子生命周期驱动,随 outdoor 渲染阶段更新和绘制,不是一次性创建的通用屏幕粒子节点。
- `Client/Eternexus/root/servercommandparser.py` / `game.py`
- 服务器 `xmas_snow 0/1``ServerCommandParser` 进入 `__XMasSnow_Enable`,先按 `__IsXMasMap` 过滤,再调用 `background.EnableSnow(0/1)`;该命令不是按地图名称自动推导天气。
- `EterLib/EnvironmentMap.cpp`
- 环境对象作为 outdoor 环境资源的生命周期边界参与加载/卸载;环境切换必须同步释放旧天空、雾、滤色、lens flare 和粒子状态。
## 当前端实现映射
- `formats/environment.*` / `extension/src/environment_builder.*`
- 已解析 `.msenv` 的方向光、fog、sky gradient/六面/云、filter 和 lens flare 字段;`apply_environment` 已创建背景 `Sun`、角色 `CharacterLight``WorldEnvironment`texture-mode sky 已用 shader 采样六面和滚动云层。
- filter、lens flare、wind 目前主要保存在 `WorldEnvironment` metadata;没有对应运行时后处理、光晕节点或 SpeedTree 风更新。fog 使用 Godot depth fog,并主动 clamp/push begin/end、curve/density 与参考端 D3D 线性雾不相同。
- `extension/src/metin2_world.cpp` / `project/game_scene.gd`
- `.msenv` 在正式地图加载时接入 `Metin2World`,世界卸载会移除环境节点;GameScene 会优先采用 `.msenv` 环境,避免兜底光照覆盖它。
- 生产场景创建 `fx/weather.gd`,并由 `EntityStore::apply_server_command -> M2Client.weather_changed -> GameScene._on_weather_changed` 接收 `xmas_snow`;场景按 40250 四张排除地图过滤,并在换图后重新应用当前开关。
- `WeatherDayNightSystem` 仍未实例化到正式场景;它的按地图自动天气/昼夜预设不作为 40250 生产行为。
- `project/fx/weather.gd`
- 使用跟随相机的单个 `GPUParticles3D` 实现 snow/rain/none,粒子数量、重力、速度和颜色可切换;它没有 40250 `SnowEnvironment/SnowParticle` 的池、风向、范围、渲染阶段或资源失败回退链。
- `project/weather_daynight_system.gd`
- 是当前端独立的昼夜/地图天气 helper,能计算 phase、天气和光照字典;但其地图预设与 40250 `.msenv` 静态环境不是同一数据源,且正式 GameScene 未消费它。
## 分支等价矩阵
| 40250 判据/副作用 | 当前实现 | 结论 |
|---|---|---|
| `.msenv` 解析、地图加载、环境节点创建和卸载 | `formats/environment` + `Metin2World::load_map` + `apply_environment` | 基础链路通过;复杂地图/重入清理仍需扩展证据 |
| 背景/角色两套方向光和可见层 | `Sun` layer 1、`CharacterLight` layer 2 | 部分等价;光照色/能量和角色渲染消费仍需逐场景比对 |
| fog near/far/color、density/linear 分支、terrain/HTP/STP 使用 | Godot depth fogbegin/end 被 clampcurve=0.5、density=0 | 不等价;参考的线性 D3D 雾公式和 LOD 分支没有 1:1 保持 |
| 六面天空、gradient、scale、texture mode、cloud plane/UV | Godot sky shader/ProceduralSkyMaterial,六面和云测试通过 | 部分等价;shader 采样与参考 quad/transition 仍需像素和边界比对 |
| screen filter alpha blend 和 lens flare | 字段只写 metadata,无运行时后处理/flare 渲染节点 | GAP |
| 风强度进入森林/树木更新 | 固定 `msenv_wind_strength=0.2` metadata,无 SpeedTree/树节点风更新 | GAP |
| SnowEnvironment/SnowParticle 池、范围、风/重力和 outdoor render 时序 | 单个相机跟随 GPUParticles3D | 部分等价;粒子可切换不代表池/时序/清理等价 |
| 服务器 `xmas_snow 0/1``__IsXMasMap` 过滤和雪开关 | typed command -> `weather_changed` -> GameScene map filter -> `Weather.set_weather` | 部分等价;命令/过滤时序已对齐,但粒子池/渲染阶段不是 SnowEnvironment 1:1 |
| `.msenv` 静态地图环境 vs 昼夜/天气切换 | 正式链消费服务器 `xmas_snow``WeatherDayNightSystem` helper 仍独立存在且不驱动生产地图 | 部分等价;40250 的 `DayMode/PRESERVE_DayMode` 和环境切换仍未接入 |
| 地图切换、暂停、重载和失败清理 | world 环境节点 queue_free;天气节点未按地图环境重置/验证 | 部分等价;缺少环境/粒子/云资源失败和快速切图组合证据 |
## 已执行测试
- `project/environment_test.gd`:通过;A1 `.msenv`、双方向光、WorldEnvironment、云纹理和 wind/filter metadata 可读取。
- `project/skybox_test.gd`:通过;CapeDragonHead/DawnMistWood texture-mode 六面天空、云层、scale 和 UV speed 断言通过。
- `project/p9_test.gd`:通过;通用 weather snow/rain/none 粒子开关路径通过,但不是参考雪环境池测试。
- `project/test_weather_daynight_parity.gd`22 passed、0 failed;仅覆盖 `WeatherDayNightSystem` helper 的默认时相、时间推进、天气预设和信号,不覆盖正式 GameScene 接入或 40250 `.msenv` 渲染。
- `extension/tests/net_entity_test.cpp` / `build/extension/net_entity_test`:通过;覆盖 `GC_CHAT/COMMAND``xmas_snow 1/0` typed event 顺序。
- `project/gamescene_test.gd`:通过;覆盖正式 GameScene 对 eligible map、四张 40250 排除地图和关闭命令的雪开关处理。
- `project/netbridge_test.gd`:通过;确认 `M2Client.weather_changed` 信号已注册。
## Audit evidence round 2026-09-22T09:30Z
- 重新运行 `environment_test.gd``skybox_test.gd``p9_test.gd``test_weather_daynight_parity.gd`,结果分别通过、通过、通过、22/22 通过。
- `environment_test.gd` 实际加载 A1 `.msenv` 地图,`skybox_test.gd` 实际加载 CapeDragonHead/DawnMistWood 六面天空;这些结果确认 `.msenv`/天空基础链路仍可用,但不改变 filter、lens flare、wind、线性 fog 和 SnowEnvironment 池的差异结论。
- `test_weather_daynight_parity.gd` 仍然只实例化独立 `WeatherDayNightSystem`;对照 `GameScene::_build_world` 当前只创建 `fx/weather.gd`,未发现正式地图加载时消费该 helper 的调用边沿,因此不能将 22/22 记为生产天气接入通过。
- 本轮修复了服务器 `xmas_snow` 的命令接入和正式场景地图过滤;合同继续保持 `PARTIAL`,下一实现入口是 `DayMode/PRESERVE_DayMode`、SnowEnvironment 池以及已确认的 filter/lens flare/wind GAP。
## Deep audit round 2026-09-21
### Fresh regression results
- `environment_test.gd``skybox_test.gd``p9_test.gd` 均退出码 0;真实 A1/CapeDragonHead/DawnMistWood 环境、六面天空、云参数和基础天气切换断言通过。
- `test_weather_daynight_parity.gd` 22/22 通过,但它验证的是独立 `WeatherDayNightSystem` helper,不证明正式 `GameScene` 已实例化并消费天气系统。
### Static parity conclusion
- `.msenv` 解析、背景/角色光、SkyBox 和地图环境节点的基础链路存在;filter、lens flare、wind 仍主要停留在 metadata,未形成 40250 的运行时后处理、光晕和树木风更新。
- Godot depth fog 的 clamp/curve/density 与 40250 线性 D3D 雾不等价;六面天空/云 shader 有结构测试,但没有与参考 transition/render order 的像素 oracle。
- 生产场景已接入 40250 的服务器 `xmas_snow` 命令和地图排除过滤,但没有接入 `DayMode/PRESERVE_DayMode`;单个 GPUParticles3D 也不等价于 SnowEnvironment/SnowParticle 池和 outdoor render 时序。
本轮仍为 `PARTIAL`,完成服务器天气命令的实现和第三轮环境/天气证据登记。
### Implementation fix round 2026-09-22T10:00Z
- 修复前 `gamescene_test.gd` 的生产链回归无法让 `xmas_snow=1` 启用雪;native command-bus 也没有天气事件。
- 按 40250 `ServerCommandParser.__XMasSnow_Enable -> game.__XMasSnow_Enable -> background.EnableSnow`,新增 `EntityStore::WeatherChanged` typed event、`M2Client.weather_changed(bool)` 信号,以及 `GameScene._on_weather_changed -> _apply_server_weather`
- `_apply_server_weather` 复刻 `__IsXMasMap` 的四张排除地图:`metin2_map_n_flame_01``metin2_map_n_desert_01``metin2_map_spiderdungeon``metin2_map_deviltower1`;地图切换后重新计算开关,避免服务器命令状态污染新地图。
- 修复后 native `net_entity_test``gamescene_test.gd``netbridge_test.gd``p9_test.gd``environment_test.gd` 均通过。Godot 粒子仍只是平台适配,SnowEnvironment 池、DayMode、filter/lens flare/wind 和线性 fog 差异继续保留。
### Active EterLib environment-render review
- `EterLib/SkyBox.cpp` 实际维护天空六面纹理、天空/云纹理、gradient、scale、scroll、天气/颜色过渡和 render 顺序;`ScreenFilter.cpp``LensFlare.cpp` 是独立的屏幕滤镜与镜头光晕渲染对象,不只是环境字典字段。
- 当前 `WorldEnvironment`/sky shader 能提供天空和雾的部分视觉结果,但 `filter`、lens flare 和风更新主要停留在 metadata,没有对应运行时后处理/光晕对象;Godot depth fog 的 clamp、curve 和 density 也不等价于参考端的 D3D 线性雾分支。
- 因此本轮完成 `SkyBox``ScreenFilter``LensFlare` 活跃源码静态核对;天空结构测试通过不能证明 transition/render order、滤镜、光晕和地图环境切换副作用一致,合同保持 `PARTIAL`
## 已确认差异和未验证项
1. 保持 filter/lens flare/wind 的明确 GAP,或实现对应的后处理、光晕和树木风更新,并为每个资源失败/禁用分支补测试。
2. 以 40250 的 fog near/far、天空 transition、云 plane、背景/角色光照和 render order 建立截图/参数 oracle,禁止只用 metadata 断言代替渲染证据。
3. 补齐 `DayMode/PRESERVE_DayMode` 的正式环境切换和场景生命周期;`WeatherDayNightSystem` 的自动地图预设继续隔离,不能替代 40250 服务器命令。
4. 建立真实地图快速切换、暂停恢复、环境资源缺失、重复加载/卸载和粒子/天空无悬挂节点的组合测试。
5. 对 SnowEnvironment 的池化、世界范围、风/重力、相机边界和 outdoor render 时序补专门实现或明确平台适配合同。
## 下一轮验证入口
- 进入实现阶段后,优先修复正式 GameScene 的天气/地图环境接入和 fog/filter/lens flare/wind 中的已确认 GAP;修复后重新运行本合同四组测试并增加真实渲染证据。
### 2026-09-22 死代码删除
以下文件只被自身测试引用、运行时从不加载,已删除;本文中以它们为实现或证据的结论作废,相关行为需按 40250 源码单元重新移植:`test_weather_daynight_parity.gd`, `weather_daynight_system.gd`