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>
109 lines
12 KiB
Markdown
109 lines
12 KiB
Markdown
# 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 fog,begin/end 被 clamp,curve=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`。
|