# lifecycle.platform_release —— Windows/桌面窗口、导出、资源自包含、崩溃和发布门禁 状态:`PARTIAL` 本合同检查 40250 的 Win32 应用/窗口消息循环、全屏与窗口状态、资源自包含、版本/CRC 检查、异常退出、前后台处理和发布产物。判断标准是目标平台上是否具备相同的启动、窗口、资源、错误处理和退出副作用;“某个平台能导出”不能代替 Windows 40250 等价实现。 ## 40250 参考调用链 - `EterLib/MSApplication.cpp` / `MSWindow.cpp` - `CMSApplication::Initialize` 保存 HINSTANCE,`MessageLoop` 通过 `GetMessage/TranslateMessage/DispatchMessage` 驱动窗口;`WM_CLOSE` 转为退出消息。 - `CMSWindow` 注册 Win32 窗口类,创建 HWND,处理 `WM_SIZE`、`WM_ACTIVATEAPP`、显示/隐藏、窗口/客户区尺寸、鼠标坐标、居中、位置和全屏窗口尺寸。 - `UserInterface/PythonApplication.cpp` / `PythonApplicationProcedure.cpp` - 初始化 800×600、60 FPS、相机/渲染/网络/音频/Granny 共享资源,并在非 Debug 模式安装 Eter 异常处理器。 - `WM_ACTIVATEAPP` 负责音量 Save/Restore 和全屏显示模式切换;`WM_SIZE`/`WM_EXITSIZEMOVE` 重建 back buffer;`WM_CLOSE` 按构建配置退出或进入退出流程。 - 统一处理 IME 消息、鼠标 capture、输入和窗口激活状态,主循环按固定帧/网络/场景更新顺序执行。 - `UserInterface/CheckLatestFiles.cpp` - 可选编译 `CHECK_LATEST_DATA_FILES` 时启动低优先级线程,对 `CRC32_inc.h` 中的文件逐个检查可读性和 CRC;错误通过 Application error string 触发退出。 - `EterPack/*` / `Locale*` - 运行时从 EterPack/locale 读取资源,并通过版本/资源链保证客户端数据完整;坏资源和版本不匹配有明确失败路径。 ## 当前端实现映射 - `project/client_main.gd` / `project/app_flow.gd` - 已有 Godot 主场景、AppFlow 状态机、登录→选人→游戏切换、断线重连和测试模式;客户端启动时配置协议、AssetPack 和资源根。 - Godot MainLoop 取代 Win32 `CMSApplication`,没有 40250 的 HWND 类注册、Win32 消息分派、back buffer resize 和全屏显示模式切换等价代码。 - `project/app_lifecycle.gd` - 已处理 Godot 的暂停/恢复、窗口焦点、内存警告、Android 返回和桌面关闭信号,后台降 FPS 并绑定客户端/音频。 - 窗口失焦/重新获得焦点现在复用后台入口,分别执行音量保存、BGM/SFX 静音和恢复;关闭请求目前主要发信号,仍未形成与 40250 `WM_CLOSE`/`PostQuitMessage`/退出清理一致的统一出口。 - `project/asset_root.gd` / `asset_pack.gd` / `build-macos-client.sh` / `build-android.sh` / `project/export_presets.cfg` - macOS 脚本将 assets/bgm 复制到 app Resources,Android 使用 `assets.zip`/`asset_index.txt`,AssetRoot 支持环境变量、散文件、包内资源和可执行文件旁资源。 - 当前没有 Windows 导出预设或 Windows GDExtension 构建脚本;资源链也不是 EterPack 的原生 eix/epk/CRC/更新流程,移动端还依赖外部 zip。 - `oracle/*` - 有 Windows/Wine Granny 对拍工具和文档,但它是测试 oracle,不是客户端发布/崩溃/版本链。 ## 分支等价矩阵 | 40250 判据/副作用 | 当前实现 | 结论 | |---|---|---| | Win32 HINSTANCE/HWND、窗口类、消息循环和 WM_CLOSE | Godot MainLoop/Window | 平台适配;没有 Windows 40250 同链实现,Windows 发布未闭合 | | WM_SIZE/EXITSIZEMOVE、back buffer resize、窗口/客户区尺寸 | Godot 窗口系统自动处理,脚本未提供等价回调证据 | 部分等价;缺 Windows 原生尺寸/渲染设备恢复测试 | | 前后台激活、全屏显示模式切换和音量保存恢复 | AppLifecycle 对 focus/pause 统一进入/退出后台,保存并恢复 BGM/SFX;全屏切换由 Godot 配置承担 | 部分等价;焦点音量副作用已有回归,Win32 全屏显示模式分支仍缺失 | | 初始化/固定帧/网络/渲染/退出顺序 | AppFlow/GameScene/Godot scene tree 已有状态机 | 部分等价;没有与 `CPythonApplication::Process` 更新顺序和异常中止路径的生产级证据 | | Eter 异常处理、Abort/Exit 和错误退出 | Godot 日志/进程退出,未发现专用异常处理器和 crash report | GAP;崩溃收集、错误字符串和资源回收链未对齐 | | CheckLatestFiles CRC/可读性/低优先级线程更新检查 | 没有对应版本/CRC 更新线程 | GAP | | EterPack/locale 自包含和坏资源失败回退 | AssetRoot/AssetPack/外部 assets.zip/手工复制 | 部分等价;资源来源可用,但原生 pack、版本校验、坏包/缺包门禁和 Windows 路径未闭合 | | Windows 导出、GDExtension、资源自包含和启动验证 | 只有 macOS/Android 导出预设;macOS 导出探针通过 | GAP(Windows);其它平台基础导出通过 | | 应用关闭、场景释放、音频/网络/模型清理 | queue_free、AppFlow 状态切换和局部生命周期测试 | 部分等价;没有 Windows 关闭消息、崩溃中止和整包资源释放门禁 | ## 已执行测试 - `project/app_flow_lifecycle_test.gd`:通过;覆盖 AppFlow 单一生命周期属主、登录/游戏断线重连和场景状态摘要。 - `project/bgm_test.gd`:通过;覆盖窗口失焦/获得焦点时 BGM/SFX 保存、静音和恢复;修复前该回归有 2 项失败。 - `project/dds_lifecycle_test.gd`:通过;20 次 DDS 解码后图像仍有效且节点计数不变。 - `godot --headless --path project --editor --quit`:退出码 0,脚本/GDExtension/项目结构校验完成;过程自动补建若干缺失 `.uid` 缓存文件,未发现阻断错误。 - `godot --headless --path project --export-release macOS /tmp/mtgodot-platform-audit.app`:退出码 0,macOS 导出流程通过;该结果不代表 Windows 导出可用。 ## Deep audit round 2026-09-21 ### Fresh regression results - `app_flow_lifecycle_test.gd`、`dds_lifecycle_test.gd` 均退出码 0;覆盖生命周期属主和 DDS 资源解码后对象稳定性。 - `godot --headless --path project --editor --quit` 退出码 0,但编辑器自动重建了缺失的 `view_equipment_ui_test.gd.uid`,且在无 Android daemon 时出现连接拒绝提示;这不是 Windows 发布验证。 - 当前没有 Windows export preset/GDExtension 构建脚本;本轮没有把 macOS/Android 结果替代 Windows 发布通过。 ### Static parity conclusion - Godot MainLoop/AppLifecycle 能覆盖跨平台基础生命周期,且焦点音量保存/恢复已对齐 `WM_ACTIVATEAPP` 的可观察副作用,但没有 40250 Win32 HWND/WM_SIZE/WM_CLOSE、Eter 异常处理、CRC 更新检查和统一崩溃/退出链。 - 资源合同确认的 PCK/zip/loose 入口和当前自定义 pack 不能直接证明 Windows 自包含资源、坏包/缺包阻断、版本校验和路径大小写行为。 - 未发现可执行的 Windows 导出、Windows GDExtension 和启动/连接/地图/音频/退出冒烟门禁,因此平台发布合同继续保持 PARTIAL。 本轮仍为 `PARTIAL`,完成焦点激活链的实现和第三轮平台生命周期证据登记。 ### Implementation fix round 2026-09-22T09:10Z - 修复前新增的 `bgm_test.gd` 失焦回归出现 2 项失败:`WM_WINDOW_FOCUS_OUT` 不会静音 BGM/SFX,重新获得焦点也没有恢复备份音量。 - 参考 `CPythonApplication::WindowProcedure` 的 `WM_ACTIVATEAPP` 分支,`AppLifecycle._notification` 现在在 `APPLICATION_FOCUS_OUT`/`WM_WINDOW_FOCUS_OUT` 调用 `_enter_background()`,在对应 `*_FOCUS_IN` 调用 `_exit_background()`;`_bg` 守卫避免同时收到 pause/focus 通知时重复保存或恢复。 - 修复后 `bgm_test.gd`、`app_flow_lifecycle_test.gd`、`mouse_controller_test.gd`、`audio_miles_test.gd` 通过。全屏显示模式、WM_SIZE/back-buffer、Windows 导出和 Win32 异常/CRC 链仍为平台级未闭合项。 ### Active EterLib device-core review - `EterLib/GrpDevice.cpp`、`GrpScreen.cpp`、`GrpShadowTexture.cpp` 负责 D3D 设备/交换链创建、back buffer、lost/reset、屏幕尺寸和阴影纹理资源;这些不是单纯由窗口系统自动替代的 UI 行为,而是和渲染资源、全屏切换、设备丢失恢复绑定的状态机。 - 当前 Godot renderer 由引擎托管,`AppLifecycle` 只收到焦点/暂停/窗口通知,没有对应的设备创建、lost-device、reset、back-buffer 和 shadow texture 重建回调,也没有 Windows 目标上的验证矩阵。 - 因此本轮完成上述活跃 EterLib 图形设备源码静态核对;Godot editor/macOS 导出通过不能证明 Windows D3D/窗口/设备恢复一致,平台合同继续为 `PARTIAL`。 ### Active EterLib graphics/runtime utility review - `EterLib/GrpDetector.cpp` 枚举 adapter/display mode/pixel format/capability;`GrpBase.cpp` 维护 back buffer、camera/projection/view、default index buffer、dynamic vertex stream 和 screen effects;`StateManager.cpp` 保存/恢复 D3D render/texture/shader/transform/stream/index/material 状态。 - `GrpVertexBuffer*`、`GrpIndexBuffer*`、`GrpD3DXBuffer`、`GrpPixelShader`/`GrpVertexShader`、`GrpLightManager`、`GrpObjectInstance` 和 `GrpColorInstance` 分别管理 GPU buffer/shader/light/object transform/color transition;当前 Godot renderer 将这些责任下沉给引擎,没有对应 Windows lost/reset 和状态恢复 oracle。 - `Pool.h`、`Dynamic.h`、`Ref.h`/`ReferenceObject.cpp`、`Thread.cpp`、`Event.h`、`Mutex.h` 形成参考端池化、引用计数、线程、事件排序和同步清理基础;当前端虽有 queue_free/RefCounted/SceneTree,但池容量、引用自毁、线程 shutdown 和按时间排序事件没有同一可观察契约。 - 本轮完成 EterLib 图形/runtime utility 活跃文件静态核对,合同仍为 `PARTIAL`。 ### Active UserInterface platform-host review - `PythonSystem.cpp` 的配置文件、分辨率/频率枚举、窗口状态、音量/阴影/光标和 D3D adapter 查询,与当前 Godot `project/system_options.gd`/`app_lifecycle.gd` 的配置来源和窗口能力不同。 - `PythonApplicationLogo.cpp`/`MovieMan.cpp` 通过 DirectShow/DirectDraw surface 驱动开场视频并恢复 D3D 状态;当前项目没有等价的 Windows media surface/skip/fade 生命周期。 - `ProcessCRC`、`ProcessScanner`、`PythonExceptionSender` 与 GameGuard/HackShield/XTrap 提供参考端完整性/异常/安全发布门禁;当前没有相应的 Windows 组件和可执行验证。静态核对完成,但这些平台能力仍明确为 `PARTIAL/GAP`。 ## 已确认差异和未验证项 1. 增加 Windows 导出预设、Windows GDExtension 构建和资源自包含脚本,至少验证启动、连接、地图/模型/音频资源加载和退出。 2. 建立平台窗口合同:窗口大小/客户区、resize、全屏/窗口化、激活/失焦、关闭、鼠标坐标和输入法消息的运行时快照。 3. 建立发布资源门禁:资源清单、哈希/版本、缺包/坏包/权限失败、路径大小写和外部 zip/PCK 解包失败均必须可诊断并阻断启动。 4. 补充崩溃/异常/退出测试和诊断日志;区分正常关闭、网络断开、资源失败、GDExtension 加载失败和 native crash。 5. 将 Windows、macOS、Android 的导出产物、资源来源、版本号和回归测试结果写入发布报告,避免把单平台导出通过误记为完整发布通过。 ## 下一轮验证入口 - `world.environment_weather` 是当前唯一尚未逐分支审计的映射域;完成后生成全清单覆盖报告,再进入按优先级修复阶段。