Files
mtgodot-poc/audit/contracts/lifecycle.platform-release.md
T
shenandshen c93894313a fix: 装备属性面板避让逻辑 + 多项功能更新
- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧
- inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域
- 包含其他累积的功能开发和测试文件
2026-09-21 16:38:59 -07:00

11 KiB
Raw Blame History

lifecycle.platform_release —— Windows/桌面窗口、导出、资源自包含、崩溃和发布门禁

状态:PARTIAL

本合同检查 40250 的 Win32 应用/窗口消息循环、全屏与窗口状态、资源自包含、版本/CRC 检查、异常退出、前后台处理和发布产物。判断标准是目标平台上是否具备相同的启动、窗口、资源、错误处理和退出副作用;“某个平台能导出”不能代替 Windows 40250 等价实现。

40250 参考调用链

  • EterLib/MSApplication.cpp / MSWindow.cpp
    • CMSApplication::Initialize 保存 HINSTANCEMessageLoop 通过 GetMessage/TranslateMessage/DispatchMessage 驱动窗口;WM_CLOSE 转为退出消息。
    • CMSWindow 注册 Win32 窗口类,创建 HWND,处理 WM_SIZEWM_ACTIVATEAPP、显示/隐藏、窗口/客户区尺寸、鼠标坐标、居中、位置和全屏窗口尺寸。
  • UserInterface/PythonApplication.cpp / PythonApplicationProcedure.cpp
    • 初始化 800×600、60 FPS、相机/渲染/网络/音频/Granny 共享资源,并在非 Debug 模式安装 Eter 异常处理器。
    • WM_ACTIVATEAPP 负责音量 Save/Restore 和全屏显示模式切换;WM_SIZE/WM_EXITSIZEMOVE 重建 back bufferWM_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 ResourcesAndroid 使用 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.gddds_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::WindowProcedureWM_ACTIVATEAPP 分支,AppLifecycle._notification 现在在 APPLICATION_FOCUS_OUT/WM_WINDOW_FOCUS_OUT 调用 _enter_background(),在对应 *_FOCUS_IN 调用 _exit_background()_bg 守卫避免同时收到 pause/focus 通知时重复保存或恢复。
  • 修复后 bgm_test.gdapp_flow_lifecycle_test.gdmouse_controller_test.gdaudio_miles_test.gd 通过。全屏显示模式、WM_SIZE/back-buffer、Windows 导出和 Win32 异常/CRC 链仍为平台级未闭合项。

Active EterLib device-core review

  • EterLib/GrpDevice.cppGrpScreen.cppGrpShadowTexture.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/capabilityGrpBase.cpp 维护 back buffer、camera/projection/view、default index buffer、dynamic vertex stream 和 screen effectsStateManager.cpp 保存/恢复 D3D render/texture/shader/transform/stream/index/material 状态。
  • GrpVertexBuffer*GrpIndexBuffer*GrpD3DXBufferGrpPixelShader/GrpVertexShaderGrpLightManagerGrpObjectInstanceGrpColorInstance 分别管理 GPU buffer/shader/light/object transform/color transition;当前 Godot renderer 将这些责任下沉给引擎,没有对应 Windows lost/reset 和状态恢复 oracle。
  • Pool.hDynamic.hRef.h/ReferenceObject.cppThread.cppEvent.hMutex.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 生命周期。
  • ProcessCRCProcessScannerPythonExceptionSender 与 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 是当前唯一尚未逐分支审计的映射域;完成后生成全清单覆盖报告,再进入按优先级修复阶段。