- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
11 KiB
11 KiB
lifecycle.platform_release —— Windows/桌面窗口、导出、资源自包含、崩溃和发布门禁
状态:PARTIAL
本合同检查 40250 的 Win32 应用/窗口消息循环、全屏与窗口状态、资源自包含、版本/CRC 检查、异常退出、前后台处理和发布产物。判断标准是目标平台上是否具备相同的启动、窗口、资源、错误处理和退出副作用;“某个平台能导出”不能代替 Windows 40250 等价实现。
40250 参考调用链
EterLib/MSApplication.cpp/MSWindow.cppCMSApplication::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。
- macOS 脚本将 assets/bgm 复制到 app Resources,Android 使用
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 查询,与当前 Godotproject/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。
已确认差异和未验证项
- 增加 Windows 导出预设、Windows GDExtension 构建和资源自包含脚本,至少验证启动、连接、地图/模型/音频资源加载和退出。
- 建立平台窗口合同:窗口大小/客户区、resize、全屏/窗口化、激活/失焦、关闭、鼠标坐标和输入法消息的运行时快照。
- 建立发布资源门禁:资源清单、哈希/版本、缺包/坏包/权限失败、路径大小写和外部 zip/PCK 解包失败均必须可诊断并阻断启动。
- 补充崩溃/异常/退出测试和诊断日志;区分正常关闭、网络断开、资源失败、GDExtension 加载失败和 native crash。
- 将 Windows、macOS、Android 的导出产物、资源来源、版本号和回归测试结果写入发布报告,避免把单平台导出通过误记为完整发布通过。
下一轮验证入口
world.environment_weather是当前唯一尚未逐分支审计的映射域;完成后生成全清单覆盖报告,再进入按优先级修复阶段。