Initial import of farm3 project
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Local database dumps should not be pushed by default.
|
||||||
|
*.sql
|
||||||
|
|
||||||
|
# Godot generated/import cache and exported builds.
|
||||||
|
godot/FarmGodot/.godot/
|
||||||
|
godot/FarmGodot/build/
|
||||||
|
godot/FarmGodot/export_credentials.cfg
|
||||||
|
|
||||||
|
# Local dependency installs and logs.
|
||||||
|
node_modules/
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
144
AGENTS.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## Working Agreements
|
||||||
|
|
||||||
|
1. 做任何事情之前不要猜测,先查本地代码、资源、文档、原 H5 行为或官方 API,找最直接的解决方案。
|
||||||
|
2. 所有解决的问题都必须验证。不能只改代码不跑检查。
|
||||||
|
3. 修改时碰到已有改动无需询问,继续在现有改动基础上工作;不要回滚用户或其他代理的改动。
|
||||||
|
4. UI 以原版 H5 运行截图和 Egret 资源为验收标准,不能用“差不多”替代一致。
|
||||||
|
5. 性能优先。新增功能要避免全量重绘、重复加载纹理、常驻无意义 `_process` 和过度创建节点。
|
||||||
|
6. 遇到缺失工具可以直接安装,但要优先使用项目现有工具链,并在最终说明里写清验证命令。
|
||||||
|
|
||||||
|
## Project Scope
|
||||||
|
|
||||||
|
这是 Egret H5 农场游戏到 Godot 4.6.2 的 H5 重构项目。
|
||||||
|
|
||||||
|
- Godot 工程:`godot/FarmGodot`
|
||||||
|
- 启动场景:`godot/FarmGodot/scenes/bootstrap.tscn`
|
||||||
|
- 主 UI 场景:`godot/FarmGodot/scenes/ui/game_scene.tscn`
|
||||||
|
- 主场景脚本:`godot/FarmGodot/scripts/ui/game_scene.gd`
|
||||||
|
- 原 H5/后端参考:`muchang/`
|
||||||
|
- UI 基准和 smoke 截图:`docs/ui-baseline/`
|
||||||
|
|
||||||
|
默认自动登录在 `godot/FarmGodot/scripts/bootstrap.gd`:
|
||||||
|
|
||||||
|
- 账号:`13800000001`
|
||||||
|
- 密码:`123456`
|
||||||
|
|
||||||
|
后端地址配置在 `godot/FarmGodot/project.godot`:
|
||||||
|
|
||||||
|
- `farm_game/api/base_url = http://127.0.0.1:18082/index.php?r=`
|
||||||
|
- `farm_game/api/login_path = user/login`
|
||||||
|
|
||||||
|
## Current Architecture
|
||||||
|
|
||||||
|
`game_scene.gd` 当前是主场景协调层,目标是保持很薄。不要把新功能大块写回这个文件。
|
||||||
|
|
||||||
|
核心装配和运行时模块:
|
||||||
|
|
||||||
|
- `scripts/ui/game_scene.gd`:场景生命周期、节点引用、少量状态同步和跨模块回调桥接。
|
||||||
|
- `scripts/ui/game_scene_bootstrap.gd`:创建服务、状态、规则、资源缓存、Facade、Controller 和 Panel。
|
||||||
|
- `scripts/ui/game_scene_runtime_assembler.gd`:装配 HUD、菜单、ModalLayer、宠物展示、缩放根节点、土地网格、土地菜单、种子包、种植提示和 hit 路由。
|
||||||
|
- `scripts/ui/game_scene_panel_router.gd`:统一面板入口、弹窗打开/关闭、房屋/土地扩建入口、宠物/活动/支付等面板打开流程。
|
||||||
|
- `scripts/ui/scene_hit_router.gd`:顶部、左侧、建筑、宠物等点击热区和直接命中兜底。
|
||||||
|
- `scripts/ui/farm/farm_interaction_coordinator.gd`:土地点击、长按、选中光圈、动作菜单、背包和作物提示交互。
|
||||||
|
|
||||||
|
业务分层:
|
||||||
|
|
||||||
|
- `scripts/services/`:后端 API。网络请求必须走 `ApiClient` 和对应 `*_api.gd`。
|
||||||
|
- `scripts/state/`:玩家、农场、库存等本地状态和 Facade。
|
||||||
|
- `scripts/domain/rules/`:纯规则判断,例如作物阶段、土地动作、消耗判断。
|
||||||
|
- `scripts/domain/mappers/`:后端数据到 Godot 本地结构的归一化。
|
||||||
|
- `scripts/resources/`:Egret 图集区域和 `AtlasTexture` 缓存。
|
||||||
|
- `scripts/ui/common/`:通用 UI 构建、纹理提供、弹窗层、动效工具。
|
||||||
|
- `scripts/ui/panels/`:各功能面板。新增面板优先继承或复用 `PanelModule`、`UiBuilder`、`TextureProvider`。
|
||||||
|
|
||||||
|
当前 `game_scene.gd` 已降到 1200 行以内。后续架构目标是把跨模块回调字典继续收敛为显式 `GameSceneContext`,并保持新增功能独立成模块。
|
||||||
|
|
||||||
|
## Source Lookup Order
|
||||||
|
|
||||||
|
遇到行为、接口、资源或 UI 不确定时,按这个顺序查:
|
||||||
|
|
||||||
|
1. `docs/ui-baseline/` 和原 H5 运行截图。
|
||||||
|
2. `muchang/home/web/game/` 中的 JS、EXML、资源 JSON。
|
||||||
|
3. `muchang/` 里的 PHP/Yii 接口和 `muchang_20211111_141209.sql`。
|
||||||
|
4. Godot 4.6 官方文档和类参考。
|
||||||
|
5. 官方没有覆盖时再查 GitHub 或社区资料,并记录来源。
|
||||||
|
|
||||||
|
不要凭记忆猜接口名、资源名、节点坐标、Godot API 或原版 UI 行为。
|
||||||
|
|
||||||
|
## Implementation Rules
|
||||||
|
|
||||||
|
- 新功能先判断归属层级:接口进 `services/`,状态进 `state/`,规则进 `domain/`,资源进 `resources/`,显示进 `ui/`。
|
||||||
|
- 新面板放到 `scripts/ui/panels/<feature>_panel.gd`,不要堆进 `game_scene.gd`。
|
||||||
|
- 新主场景入口接入 `GameScenePanelRouter` 或 `SceneHitRouter`,不要在场景脚本里新增一串 `_open_*` 包装。
|
||||||
|
- 土地相关交互优先放入 `FarmInteractionCoordinator`、`LandGridView`、`LandActionMenu`、`SeedBagView`、`PlantTipView`。
|
||||||
|
- 背包、奖励、消耗、货币变更优先走 `PlayerInventoryFacade`。
|
||||||
|
- 玩家快照字段访问优先走 `PlayerState`,避免新增 `_player_data.get()` 或 `_player_data[...]`。
|
||||||
|
- 跨 UI 模块共享能力优先走 `GameSceneContext`,不要在 Bootstrap 或面板里新增大 callback 字典。
|
||||||
|
- 图集和图标纹理优先走 `TextureProvider`、`IconTextureProvider` 和 `AtlasTextureCache`,不要重复 `load()` 大图或手动裁剪。
|
||||||
|
- Egret `scale9Grid` 对应 Godot `NinePatchRect`,不要用普通 `TextureRect` 直接拉伸九宫格素材。
|
||||||
|
- UI 坐标优先参考 EXML、原图集 JSON 和现有面板实现,不要目测随意摆。
|
||||||
|
|
||||||
|
## Coding Standards
|
||||||
|
|
||||||
|
- 使用 Godot 4.6.2 stable,非 .NET 版本。
|
||||||
|
- 只写 GDScript。
|
||||||
|
- Web 渲染路径保持 Compatibility。
|
||||||
|
- 文件、函数、变量使用 `snake_case`。
|
||||||
|
- 常量使用 `ALL_CAPS`。
|
||||||
|
- 尽量使用明确类型标注,但公共 helper 入口需要兼容普通 `Array` 时不要过度收窄为 `Array[String]`。
|
||||||
|
- 使用 `and`、`or`、`not`,不要写 `&&`、`||`、`!`。
|
||||||
|
- 控件文本要保证移动端不溢出、不重叠。
|
||||||
|
- 新增复杂逻辑只写必要注释,不写空泛注释。
|
||||||
|
|
||||||
|
## Verification Commands
|
||||||
|
|
||||||
|
按修改范围选择验证,不要省略。
|
||||||
|
|
||||||
|
检查单个脚本:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_bootstrap.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_runtime_assembler.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_panel_router.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
P0 规则和配置验证:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --script res://tools/verify_p0.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
工程导入检查:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --import --quit
|
||||||
|
```
|
||||||
|
|
||||||
|
Web 导出:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --export-release Web build/web/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
H5 smoke:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run smoke:godot:web
|
||||||
|
```
|
||||||
|
|
||||||
|
UI 图片对比:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run compare:ui -- <egret.png> <godot.png> <diff.png>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Safety Rules
|
||||||
|
|
||||||
|
- 不要执行 `git reset --hard`、`git checkout --` 等破坏性命令,除非用户明确要求。
|
||||||
|
- 不要删除原始资源、SQL、原 H5、解密 HTML、基准截图或 Web 导出配置。
|
||||||
|
- 不要把临时 `print`、`DEBUG`、一次性截图脚本长期留在代码里。
|
||||||
|
- 不要引入第三方库,除非官方方案不能解决,并且记录版本、来源和许可证。
|
||||||
|
- 不要把 UI 改成新风格。目标是复刻原版 UI 和功能逻辑。
|
||||||
231
README.md
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
# Farm3 Godot H5 重构
|
||||||
|
|
||||||
|
这是一个把原 Egret H5 农场游戏重构到 Godot 4.6.2 的项目。目标是保留原版 UI、动效、后端协议和核心玩法,同时把旧的大脚本拆成可维护、高性能的模块化结构。
|
||||||
|
|
||||||
|
## 当前状态
|
||||||
|
|
||||||
|
- Godot 工程可以自动登录并进入农场主场景。
|
||||||
|
- 默认账号:`13800000001 / 123456`。
|
||||||
|
- 主农场基础闭环已接入:播种、收获、铲除、施肥、浇水、除草、除虫、倒计时、成熟点击。
|
||||||
|
- 主场景入口已接入:商店、仓库、好友、日志、土地升级、充值、等级礼包、幸运转盘、宝箱、福利大厅、系统公告、每日签到、在线礼包、兑换金币、世界菜单、宠物显示。
|
||||||
|
- 土地场景支持双指和滚轮缩放,UI 层不跟随缩放。
|
||||||
|
- P0 架构拆分已完成,`game_scene.gd` 已降到 1200 行以内。
|
||||||
|
- UI 基准截图和 smoke 截图保存在 `docs/ui-baseline/`。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── AGENTS.md # 本项目代理开发规范
|
||||||
|
├── README.md # 项目说明
|
||||||
|
├── docs/ # 架构、迁移、优先级和 UI 基准文档
|
||||||
|
├── godot/FarmGodot/ # Godot 4.6.2 工程
|
||||||
|
│ ├── assets/egret/ # 从原 Egret H5 迁移的资源
|
||||||
|
│ ├── build/web/ # Web 导出产物
|
||||||
|
│ ├── scenes/ # Godot 场景
|
||||||
|
│ ├── scripts/ # GDScript 代码
|
||||||
|
│ └── tools/ # Godot 侧验证脚本
|
||||||
|
├── muchang/ # 原 H5、PHP/Yii 后端和运行参考
|
||||||
|
├── muchang_20211111_141209.sql # 原数据库备份
|
||||||
|
├── package.json # Web smoke 和 UI diff 工具命令
|
||||||
|
└── tools/ # Node/Playwright 验证工具
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- Godot `4.6.2.stable.official.71f334935`
|
||||||
|
- GDScript
|
||||||
|
- Godot Web/H5 导出
|
||||||
|
- Compatibility 渲染
|
||||||
|
- Egret 原始图集、EXML、配置和后端协议
|
||||||
|
- Node.js + Playwright smoke
|
||||||
|
|
||||||
|
确认 Godot 版本:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --version
|
||||||
|
```
|
||||||
|
|
||||||
|
## 后端配置
|
||||||
|
|
||||||
|
后端地址在:
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/project.godot
|
||||||
|
```
|
||||||
|
|
||||||
|
当前默认值:
|
||||||
|
|
||||||
|
```text
|
||||||
|
farm_game/api/base_url="http://127.0.0.1:18082/index.php?r="
|
||||||
|
farm_game/api/login_path="user/login"
|
||||||
|
```
|
||||||
|
|
||||||
|
自动登录账号在:
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/scripts/bootstrap.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
const AUTO_USERNAME := "13800000001"
|
||||||
|
const AUTO_PASSWORD := "123456"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行工程
|
||||||
|
|
||||||
|
从仓库根目录运行 Godot:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --path godot/FarmGodot
|
||||||
|
```
|
||||||
|
|
||||||
|
无界面导入检查:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --import --quit
|
||||||
|
```
|
||||||
|
|
||||||
|
## 导出 H5
|
||||||
|
|
||||||
|
从仓库根目录运行:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --export-release Web build/web/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
导出产物:
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/build/web/
|
||||||
|
```
|
||||||
|
|
||||||
|
启动本地预览:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 -m http.server 8792 --directory godot/FarmGodot/build/web
|
||||||
|
```
|
||||||
|
|
||||||
|
浏览器打开:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://127.0.0.1:8792/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验证命令
|
||||||
|
|
||||||
|
安装 Node 依赖:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install
|
||||||
|
npx playwright install chromium
|
||||||
|
```
|
||||||
|
|
||||||
|
检查关键脚本:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_bootstrap.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_runtime_assembler.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_panel_router.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/common/ui_builder.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
检查 P0 规则和配置:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --script res://tools/verify_p0.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
导出后跑 H5 smoke:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run smoke:godot:web
|
||||||
|
```
|
||||||
|
|
||||||
|
UI 图片对比:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm run compare:ui -- <egret.png> <godot.png> <diff.png>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 当前架构
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/scripts/
|
||||||
|
├── bootstrap.gd # 自动登录、加载主场景
|
||||||
|
├── core/ # 配置目录、数字格式、位图文字
|
||||||
|
├── domain/
|
||||||
|
│ ├── mappers/ # 后端数据归一化
|
||||||
|
│ └── rules/ # 作物阶段、土地动作、消耗判断
|
||||||
|
├── farm/ # 农场操作控制器
|
||||||
|
├── resources/ # 图集区域和 AtlasTexture 缓存
|
||||||
|
├── services/ # 后端 API 服务
|
||||||
|
├── state/ # 玩家、农场、库存状态和 Facade
|
||||||
|
└── ui/
|
||||||
|
├── common/ # UiBuilder、TextureProvider、Modal、动效
|
||||||
|
├── farm/ # 土地网格、动作菜单、背包、种植提示、缩放
|
||||||
|
├── hud/ # 顶部 HUD
|
||||||
|
├── menus/ # 主菜单、世界菜单
|
||||||
|
├── panels/ # 各功能面板
|
||||||
|
├── game_scene.gd # 主场景协调层
|
||||||
|
├── game_scene_context.gd # 跨模块上下文和 legacy callback 兼容层
|
||||||
|
├── game_scene_bootstrap.gd # 服务/状态/面板装配
|
||||||
|
├── game_scene_runtime_assembler.gd
|
||||||
|
├── game_scene_panel_router.gd
|
||||||
|
└── scene_hit_router.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
核心职责:
|
||||||
|
|
||||||
|
- `GameScene`:只保留生命周期、节点引用、土地快照渲染和少量上下文桥接。
|
||||||
|
- `GameSceneContext`:统一提供玩家状态、资源纹理、面板路由和旧面板 callback 兼容入口。
|
||||||
|
- `GameSceneBootstrap`:创建 API、状态、规则、资源、控制器和面板。
|
||||||
|
- `GameSceneRuntimeAssembler`:装配运行时 UI 和土地交互组件。
|
||||||
|
- `GameScenePanelRouter`:统一打开/关闭面板和弹窗入口。
|
||||||
|
- `SceneHitRouter`:管理主场景点击热区。
|
||||||
|
- `FarmInteractionCoordinator`:管理土地选择、长按、背包、菜单和作物提示。
|
||||||
|
- `PlayerInventoryFacade`:统一奖励、消耗、仓库刷新和货币变更。
|
||||||
|
- `PlayerState`:玩家快照唯一权威来源,收敛 token、等级、房屋、皮肤和土地列表等字段访问。
|
||||||
|
|
||||||
|
## 开发原则
|
||||||
|
|
||||||
|
- 先查原 H5 行为、资源 JSON、EXML、JS/PHP 逻辑,再写 Godot 实现。
|
||||||
|
- UI 必须对齐原版,优先使用 Egret 原素材。
|
||||||
|
- 网络请求必须走 `ApiClient` 和 `scripts/services/*_api.gd`。
|
||||||
|
- 状态变化优先走 `scripts/state/` 和 Facade,再刷新 UI。
|
||||||
|
- 新面板放到 `scripts/ui/panels/`,不要堆到 `game_scene.gd`。
|
||||||
|
- 图集纹理优先走 `TextureProvider`、`TextureRegionCatalog`、`AtlasTextureCache`。
|
||||||
|
- 每次修改必须按影响面验证。
|
||||||
|
|
||||||
|
## 关键文档
|
||||||
|
|
||||||
|
- `docs/godot-architecture-flow.md`:整体模块化架构流程。
|
||||||
|
- `docs/godot-architecture-refactor-progress.md`:架构拆分进度。
|
||||||
|
- `docs/godot-refactor-status-priority.md`:P0/P1/P2 功能缺口和优先级。
|
||||||
|
- `docs/godot-development-standards.md`:Godot 开发规范和验证规则。
|
||||||
|
- `docs/godot-migration-rebuild.md`:Godot 重构方案。
|
||||||
|
- `docs/godot-migration-progress.md`:迁移进度。
|
||||||
|
- `docs/ui-baseline/README.md`:UI 基准截图说明。
|
||||||
|
|
||||||
|
## 当前主要缺口
|
||||||
|
|
||||||
|
P0 已完成。下一阶段主要是 P1:
|
||||||
|
|
||||||
|
- 好友搜索、申请、访问好友农场和好友互动。
|
||||||
|
- 世界玩法完整化:成就、竞技场、游乐园、战宠对战。
|
||||||
|
- 换肤/背景完整流程。
|
||||||
|
- 玩家信息面板。
|
||||||
|
- 活动面板逐页像素级对齐。
|
||||||
|
- 音频、FNT、全部原版动画和批量 EXML 辅助转换。
|
||||||
|
|
||||||
|
## 最近验证产物
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/ui-baseline/smoke/
|
||||||
|
docs/ui-baseline/godot-architecture-refactor-main.png
|
||||||
|
docs/ui-baseline/godot-architecture-refactor-land-menu.png
|
||||||
|
docs/ui-baseline/godot-architecture-refactor-land-menu-closed.png
|
||||||
|
docs/ui-baseline/godot-architecture-refactor-main-menu.png
|
||||||
|
docs/ui-baseline/godot-architecture-refactor-meta.json
|
||||||
|
```
|
||||||
637
docs/godot-architecture-flow.md
Normal file
@ -0,0 +1,637 @@
|
|||||||
|
# Godot 架构流程设计
|
||||||
|
|
||||||
|
## 1. 目标
|
||||||
|
|
||||||
|
当前 `godot/FarmGodot/scripts/ui/game_scene.gd` 已经承担了主场景渲染、土地玩法、背包、商店、仓库、好友、房屋升级、狗、弹窗、动画、资源裁剪、接口调用和数据修正等职责,文件长度已超过 3000 行。继续在这个文件里堆功能,会让性能优化、UI 对齐和后续功能开发都变慢。
|
||||||
|
|
||||||
|
重构目标不是立刻重写全部代码,而是建立一套可持续拆分的 Godot 客户端架构:
|
||||||
|
|
||||||
|
- 性能优先:减少节点创建、减少全量重绘、减少 `_process` 常驻逻辑、减少重复纹理加载。
|
||||||
|
- UI 一致:保留 Egret 运行截图作为验收基准,拆分不能改变视觉和动效表现。
|
||||||
|
- 业务清晰:UI 只负责显示和输入,后端协议、数据归一化、玩法规则放到独立模块。
|
||||||
|
- 渐进迁移:每次只拆一个垂直模块,拆完必须跑 Godot 检查、Web 导出和截图验证。
|
||||||
|
|
||||||
|
## 2. 当前问题
|
||||||
|
|
||||||
|
### 2.1 职责混杂
|
||||||
|
|
||||||
|
`GameScene` 当前包含这些职责:
|
||||||
|
|
||||||
|
- 顶部资源栏、经验条、头像、战斗力位图字体。
|
||||||
|
- 主菜单、左侧菜单、顶部入口、弹窗层。
|
||||||
|
- 商店、仓库、好友、房屋升级、土地扩展、狗面板。
|
||||||
|
- 土地点击、长按、圆形操作菜单、成熟倒计时、种植提示。
|
||||||
|
- 播种、收获、铲除、施肥、除虫、除草等后端请求。
|
||||||
|
- 背包数据、仓库数据、消耗扣除、本地土地数据更新。
|
||||||
|
- 图集区域读取、AtlasTexture 创建、通用按钮和标签工厂。
|
||||||
|
|
||||||
|
这些职责应该拆成服务层、状态层、玩法层、UI 层和资源层。
|
||||||
|
|
||||||
|
### 2.2 性能风险
|
||||||
|
|
||||||
|
- 多处运行时动态创建 `TextureRect`、`Button`、`Label`,面板反复打开会产生 GC 和节点树抖动。
|
||||||
|
- `_process` 负责倒计时刷新,后续页面增多后容易变成常驻开销。
|
||||||
|
- 图集区域和 `AtlasTexture` 在 UI 创建阶段按需拼装,缺少统一缓存。
|
||||||
|
- 土地渲染仍有全量清空再重建的路径,后续 12 块地之外的扩展会放大成本。
|
||||||
|
- UI 面板逻辑和接口逻辑绑定在同一个脚本里,不利于做请求节流、失败回滚和本地状态差异更新。
|
||||||
|
|
||||||
|
## 3. 目标分层
|
||||||
|
|
||||||
|
```text
|
||||||
|
Bootstrap / AppRoot
|
||||||
|
-> ServiceRegistry
|
||||||
|
-> SceneRouter
|
||||||
|
-> GameSession
|
||||||
|
-> Feature Scenes
|
||||||
|
|
||||||
|
services/
|
||||||
|
网络、接口、账号、配置、日志
|
||||||
|
|
||||||
|
state/
|
||||||
|
玩家、农场、背包、仓库、UI 临时状态
|
||||||
|
|
||||||
|
domain/
|
||||||
|
纯业务模型、规则、后端数据映射
|
||||||
|
|
||||||
|
features/
|
||||||
|
farm、topbar、main_menu、shop、warehouse、friend、building、dog、sign
|
||||||
|
|
||||||
|
ui/common/
|
||||||
|
通用面板壳、按钮、标签、Tab、虚拟列表、动画工具
|
||||||
|
|
||||||
|
assets/
|
||||||
|
Egret 原始资源、替换资源、生成资源、图集索引和缓存
|
||||||
|
```
|
||||||
|
|
||||||
|
核心规则:依赖只能从上往下,不能反向依赖。
|
||||||
|
|
||||||
|
```text
|
||||||
|
feature UI -> controllers -> domain use cases -> services/state
|
||||||
|
```
|
||||||
|
|
||||||
|
UI 不直接调用 `HTTPRequest`,也不直接解析后端原始字段。服务返回归一化数据,状态层负责保存,UI 订阅状态变化并做局部刷新。
|
||||||
|
|
||||||
|
## 4. 推荐目录
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/
|
||||||
|
scenes/
|
||||||
|
bootstrap.tscn
|
||||||
|
app/
|
||||||
|
app_root.tscn
|
||||||
|
farm/
|
||||||
|
farm_scene.tscn
|
||||||
|
land_slot.tscn
|
||||||
|
crop_view.tscn
|
||||||
|
land_action_menu.tscn
|
||||||
|
plant_tip.tscn
|
||||||
|
seed_bag.tscn
|
||||||
|
ui/
|
||||||
|
top_bar.tscn
|
||||||
|
main_menu.tscn
|
||||||
|
modal_layer.tscn
|
||||||
|
common_panel_shell.tscn
|
||||||
|
tab_bar.tscn
|
||||||
|
panels/
|
||||||
|
shop_panel.tscn
|
||||||
|
warehouse_panel.tscn
|
||||||
|
friend_panel.tscn
|
||||||
|
building_panel.tscn
|
||||||
|
dog_panel.tscn
|
||||||
|
sign_panel.tscn
|
||||||
|
|
||||||
|
scripts/
|
||||||
|
app/
|
||||||
|
app_root.gd
|
||||||
|
scene_router.gd
|
||||||
|
service_registry.gd
|
||||||
|
game_session.gd
|
||||||
|
event_bus.gd
|
||||||
|
services/
|
||||||
|
api_client.gd
|
||||||
|
auth_service.gd
|
||||||
|
farm_api.gd
|
||||||
|
inventory_api.gd
|
||||||
|
shop_api.gd
|
||||||
|
friend_api.gd
|
||||||
|
building_api.gd
|
||||||
|
dog_api.gd
|
||||||
|
state/
|
||||||
|
player_state.gd
|
||||||
|
farm_state.gd
|
||||||
|
inventory_state.gd
|
||||||
|
warehouse_state.gd
|
||||||
|
ui_state.gd
|
||||||
|
domain/
|
||||||
|
models/
|
||||||
|
player_data.gd
|
||||||
|
land_data.gd
|
||||||
|
inventory_item.gd
|
||||||
|
cost.gd
|
||||||
|
rules/
|
||||||
|
land_action_rules.gd
|
||||||
|
crop_phase_rules.gd
|
||||||
|
cost_rules.gd
|
||||||
|
mappers/
|
||||||
|
login_mapper.gd
|
||||||
|
farm_mapper.gd
|
||||||
|
inventory_mapper.gd
|
||||||
|
resources/
|
||||||
|
atlas_texture_cache.gd
|
||||||
|
texture_region_catalog.gd
|
||||||
|
resource_paths.gd
|
||||||
|
node_pool.gd
|
||||||
|
ui/
|
||||||
|
common/
|
||||||
|
bitmap_font_label.gd
|
||||||
|
panel_shell.gd
|
||||||
|
texture_button_view.gd
|
||||||
|
virtual_item_list.gd
|
||||||
|
tween_runner.gd
|
||||||
|
top_bar/
|
||||||
|
top_bar_view.gd
|
||||||
|
main_menu/
|
||||||
|
main_menu_view.gd
|
||||||
|
farm/
|
||||||
|
farm_scene.gd
|
||||||
|
farm_controller.gd
|
||||||
|
land_grid_view.gd
|
||||||
|
land_slot_view.gd
|
||||||
|
crop_view.gd
|
||||||
|
land_action_menu.gd
|
||||||
|
plant_tip_view.gd
|
||||||
|
seed_bag_view.gd
|
||||||
|
panels/
|
||||||
|
shop_panel.gd
|
||||||
|
warehouse_panel.gd
|
||||||
|
friend_panel.gd
|
||||||
|
building_panel.gd
|
||||||
|
dog_panel.gd
|
||||||
|
sign_panel.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. 启动流程
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A["Bootstrap"] --> B["ServiceRegistry.create"]
|
||||||
|
B --> C["AuthService.auto_login"]
|
||||||
|
C --> D["GameSession.set_player"]
|
||||||
|
D --> E["SceneRouter.open FarmScene"]
|
||||||
|
E --> F["FarmScene.setup(session)"]
|
||||||
|
F --> G["TopBarView.bind(PlayerState)"]
|
||||||
|
F --> H["FarmController.bind(FarmState, InventoryState)"]
|
||||||
|
H --> I["FarmState.init_from_login_land_data"]
|
||||||
|
I --> J["LandGridView.render_dirty_slots"]
|
||||||
|
```
|
||||||
|
|
||||||
|
启动阶段只做三件事:
|
||||||
|
|
||||||
|
- 创建全局服务。
|
||||||
|
- 登录并归一化玩家数据。
|
||||||
|
- 打开主农场场景。
|
||||||
|
|
||||||
|
`Bootstrap` 不再持有具体页面逻辑,后续切换账号、进入好友农场、回到家园都走 `SceneRouter`。
|
||||||
|
|
||||||
|
## 6. 状态流
|
||||||
|
|
||||||
|
### 6.1 状态对象
|
||||||
|
|
||||||
|
状态对象只保存数据和版本号,不创建 UI 节点。
|
||||||
|
|
||||||
|
```text
|
||||||
|
PlayerState
|
||||||
|
token
|
||||||
|
user_id
|
||||||
|
nickname
|
||||||
|
level
|
||||||
|
exp
|
||||||
|
gold
|
||||||
|
diamond
|
||||||
|
power
|
||||||
|
house_level
|
||||||
|
dog_level
|
||||||
|
version
|
||||||
|
|
||||||
|
FarmState
|
||||||
|
lands_by_position
|
||||||
|
changed_positions
|
||||||
|
version
|
||||||
|
|
||||||
|
InventoryState
|
||||||
|
seeds
|
||||||
|
fertilizers
|
||||||
|
warehouse_items
|
||||||
|
version
|
||||||
|
|
||||||
|
UIState
|
||||||
|
selected_land_position
|
||||||
|
active_panel
|
||||||
|
menu_open
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 更新原则
|
||||||
|
|
||||||
|
- 后端请求成功后,先更新状态,再通知 UI。
|
||||||
|
- 单块土地变化只标记 `changed_positions`,禁止整块农场全量重绘。
|
||||||
|
- 玩家资源变化只刷新 TopBar,不刷新主场景。
|
||||||
|
- 背包物品数量变化只刷新对应 item,不重建整个 ScrollContainer。
|
||||||
|
- 失败请求不改状态,只显示 toast 或错误态。
|
||||||
|
|
||||||
|
## 7. 土地玩法流程
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
participant LandSlot
|
||||||
|
participant FarmController
|
||||||
|
participant Rules as LandActionRules
|
||||||
|
participant Menu as LandActionMenu
|
||||||
|
participant Api as FarmApi
|
||||||
|
participant State as FarmState
|
||||||
|
|
||||||
|
LandSlot->>FarmController: pressed(position)
|
||||||
|
FarmController->>Rules: get_actions(land_data)
|
||||||
|
Rules-->>FarmController: actions
|
||||||
|
FarmController->>Menu: show(position, actions)
|
||||||
|
Menu->>FarmController: action_selected(action)
|
||||||
|
FarmController->>Api: request(action, payload)
|
||||||
|
Api-->>FarmController: normalized_result
|
||||||
|
FarmController->>State: apply_land_result(position, result)
|
||||||
|
State-->>LandSlot: dirty update
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.1 拆分模块
|
||||||
|
|
||||||
|
- `LandActionRules`:判断空地、成长中、成熟、虫草旱、可收获、可铲除。
|
||||||
|
- `CropPhaseRules`:根据 `seed_time`、`crop_id`、配置时间计算阶段和剩余时间。
|
||||||
|
- `FarmApi`:封装 `farm/sow-seeds`、`farm/gather-crop`、`farm/clear-land`、`farm/fertilize`、`farm/disease`。
|
||||||
|
- `FarmMapper`:把后端字段归一化为 `LandData`。
|
||||||
|
- `FarmController`:连接输入、规则、接口、状态。
|
||||||
|
- `LandGridView`:只管理 12 个 `LandSlotView`。
|
||||||
|
- `LandSlotView`:只管单块土地的底图、作物、状态图标、点击热区。
|
||||||
|
- `LandActionMenu`:只管圆形菜单的弹出、收回、按压动效。
|
||||||
|
- `PlantTipView`:只管倒计时面板显示。
|
||||||
|
|
||||||
|
### 7.2 性能规则
|
||||||
|
|
||||||
|
- `LandSlotView` 常驻 12 个节点,初始化后不销毁。
|
||||||
|
- 作物 `TextureRect`、虫草旱状态图标从 `NodePool` 复用。
|
||||||
|
- 土地刷新入口只接受 `position`,默认不允许全量刷新。
|
||||||
|
- 成熟倒计时使用一个 `Timer` 每秒驱动,只更新可见 `PlantTipView`,不扫描全部 UI。
|
||||||
|
- 圆形菜单打开时创建或复用固定数量按钮,不在每次点击时重新加载纹理。
|
||||||
|
|
||||||
|
## 8. 面板流程
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A["MainMenuView item pressed"] --> B["ModalLayer.open(panel_id)"]
|
||||||
|
B --> C["PanelFactory.get_or_create"]
|
||||||
|
C --> D["Panel.bind(state/services)"]
|
||||||
|
D --> E["Panel.show_enter_animation"]
|
||||||
|
E --> F["Panel requests data if stale"]
|
||||||
|
F --> G["State update"]
|
||||||
|
G --> H["Panel render dirty list"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.1 面板拆分
|
||||||
|
|
||||||
|
每个面板是独立 `.tscn + .gd`:
|
||||||
|
|
||||||
|
- `ShopPanel`:商店 tabs、商品列表、购买按钮。
|
||||||
|
- `WarehousePanel`:仓库 tabs、出售弹窗、数量步进器。
|
||||||
|
- `FriendPanel`:好友列表、排序、翻页、访问好友家园。
|
||||||
|
- `BuildingPanel`:房屋升级、土地扩展。
|
||||||
|
- `DogPanel`:狗状态、狗粮选择、喂养。
|
||||||
|
- `SignPanel`:签到面板,后续接入新签到资源。
|
||||||
|
|
||||||
|
公共能力放 `ui/common`:
|
||||||
|
|
||||||
|
- `PanelShell`:标题、关闭按钮、背景九宫格。
|
||||||
|
- `TabBar`:选中态和禁用态。
|
||||||
|
- `VirtualItemList`:复用可见 item,避免大量节点。
|
||||||
|
- `TextureButtonView`:统一按钮按压缩放、禁用态、音效钩子。
|
||||||
|
|
||||||
|
### 8.2 面板缓存
|
||||||
|
|
||||||
|
- 弹窗默认懒加载,第一次打开实例化,后续隐藏复用。
|
||||||
|
- 大列表只创建屏幕可见 item 加少量缓冲。
|
||||||
|
- 面板关闭只停止动画和输入,不释放资源;内存压力确认后再引入 LRU。
|
||||||
|
|
||||||
|
## 9. 资源和图集
|
||||||
|
|
||||||
|
### 9.1 资源原则
|
||||||
|
|
||||||
|
- `assets/egret` 保存原始迁移资源,不在业务代码里直接到处写路径。
|
||||||
|
- `assets/replacement` 保存替换素材。
|
||||||
|
- 后续生成的独立图标、裁剪图集和字体索引放 `assets/generated`。
|
||||||
|
- 所有图集区域通过 `TextureRegionCatalog` 查找。
|
||||||
|
- 所有 `AtlasTexture` 通过 `AtlasTextureCache` 获取。
|
||||||
|
|
||||||
|
### 9.2 AtlasTextureCache
|
||||||
|
|
||||||
|
目标接口:
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
func get_region(atlas_path: String, region_name: String) -> Texture2D
|
||||||
|
func get_rect(atlas_path: String, region_name: String) -> Rect2
|
||||||
|
func preload_group(group_name: String) -> void
|
||||||
|
func clear_unused() -> void
|
||||||
|
```
|
||||||
|
|
||||||
|
性能要求:
|
||||||
|
|
||||||
|
- 同一个 `atlas_path + region_name` 只创建一次 `AtlasTexture`。
|
||||||
|
- 高频 UI 的图集在场景进入时预加载。
|
||||||
|
- 不在 `_process`、列表 item 创建循环里解析 JSON。
|
||||||
|
|
||||||
|
## 10. 网络和用例
|
||||||
|
|
||||||
|
### 10.1 ApiClient
|
||||||
|
|
||||||
|
`ApiClient` 只负责:
|
||||||
|
|
||||||
|
- URL 拼接。
|
||||||
|
- Egret `msg=` base64 表单编码。
|
||||||
|
- HTTP 请求。
|
||||||
|
- JSON 解析。
|
||||||
|
- HTTP 状态和业务状态包装。
|
||||||
|
|
||||||
|
### 10.2 Feature Api
|
||||||
|
|
||||||
|
每个业务 API 包一层,避免 UI 直接传字符串接口名:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AuthService.login(username, password)
|
||||||
|
InventoryApi.fetch_store_house(token)
|
||||||
|
FarmApi.sow_seed(token, position, item_id)
|
||||||
|
FarmApi.gather_crop(token, position)
|
||||||
|
FarmApi.clear_land(token, position)
|
||||||
|
FarmApi.fertilize(token, position, item_id)
|
||||||
|
FarmApi.kick_disease(token, position, type)
|
||||||
|
ShopApi.buy(token, store_id)
|
||||||
|
WarehouseApi.sell(token, item_id, count)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.3 请求性能规则
|
||||||
|
|
||||||
|
- 同一按钮请求中必须禁用重复点击。
|
||||||
|
- 同一资源数据有缓存版本,未过期不重复拉取。
|
||||||
|
- 操作成功后用接口返回增量更新本地状态,不强制重新拉全部玩家数据。
|
||||||
|
- 失败时保留原状态,避免 UI 和服务端不一致。
|
||||||
|
|
||||||
|
## 11. 事件机制
|
||||||
|
|
||||||
|
使用轻量 `EventBus` 或状态信号,不能把所有节点互相 `get_node` 调用。
|
||||||
|
|
||||||
|
推荐事件:
|
||||||
|
|
||||||
|
```text
|
||||||
|
player_changed(player_state)
|
||||||
|
farm_land_changed(position)
|
||||||
|
inventory_changed(item_id)
|
||||||
|
warehouse_changed(item_id)
|
||||||
|
panel_opened(panel_id)
|
||||||
|
panel_closed(panel_id)
|
||||||
|
toast_requested(message)
|
||||||
|
```
|
||||||
|
|
||||||
|
高频事件禁止广播大对象,传 id 或 position,再由接收方按需读取状态。
|
||||||
|
|
||||||
|
## 12. 性能基线
|
||||||
|
|
||||||
|
当前目标是海外 H5,默认 Web 单线程导出,性能预算按中低端手机浏览器设计。
|
||||||
|
|
||||||
|
### 12.1 渲染预算
|
||||||
|
|
||||||
|
- 主农场常驻节点数目标小于 250。
|
||||||
|
- 打开一个普通面板后总节点数目标小于 450。
|
||||||
|
- 单次土地操作后新增临时节点小于 10,并在动画结束后复用或回收。
|
||||||
|
- UI idle 状态 `_process` 逻辑为 0 或只保留一个倒计时入口。
|
||||||
|
|
||||||
|
### 12.2 刷新预算
|
||||||
|
|
||||||
|
- TopBar:只有玩家资源变化时刷新。
|
||||||
|
- LandSlot:只有对应土地变化时刷新。
|
||||||
|
- Bag:只有打开背包或物品数量变化时刷新。
|
||||||
|
- Panel list:只刷新当前 tab 和可见 item。
|
||||||
|
- Texture:场景运行中禁止重复解析同一个图集 JSON。
|
||||||
|
|
||||||
|
### 12.3 动画预算
|
||||||
|
|
||||||
|
- 动效统一走 `TweenRunner`,避免散落创建不可控 Tween。
|
||||||
|
- 高频按钮按压只做 scale/modulate,不做复杂 shader。
|
||||||
|
- 循环动画必须在节点隐藏时停止。
|
||||||
|
- 面板关闭时要 kill 关联 tween,避免隐藏节点继续动画。
|
||||||
|
|
||||||
|
## 13. 迁移顺序
|
||||||
|
|
||||||
|
### 阶段 0:冻结基准
|
||||||
|
|
||||||
|
- 保存当前 Godot 主场景截图。
|
||||||
|
- 保存新版 HTML 主场景截图。
|
||||||
|
- 记录当前可用功能:自动登录、主场景、土地菜单、播种、收获、铲除、施肥、除虫、除草、倒计时、背包、主要面板。
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- `godot --headless --path godot/FarmGodot --import --quit`
|
||||||
|
- `godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene.gd`
|
||||||
|
- Web 导出和浏览器截图通过。
|
||||||
|
|
||||||
|
### 阶段 1:抽资源层
|
||||||
|
|
||||||
|
先从 `GameScene` 抽出无业务风险的资源工具:
|
||||||
|
|
||||||
|
- `TextureRegionCatalog`
|
||||||
|
- `AtlasTextureCache`
|
||||||
|
- `ResourcePaths`
|
||||||
|
- `NodePool`
|
||||||
|
- 通用 `_add_texture`、`_add_nine_patch`、`_add_panel_label`、`_add_texture_button`
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 主场景截图不变。
|
||||||
|
- 打开商店、仓库、好友、土地菜单无缺图。
|
||||||
|
|
||||||
|
### 阶段 2:抽状态和规则
|
||||||
|
|
||||||
|
抽纯逻辑,不动 UI 节点布局:
|
||||||
|
|
||||||
|
- `PlayerState`
|
||||||
|
- `FarmState`
|
||||||
|
- `InventoryState`
|
||||||
|
- `LandActionRules`
|
||||||
|
- `CropPhaseRules`
|
||||||
|
- `FarmMapper`
|
||||||
|
- `InventoryMapper`
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 播种、收获、铲除、施肥、除虫、除草结果一致。
|
||||||
|
- 土地倒计时和成熟判断一致。
|
||||||
|
|
||||||
|
### 阶段 3:抽农场玩法
|
||||||
|
|
||||||
|
把土地相关 1000 行左右逻辑迁到 farm feature:
|
||||||
|
|
||||||
|
- `FarmController`
|
||||||
|
- `LandGridView`
|
||||||
|
- `LandSlotView`
|
||||||
|
- `LandActionMenu`
|
||||||
|
- `PlantTipView`
|
||||||
|
- `SeedBagView`
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 点击土地菜单位置、动效、空白关闭一致。
|
||||||
|
- 成熟点击行为一致。
|
||||||
|
- 单块土地操作后只刷新单块土地。
|
||||||
|
|
||||||
|
### 阶段 4:抽 TopBar 和主菜单
|
||||||
|
|
||||||
|
- `TopBarView`
|
||||||
|
- `MainMenuView`
|
||||||
|
- `LeftMenuView`
|
||||||
|
- `TopEntryMenuView`
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 顶部资源文字、战斗力位图、经验条、头像位置不变。
|
||||||
|
- 主菜单展开和收起动效不变。
|
||||||
|
|
||||||
|
### 阶段 5:抽面板
|
||||||
|
|
||||||
|
按风险从低到高拆:
|
||||||
|
|
||||||
|
1. `FriendPanel`
|
||||||
|
2. `WarehousePanel`
|
||||||
|
3. `ShopPanel`
|
||||||
|
4. `BuildingPanel`
|
||||||
|
5. `DogPanel`
|
||||||
|
6. `SignPanel`
|
||||||
|
|
||||||
|
验收:
|
||||||
|
|
||||||
|
- 每拆一个面板,单独截图对比。
|
||||||
|
- 面板关闭后节点数不持续增长。
|
||||||
|
|
||||||
|
### 阶段 6:删除旧 GameScene 负担
|
||||||
|
|
||||||
|
最终 `GameScene` 只保留:
|
||||||
|
|
||||||
|
- 场景组合。
|
||||||
|
- 绑定 session。
|
||||||
|
- 转发生命周期给 feature controller。
|
||||||
|
|
||||||
|
目标行数:
|
||||||
|
|
||||||
|
- `farm_scene.gd` 小于 300 行。
|
||||||
|
- 每个 panel 脚本小于 500 行。
|
||||||
|
- 每个 rules/mapper/state 文件小于 250 行。
|
||||||
|
- 单个脚本超过 800 行必须继续拆分。
|
||||||
|
|
||||||
|
## 14. 文件迁移映射
|
||||||
|
|
||||||
|
```text
|
||||||
|
game_scene.gd:_render_player
|
||||||
|
-> top_bar/top_bar_view.gd
|
||||||
|
-> state/player_state.gd
|
||||||
|
|
||||||
|
game_scene.gd:_setup_main_menu ... _on_main_menu_item_pressed
|
||||||
|
-> main_menu/main_menu_view.gd
|
||||||
|
|
||||||
|
game_scene.gd:_open_shop_panel ... _buy_shop_item
|
||||||
|
-> panels/shop_panel.gd
|
||||||
|
-> services/shop_api.gd
|
||||||
|
|
||||||
|
game_scene.gd:_open_warehouse_panel ... _sell_warehouse_item
|
||||||
|
-> panels/warehouse_panel.gd
|
||||||
|
-> state/warehouse_state.gd
|
||||||
|
|
||||||
|
game_scene.gd:_open_friend_panel ... _create_friend_row
|
||||||
|
-> panels/friend_panel.gd
|
||||||
|
-> services/friend_api.gd
|
||||||
|
|
||||||
|
game_scene.gd:_open_house_upgrade_panel ... _extend_land
|
||||||
|
-> panels/building_panel.gd
|
||||||
|
-> services/building_api.gd
|
||||||
|
|
||||||
|
game_scene.gd:_open_dog_panel ... _feed_selected_dog_food
|
||||||
|
-> panels/dog_panel.gd
|
||||||
|
-> services/dog_api.gd
|
||||||
|
|
||||||
|
game_scene.gd:_setup_farm_interaction ... _get_land_node
|
||||||
|
-> farm/farm_controller.gd
|
||||||
|
-> farm/land_grid_view.gd
|
||||||
|
-> farm/land_slot_view.gd
|
||||||
|
-> farm/land_action_menu.gd
|
||||||
|
-> farm/plant_tip_view.gd
|
||||||
|
|
||||||
|
game_scene.gd:_refresh_store_house ... _extract_warehouse_items
|
||||||
|
-> services/inventory_api.gd
|
||||||
|
-> domain/mappers/inventory_mapper.gd
|
||||||
|
-> state/inventory_state.gd
|
||||||
|
|
||||||
|
game_scene.gd:_sow_seed ... _kick_disease
|
||||||
|
-> services/farm_api.gd
|
||||||
|
-> farm/farm_controller.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
## 15. 编码规则
|
||||||
|
|
||||||
|
- 每个新脚本必须有 `class_name`,方便类型标注。
|
||||||
|
- UI 脚本可以依赖 controller,controller 不依赖具体 UI 子节点。
|
||||||
|
- 业务规则必须能脱离场景运行。
|
||||||
|
- 后端原始字段只允许 mapper 读取。
|
||||||
|
- UI 节点路径只允许 view 脚本内部使用。
|
||||||
|
- 大量路径常量统一放 `ResourcePaths`。
|
||||||
|
- 不在 `_process` 里做数据解析、资源加载、节点创建。
|
||||||
|
- 不在列表 item 内部直接发请求,请求由 panel/controller 统一管理。
|
||||||
|
- 所有长动画、循环动画在 `_exit_tree` 或隐藏时停止。
|
||||||
|
|
||||||
|
## 16. 验证流程
|
||||||
|
|
||||||
|
每次拆分必须执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
godot --headless --path godot/FarmGodot --import --quit
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene.gd
|
||||||
|
godot --headless --path godot/FarmGodot --export-release Web /tmp/farm-godot-web/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
如果新增了脚本,对新增脚本逐个跑 `--check-only --script`。
|
||||||
|
|
||||||
|
UI 改动必须保存截图:
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/ui-baseline/godot-<feature>-before.png
|
||||||
|
docs/ui-baseline/godot-<feature>-after.png
|
||||||
|
docs/ui-baseline/godot-<feature>-meta.json
|
||||||
|
```
|
||||||
|
|
||||||
|
涉及后端的功能必须记录:
|
||||||
|
|
||||||
|
- 接口路径。
|
||||||
|
- HTTP 状态。
|
||||||
|
- 业务 status。
|
||||||
|
- 关键响应字段。
|
||||||
|
- 本地状态变化。
|
||||||
|
|
||||||
|
## 17. 禁止事项
|
||||||
|
|
||||||
|
- 禁止继续把新页面直接塞进 `game_scene.gd`。
|
||||||
|
- 禁止 UI 直接拼接口路径。
|
||||||
|
- 禁止功能成功后整页重载主场景。
|
||||||
|
- 禁止每次打开菜单都重新解析图集 JSON。
|
||||||
|
- 禁止隐藏面板后保留运行中的循环 tween。
|
||||||
|
- 禁止为了快速开发跳过截图验证。
|
||||||
|
- 禁止用“看起来差不多”替代新版 HTML 基准。
|
||||||
|
|
||||||
|
## 18. 下一步执行建议
|
||||||
|
|
||||||
|
最直接、风险最低的第一步是抽资源层和通用 UI 工厂,因为这部分不改变业务行为:
|
||||||
|
|
||||||
|
1. 新建 `scripts/resources/atlas_texture_cache.gd`。
|
||||||
|
2. 新建 `scripts/resources/texture_region_catalog.gd`。
|
||||||
|
3. 新建 `scripts/ui/common/ui_factory.gd` 或拆成更细的 view helpers。
|
||||||
|
4. 把 `GameScene` 中 `_common_texture`、`_friend_texture`、`_rank_texture`、`_building_texture`、`_landup_texture`、`_sign_texture`、`_region_for`、`_atlas_texture` 迁出。
|
||||||
|
5. 保持所有 UI 截图不变后,再进入状态和农场玩法拆分。
|
||||||
135
docs/godot-architecture-refactor-progress.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# Godot 架构重构进度
|
||||||
|
|
||||||
|
## 本轮已完成
|
||||||
|
|
||||||
|
- 新增资源层:
|
||||||
|
- `scripts/resources/texture_region_catalog.gd`
|
||||||
|
- `scripts/resources/atlas_texture_cache.gd`
|
||||||
|
- 新增状态层:
|
||||||
|
- `scripts/state/player_state.gd`
|
||||||
|
- `scripts/state/farm_state.gd`
|
||||||
|
- `scripts/state/inventory_state.gd`
|
||||||
|
- 新增规则层:
|
||||||
|
- `scripts/domain/rules/crop_phase_rules.gd`
|
||||||
|
- `scripts/domain/rules/land_action_rules.gd`
|
||||||
|
- `scripts/domain/rules/cost_rules.gd`
|
||||||
|
- 新增数据映射层:
|
||||||
|
- `scripts/domain/mappers/farm_mapper.gd`
|
||||||
|
- `scripts/domain/mappers/inventory_mapper.gd`
|
||||||
|
- 新增接口服务层:
|
||||||
|
- `scripts/services/farm_api.gd`
|
||||||
|
- `scripts/services/inventory_api.gd`
|
||||||
|
- `scripts/services/building_api.gd`
|
||||||
|
- `scripts/services/shop_api.gd`
|
||||||
|
- `scripts/services/warehouse_api.gd`
|
||||||
|
- `scripts/services/dog_api.gd`
|
||||||
|
- `scripts/services/friend_api.gd`
|
||||||
|
- `game_scene.gd` 已改为通过服务层调用接口,UI 主脚本不再直接写业务接口路径。
|
||||||
|
- 土地动作判断、作物阶段判断、背包数据提取、土地返回数据归一化已迁出 `game_scene.gd`。
|
||||||
|
- 顶部 HUD、主菜单、世界菜单、弹窗层/Toast、农场缩放手势已从 `game_scene.gd` 迁出:
|
||||||
|
- `scripts/ui/hud/top_bar_view.gd`
|
||||||
|
- `scripts/ui/menus/main_menu_controller.gd`
|
||||||
|
- `scripts/ui/menus/world_menu_controller.gd`
|
||||||
|
- `scripts/ui/common/modal_layer_controller.gd`
|
||||||
|
- `scripts/ui/common/ui_motion.gd`
|
||||||
|
- `scripts/ui/farm/farm_viewport_controller.gd`
|
||||||
|
- 公共 UI 构建和图集资源访问已迁出:
|
||||||
|
- `scripts/ui/common/ui_builder.gd`
|
||||||
|
- `scripts/ui/common/texture_provider.gd`
|
||||||
|
- `UiBuilder` 已提供统一面板外框和内容底图入口,素材来自 `assets/replacement/panels/panel_shell.png`、`panel_content.png`,避免各面板继续手写旧 `c_panel/inner_page/common_db_10` 背景。
|
||||||
|
- Egret MovieClip 帧解析已迁到资源层:
|
||||||
|
- `scripts/resources/egret_movie_clip_cache.gd`
|
||||||
|
- 当前用于场景宠物 `dog1` swf 帧,避免 UI 面板直接重复解析 `{mc,res}` 图集。
|
||||||
|
- 土地、背包和种植提示已迁出:
|
||||||
|
- `scripts/farm/farm_controller.gd`
|
||||||
|
- `scripts/ui/farm/land_grid_view.gd`
|
||||||
|
- `scripts/ui/farm/land_action_menu.gd`
|
||||||
|
- `scripts/ui/farm/plant_tip_view.gd`
|
||||||
|
- `scripts/ui/farm/seed_bag_view.gd`
|
||||||
|
- 主场景深拆第二阶段已完成:
|
||||||
|
- `scripts/ui/game_scene_bootstrap.gd`:装配服务、状态、规则、Facade、FarmController 和面板模块。
|
||||||
|
- `scripts/ui/game_scene_runtime_assembler.gd`:装配顶部 HUD、主菜单、世界菜单、弹窗层、宠物展示、农场缩放、土地网格、土地动作菜单、种子背包、种植提示和运行时 hit 路由。
|
||||||
|
- `scripts/ui/game_scene_panel_router.gd`:统一承接商店、仓库、好友、房屋/土地扩建、狗窝、活动、支付、宠物等弹窗入口。
|
||||||
|
- `scripts/ui/scene_hit_router.gd`:顶部/左侧入口、农场建筑入口、直接命中兜底。
|
||||||
|
- `scripts/ui/farm/farm_interaction_coordinator.gd`:土地点击、长按、选中光圈、动作菜单、种子/肥料背包和作物提示。
|
||||||
|
- `scripts/state/player_inventory_facade.gd`:仓库刷新、奖励发放、消耗扣除、货币和狗饥饿时间写入。
|
||||||
|
- `scripts/ui/game_scene_context.gd`:收敛面板和 UI 模块共享依赖,替代 Bootstrap 中的大 callback 字典。
|
||||||
|
- `scripts/state/player_state.gd`:合并原 `PlayerDataAccessor`,作为玩家快照唯一权威来源。
|
||||||
|
- `scripts/ui/common/icon_texture_provider.gd`:缓存物品、宠物、作物和房屋图标加载。
|
||||||
|
- 面板按功能拆成独立模块:
|
||||||
|
- `scripts/ui/panels/shop_panel.gd`
|
||||||
|
- `scripts/ui/panels/warehouse_panel.gd`
|
||||||
|
- `scripts/ui/panels/friend_panel.gd`
|
||||||
|
- `scripts/ui/panels/building_panel.gd`
|
||||||
|
- `scripts/ui/panels/dog_panel.gd`
|
||||||
|
- `scripts/ui/panels/log_panel.gd`
|
||||||
|
- `scripts/ui/panels/notice_panel.gd`
|
||||||
|
- `scripts/ui/panels/level_gift_panel.gd`
|
||||||
|
- `scripts/ui/panels/online_gift_panel.gd`
|
||||||
|
- `scripts/ui/panels/pay_panel.gd`
|
||||||
|
- `scripts/ui/panels/welfare_panel.gd`
|
||||||
|
- `scripts/ui/panels/gold_exchange_panel.gd`
|
||||||
|
- `scripts/ui/panels/world_info_panel.gd`
|
||||||
|
- `scripts/ui/panels/sign_panel.gd`
|
||||||
|
- `scripts/ui/panels/box_panel.gd`
|
||||||
|
- `scripts/ui/panels/lottery_panel.gd`
|
||||||
|
- `scripts/ui/panels/pet_panel.gd`
|
||||||
|
- 修复了土地数据收集逻辑,改由 `FarmState.setup_from_player_data()` 统一归一化。
|
||||||
|
- 删除了临时 `DEBUG/print` 调试输出。
|
||||||
|
|
||||||
|
## 当前保留在 GameScene 的职责
|
||||||
|
|
||||||
|
`game_scene.gd` 当前 957 行,已低于 1200 行目标;保留职责收敛为场景生命周期、常驻节点引用、上下文桥接、土地快照渲染和少量兼容状态同步。已完成本阶段深拆:
|
||||||
|
|
||||||
|
- `GameSceneBootstrap` 已接管 `_setup_architecture_modules()` 和原 `_setup_panel_views()` 装配逻辑。
|
||||||
|
- `GameSceneRuntimeAssembler` 已接管 HUD/菜单/弹窗/宠物/土地交互运行时装配。
|
||||||
|
- `GameScenePanelRouter` 已接管 `_open_*_panel` 方法族、房屋/土地扩建入口包装和弹窗 active 状态。
|
||||||
|
- `SceneHitRouter` 已接管顶部/左侧/土地建筑点击区域注册和直接命中检测。
|
||||||
|
- `FarmInteractionCoordinator` 已接管长按、土地选择、背包打开、土地高亮等交互胶水。
|
||||||
|
- `PlayerInventoryFacade` 已接管奖励发放、消耗扣除、仓库刷新等跨模块状态写入。
|
||||||
|
- `GameSceneContext` 已接管面板共享依赖和 legacy callback 兼容层。
|
||||||
|
- `PlayerState` 已合并原 `PlayerDataAccessor`,主场景 token、房屋等级、狗饥饿时间等玩家字段访问统一从 `PlayerState` 读取/写入。
|
||||||
|
|
||||||
|
下一阶段建议转入 P1 功能拆分:好友完整互动、世界玩法、活动面板像素级对齐,并继续把旧面板从 legacy callbacks 迁到显式 `GameSceneContext` 方法。
|
||||||
|
|
||||||
|
## 已验证
|
||||||
|
|
||||||
|
- `game_scene.gd` 和新增 UI 控制器/面板模块通过 Godot `--check-only`。
|
||||||
|
- `game_scene_bootstrap.gd`、`game_scene_context.gd`、`game_scene_runtime_assembler.gd`、`game_scene_panel_router.gd`、`scene_hit_router.gd`、`farm_interaction_coordinator.gd`、`player_inventory_facade.gd`、`player_state.gd` 均通过 Godot `--check-only`。
|
||||||
|
- 新增资源、状态、规则、Mapper、Service 脚本全部通过 `--check-only`。
|
||||||
|
- 工程导入通过:`godot --headless --path godot/FarmGodot --import --quit`。
|
||||||
|
- P0 验证通过:`godot --headless --path godot/FarmGodot --script res://tools/verify_p0.gd`。
|
||||||
|
- Web 导出通过:`godot --headless --path godot/FarmGodot --export-release Web build/web/index.html`。
|
||||||
|
- 本地 H5 预览通过:`http://127.0.0.1:8792/index.html`。
|
||||||
|
- 自动登录成功,请求 `user/login` 返回 HTTP 200,业务 `status=0`。
|
||||||
|
- 背包请求 `store-house` 返回 HTTP 200,业务 `status=0`。
|
||||||
|
- 主场景、土地菜单打开/关闭、主菜单、世界菜单、弹窗、缩放和新增功能入口完成浏览器烟测:`npm run smoke:godot:web`。
|
||||||
|
- 宠物功能本轮验证通过:`pet_panel.gd`、`egret_movie_clip_cache.gd`、`game_scene.gd`、`game_scene_bootstrap.gd`、`game_scene_runtime_assembler.gd` 通过 `--check-only`;工程 `--import --quit` 和 Web 导出通过;浏览器截图确认主场景宠物、战宠面板、狗窝牌子入口均可用。
|
||||||
|
- 战宠面板经验条补充验证通过:按 `BattleProssBar2Skin.exml` 的九宫格背景和遮罩结构重做进度条,Web 截图确认经验条不再穿出面板;`pet_panel.gd` 通过 `--check-only`,Web 导出和 `npm run smoke:godot:web` 均通过。
|
||||||
|
- 家园宠物点击行为补充验证通过:对照旧版 `WidgetDog`,移除场景宠物显示节点、运行时装配层和直接命中路由里的 `open_pet_panel` 绑定;点击家园宠物不再打开战宠面板,世界菜单的战宠入口仍可打开;相关脚本通过 `--check-only`,Web 导出和 `npm run smoke:godot:web` 均通过。
|
||||||
|
- 统一面板背景本轮验证通过:`batch_prepare_icons.py` 可用 `--cutout` 抠出两张透明素材;所有受影响面板脚本通过 `--check-only`;工程 `--import --quit`、Web 导出、`npm run smoke:godot:web` 和补充 Playwright 截图均通过。
|
||||||
|
- 异步面板关闭防护本轮验证通过:`LevelGiftPanel` 复现路径已修复,公告、日志、好友、兑换记录、宝箱、签到、福利、宠物、世界信息等同类异步面板增加节点存活校验;相关脚本通过 `--check-only`,Web 导出、`npm run smoke:godot:web` 和等级礼包快速打开/关闭 Playwright 检查均通过。
|
||||||
|
- 房屋升级和用户信息面板本轮验证通过:`BuildingPanel` 的房屋升级按钮坐标回到旧 EXML 主内容组顶部位置,不再遮盖房屋;`PlayerInfoPanel` 顶部资料区补统一内容底图,标题改用 `roleinfo` 图集标题,用户 ID 清理为整数文本;`BoxPanel`、`LotteryPanel` 右侧装饰节点补显式类型,修复 Web 编译时类型推断失败;相关脚本通过 `--check-only`,Web 导出、Playwright 截图和 `npm run smoke:godot:web` 均通过。
|
||||||
|
|
||||||
|
## 验证产物
|
||||||
|
|
||||||
|
- `docs/ui-baseline/godot-architecture-refactor-main.png`
|
||||||
|
- `docs/ui-baseline/godot-architecture-refactor-land-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-architecture-refactor-land-menu-closed.png`
|
||||||
|
- `docs/ui-baseline/godot-architecture-refactor-main-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-architecture-refactor-meta.json`
|
||||||
|
- `docs/ui-baseline/smoke/*.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-main.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-doghouse-click.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-scene-click-no-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-world-pet-entry-still-opens.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-shop.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-warehouse.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-friend.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-pet.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-panel-expbar-fixed.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-dog.png`
|
||||||
|
- `docs/ui-baseline/godot-house-upgrade-button-position-fixed.png`
|
||||||
|
- `docs/ui-baseline/godot-player-info-bg-fixed.png`
|
||||||
|
- `docs/ui-baseline/godot-player-info-title-id-fixed.png`
|
||||||
84
docs/godot-development-standards.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Godot 开发规范
|
||||||
|
|
||||||
|
## 1. 资料优先级
|
||||||
|
|
||||||
|
1. Godot 4.6 官方文档和类参考。
|
||||||
|
2. Godot 官方 GitHub Release、官方 godot-builds Release。
|
||||||
|
3. 原项目本地资源、EXML、PHP/Yii 接口和数据库。
|
||||||
|
4. 官方没有覆盖时,再查 GitHub/Godot Asset Library/社区资料,并在文档中记录来源。
|
||||||
|
|
||||||
|
## 2. 引擎和语言
|
||||||
|
|
||||||
|
- 固定使用 Godot 4.6.2 stable。
|
||||||
|
- 使用非 .NET 版本。
|
||||||
|
- 只写 GDScript,不引入 C#。
|
||||||
|
- Web 渲染路径使用 Compatibility。
|
||||||
|
- Web 导出默认单线程。
|
||||||
|
- Web 导出预设中 `vram_texture_compression/for_mobile` 默认保持 `false`,除非先启用并验证 ETC2/ASTC 导入设置。
|
||||||
|
|
||||||
|
## 3. 命名
|
||||||
|
|
||||||
|
遵循 Godot 官方 GDScript 风格指南:
|
||||||
|
|
||||||
|
- 文件名:`snake_case.gd`、`snake_case.tscn`。
|
||||||
|
- 类名:`PascalCase`。
|
||||||
|
- 函数和变量:`snake_case`。
|
||||||
|
- 常量:`ALL_CAPS`。
|
||||||
|
- 信号:过去式或事件语义,例如 `login_completed`、`inventory_changed`。
|
||||||
|
|
||||||
|
## 4. 代码规则
|
||||||
|
|
||||||
|
- 优先静态类型标注:`var name: String`、`func load_user() -> void`。
|
||||||
|
- 使用 `and`、`or`、`not`,不用 `&&`、`||`、`!`。
|
||||||
|
- 每个脚本只承担一个清晰职责。
|
||||||
|
- UI 节点脚本不直接拼后端 URL,不直接解析复杂业务规则。
|
||||||
|
- 网络请求统一从 `ApiClient` 发出。
|
||||||
|
- 配置项统一放 `project.godot` 或后续独立配置资源。
|
||||||
|
- 不在脚本里硬编码大量资源路径;临时路径必须在迁移文档里登记。
|
||||||
|
|
||||||
|
## 5. 场景规则
|
||||||
|
|
||||||
|
- UI 以完全一致为验收标准,不接受只“差不多”的重构。
|
||||||
|
- 每个页面必须先保存白鹭基准截图,再保存 Godot 同分辨率截图,并记录差异。
|
||||||
|
- 白鹭页面存在多个 canvas 时,实际游戏画布以最后一个 canvas 为准;旧登录页当前实测实际 canvas 为 `480 x 960`。
|
||||||
|
- 白鹭源 EXML 和编译后 `default.thm_*.js` 不一致时,以线上运行时编译皮肤和截图为准。
|
||||||
|
- 每个可复用 UI 面板都是独立 `.tscn`。
|
||||||
|
- 页面入口放在 `scenes/ui`。
|
||||||
|
- 运行入口只做场景装配,不写业务规则。
|
||||||
|
- 能用 `Control` 完成的 UI 不用 `Node2D`。
|
||||||
|
- Egret `scale9Grid` 必须迁移为 Godot `NinePatchRect`,不能直接用普通 `TextureRect` 拉伸。
|
||||||
|
- 使用 640 x 960 作为当前登录页基准,后续如确认线上实际为 640 x 1136,再统一调整。
|
||||||
|
|
||||||
|
## 6. 资源规则
|
||||||
|
|
||||||
|
- Egret 原资源先保存在 `assets/egret` 作为迁移输入。
|
||||||
|
- Godot 可运行资源逐步转入 Godot 原生资源格式。
|
||||||
|
- 图集转换要保留原 Egret 资源名,避免 UI 绑定丢失。
|
||||||
|
- 字体授权未确认前,不把字体作为最终发布依赖。
|
||||||
|
|
||||||
|
## 7. Web 规则
|
||||||
|
|
||||||
|
- Web 构建必须使用 `index.html` 作为入口文件名。
|
||||||
|
- Web 导出的 HTML shell 必须保持旧 H5 的可见容器规则;当前登录页是 `max-width: 480px; height: 100vh; background: #000`。
|
||||||
|
- 所有 HTTP 接口必须支持 HTTPS 和 CORS。
|
||||||
|
- 不使用原生 TCP/UDP。
|
||||||
|
- 需要浏览器能力时优先查 `JavaScriptBridge` 官方文档。
|
||||||
|
- 广告、统计、平台 SDK 通过 JavaScriptBridge 做薄封装,不污染核心玩法代码。
|
||||||
|
|
||||||
|
## 8. 验证规则
|
||||||
|
|
||||||
|
每次修改至少做对应验证:
|
||||||
|
|
||||||
|
- 改 GDScript:执行 `--check-only --script`。
|
||||||
|
- 改资源或场景:执行 `--import --quit`。
|
||||||
|
- 改 Web/平台相关:执行 Web 导出。
|
||||||
|
- 改 Web 导出预设:同时验证 `index.html`、`index.wasm`、`index.pck` 能通过本地 HTTP 服务访问。
|
||||||
|
- 改 UI:用 Godot 或浏览器截图和 Egret 基准截图对比。
|
||||||
|
- UI 对比命令:`NODE_PATH=/tmp/farm3-playwright/node_modules node tools/compare_ui_baseline.mjs <egret.png> <godot.png> <diff.png>`。
|
||||||
|
- 改网络:保存请求路径、请求参数、响应码、响应体摘要。
|
||||||
|
|
||||||
|
## 9. 第三方工具规则
|
||||||
|
|
||||||
|
- 官方 API 能解决时不引第三方。
|
||||||
|
- 官方没有 GDScript 游戏单元测试框架,后续需要自动化测试时优先评估 GUT 9.6.0。
|
||||||
|
- 引入第三方前必须记录版本、来源、许可证、Godot 兼容版本和替代方案。
|
||||||
163
docs/godot-map-pan-review.md
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# Godot 农场地图拖动功能检验
|
||||||
|
|
||||||
|
日期:2026-05-12
|
||||||
|
|
||||||
|
## 范围
|
||||||
|
|
||||||
|
本轮检验对象是 Godot 主农场的地图拖动预览能力:
|
||||||
|
|
||||||
|
- 地图可拖动范围最大为 `2000x2000`。
|
||||||
|
- 默认进入农场时,土地内容位于地图中心。
|
||||||
|
- 背景图不足时先使用现有背景拉伸铺底,不额外补图。
|
||||||
|
- 拖动地图不能误触土地菜单、扩建弹窗或长按提示。
|
||||||
|
- 缩放、建筑点击、扩建入口和固定 HUD 不能被拖动能力破坏。
|
||||||
|
|
||||||
|
## 模块拆分结论
|
||||||
|
|
||||||
|
该功能已经按现有架构拆出,主逻辑没有堆回 `game_scene.gd`。
|
||||||
|
|
||||||
|
| 模块 | 职责 | 当前判断 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `scripts/ui/farm/farm_viewport_controller.gd` | 农场内容根节点、`2000x2000` 地图、默认居中、单指/鼠标拖动、双指/Ctrl 滚轮缩放、边界 clamp | 拖动功能核心已独立 |
|
||||||
|
| `scripts/ui/farm/farm_interaction_coordinator.gd` | 土地点击、长按、菜单、背包;只通过 `on_scene_pan_started/finished` 抑制拖动误触 | 和地图拖动保持低耦合 |
|
||||||
|
| `scripts/ui/game_scene_runtime_assembler.gd` | 创建缩放控制器和土地交互模块,并连接拖动开始/结束回调 | 只做装配 |
|
||||||
|
| `scripts/ui/game_scene.gd` | 当前只保留扩建图标透明命中区的坐标同步 | 仍有一个可继续迁出的 UI 坐标桥接点 |
|
||||||
|
|
||||||
|
控制器已命名为 `FarmViewportController`,避免只体现缩放而遗漏拖动视口职责。
|
||||||
|
|
||||||
|
## 当前实现
|
||||||
|
|
||||||
|
### 地图边界
|
||||||
|
|
||||||
|
地图范围使用常量:
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
const MAP_PREVIEW_SIZE := Vector2(2000.0, 2000.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
拖动偏移由 `_clamped_scene_offset()` 限制:
|
||||||
|
|
||||||
|
```gdscript
|
||||||
|
var scaled_map_size := MAP_PREVIEW_SIZE * _zoom
|
||||||
|
var min_offset := _panel_size - scaled_map_size
|
||||||
|
clampf(value.x, minf(min_offset.x, 0.0), 0.0)
|
||||||
|
clampf(value.y, minf(min_offset.y, 0.0), 0.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
以当前屏幕 `640x960` 为例:
|
||||||
|
|
||||||
|
| 缩放 | 缩放后地图 | X 偏移范围 | Y 偏移范围 | 结论 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `0.6667` | 约 `1333x1333` | `[-693, 0]` | `[-373, 0]` | 缩小时仍有可预览区域,不露出黑边 |
|
||||||
|
| `1.0` | `2000x2000` | `[-1360, 0]` | `[-1040, 0]` | 满足 2000 地图拖动 |
|
||||||
|
| `1.3` | `2600x2600` | `[-1960, 0]` | `[-1640, 0]` | 放大后边界随缩放扩大 |
|
||||||
|
|
||||||
|
边界设计合理:偏移范围以“缩放后的地图尺寸 - 屏幕尺寸”为准,缩放和拖动共用同一套 clamp,不会在缩放后越界。
|
||||||
|
|
||||||
|
### 默认居中
|
||||||
|
|
||||||
|
默认进入时执行:
|
||||||
|
|
||||||
|
1. 把 `Ground`、`House`、`DogHouse`、`FenceBack`、`GameView`、`FenceFront`、`PetLayer` 移到 `FarmSceneRoot`。
|
||||||
|
2. 从 `GameView` 下严格匹配 `Land` + 数字的节点计算土地包围盒。
|
||||||
|
3. 将土地包围盒中心平移到 `2000x2000` 地图中心。
|
||||||
|
4. 将镜头偏移设为地图中心对准屏幕中心。
|
||||||
|
|
||||||
|
当前顺序是安全的:计算土地包围盒发生在 `LandHitLayer`、`LandLight` 等运行时节点创建前,因此不会把命中层误算进土地范围。
|
||||||
|
|
||||||
|
### 拖动与点击冲突
|
||||||
|
|
||||||
|
当前使用 `PAN_DRAG_THRESHOLD = 8` 像素区分点击和拖动。
|
||||||
|
|
||||||
|
- 移动距离小于阈值:仍按点击处理。
|
||||||
|
- 移动距离达到阈值:进入地图拖动。
|
||||||
|
- 拖动开始时调用 `FarmInteractionCoordinator.on_scene_pan_started()`。
|
||||||
|
- 拖动结束后调用 `on_scene_pan_finished()`,延迟清理抑制标记。
|
||||||
|
|
||||||
|
土地点击被抑制的路径:
|
||||||
|
|
||||||
|
```text
|
||||||
|
FarmViewportController pan started
|
||||||
|
-> FarmInteractionCoordinator.on_scene_pan_started()
|
||||||
|
-> stop long press timer
|
||||||
|
-> suppress next land press
|
||||||
|
-> hide selection UI
|
||||||
|
```
|
||||||
|
|
||||||
|
该设计能避免“拖动土地后弹出土地菜单或扩建弹窗”的误触。
|
||||||
|
|
||||||
|
### 固定 UI 与农场内容分离
|
||||||
|
|
||||||
|
只迁移农场内容到 `FarmSceneRoot`,顶部 HUD、左侧按钮、底部世界/家园按钮仍留在主场景固定层。因此拖动地图不会带动 HUD。
|
||||||
|
|
||||||
|
### 背景策略
|
||||||
|
|
||||||
|
当前使用 `FarmZoomBackdrop` 将原背景拉伸到 `2000x2000`,并隐藏原 `Ground`。这符合“背景图不够先不用管”的要求。后续补齐大地图背景时,只需要替换 `FarmZoomBackdrop` 的纹理来源,不需要重写拖动逻辑。
|
||||||
|
|
||||||
|
## 功能检验结果
|
||||||
|
|
||||||
|
| 检验项 | 结果 |
|
||||||
|
| --- | --- |
|
||||||
|
| 默认土地在视野中心 | 通过 |
|
||||||
|
| 鼠标拖动地图可移动视野 | 通过 |
|
||||||
|
| 拖动后不弹扩建面板 | 通过 |
|
||||||
|
| 拖动后不弹土地菜单 | 通过 |
|
||||||
|
| HUD 不随地图拖动 | 通过 |
|
||||||
|
| Web 导出后可运行 | 通过 |
|
||||||
|
| smoke 主流程 | 通过 |
|
||||||
|
|
||||||
|
截图记录:
|
||||||
|
|
||||||
|
- `docs/ui-baseline/godot-map-pan-final-default.png`
|
||||||
|
- `docs/ui-baseline/godot-map-pan-final-after-drag.png`
|
||||||
|
- `docs/ui-baseline/godot-map-pan-rename-default.png`
|
||||||
|
- `docs/ui-baseline/godot-map-pan-rename-after-drag.png`
|
||||||
|
|
||||||
|
## 已执行验证
|
||||||
|
|
||||||
|
```sh
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/farm/farm_viewport_controller.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/farm/farm_interaction_coordinator.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene_runtime_assembler.gd
|
||||||
|
godot --headless --path godot/FarmGodot --check-only --script res://scripts/ui/game_scene.gd
|
||||||
|
godot --headless --path godot/FarmGodot --script res://tools/verify_p0.gd
|
||||||
|
godot --headless --path godot/FarmGodot --import --quit
|
||||||
|
godot --headless --path godot/FarmGodot --export-release Web build/web/index.html
|
||||||
|
npm run smoke:godot:web
|
||||||
|
```
|
||||||
|
|
||||||
|
浏览器验证目标:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://127.0.0.1:8792/index.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## 边界风险
|
||||||
|
|
||||||
|
| 风险 | 当前影响 | 建议 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `2000x2000` 固定在控制器常量里 | 后续如果不同地图皮肤尺寸不同,需要改代码 | 改成从 `game_scene_runtime_assembler.gd` 的 constants 注入 |
|
||||||
|
| 建筑直接命中仍是按点击入口处理 | 拖动从建筑区域开始时,后续可能需要更严格的 tap/release 判定 | 若出现误触,把农场建筑 direct hit 改为 release 后、且未超过拖动阈值才触发 |
|
||||||
|
| 缩放没有围绕双指中心或鼠标位置缩放 | 当前可用,但放大时视角体验不够细 | 后续按手势中心调整 `_scene_offset` |
|
||||||
|
| 没有惯性滑动和边界回弹 | 当前符合第一版预览需求 | 后续如果要接近原生手感,可加轻量 Tween,但要避免 `_process` 常驻计算 |
|
||||||
|
|
||||||
|
## 优化优先级
|
||||||
|
|
||||||
|
P0 暂无阻断问题。
|
||||||
|
|
||||||
|
P1:
|
||||||
|
|
||||||
|
- 将地图尺寸从常量改为装配层配置,便于不同背景/地图皮肤切换。
|
||||||
|
- 把扩建图标命中区同步从 `game_scene.gd` 迁到 `SceneHitRouter` 或农场交互模块,进一步减薄主场景。
|
||||||
|
- 建筑 direct hit 改为 tap 语义,避免未来拖动从房屋/狗窝起手时误触面板。
|
||||||
|
|
||||||
|
已处理:
|
||||||
|
|
||||||
|
- `FarmSceneZoomController` 已重命名为 `FarmViewportController`,文件同步改为 `farm_viewport_controller.gd`。
|
||||||
|
- 土地包围盒匹配已从 `Land*` 改为 `Land` + 数字,避免 `LandPreview*` 这类装饰节点被纳入默认居中计算。
|
||||||
|
|
||||||
|
P2:
|
||||||
|
|
||||||
|
- 增加缩放中心保持逻辑,让双指缩放时手指中点下的地图内容保持稳定。
|
||||||
|
- 增加可选惯性拖动和边界阻尼。
|
||||||
|
- 背景素材补齐后,把 `FarmZoomBackdrop` 改为真实大图或分块贴图,避免拉伸纹理。
|
||||||
273
docs/godot-migration-progress.md
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
# Godot 重构进度
|
||||||
|
|
||||||
|
## 已完成
|
||||||
|
|
||||||
|
- 删除旧 Unity 目录:`unity`。
|
||||||
|
- 安装 Godot 4.6.2 stable 到:`/Users/hy/Applications/Godot.app`。
|
||||||
|
- 添加命令行入口:`/Users/hy/.local/bin/godot`。
|
||||||
|
- 安装 Godot 4.6.2 官方导出模板到用户模板目录。
|
||||||
|
- 新建 Godot 工程:`godot/FarmGodot`。
|
||||||
|
- 添加并验证 Web 导出预设:`export_presets.cfg`。
|
||||||
|
- 拷贝登录页第一批 Egret 素材:
|
||||||
|
- `login_bg.jpg`
|
||||||
|
- `login_bg.png`
|
||||||
|
- `login_db.png`
|
||||||
|
- `login_phone.png`
|
||||||
|
- `login_pwd.png`
|
||||||
|
- `login_jizhuPassword.png`
|
||||||
|
- `login_regist.png`
|
||||||
|
- `login_findpwd.png`
|
||||||
|
- `login_goubg.png`
|
||||||
|
- `login_gou.png`
|
||||||
|
- `select_db.png`
|
||||||
|
- `select_db1.png`
|
||||||
|
- `common.png` 中 `c_btn1_png`
|
||||||
|
- `huakang.ttf`
|
||||||
|
- `huakanghaibao.ttf`
|
||||||
|
- 拷贝资源规格:
|
||||||
|
- `default.res.json`
|
||||||
|
- `default.thm.json`
|
||||||
|
- `LoginSceneSkin.exml`
|
||||||
|
- 已按新版解密 HTML 完整同步原版素材:
|
||||||
|
- 来源:`muchang/home/web/game/resource/`
|
||||||
|
- 目标:`godot/FarmGodot/assets/egret/`
|
||||||
|
- 保留原版相对路径:`assets/`、`config/`、`fonts/`、`skins/`、根目录资源清单。
|
||||||
|
- 原版 `resource` 下 882 个文件已同步;`rsync -ani --inplace --omit-dir-times` 复查无待同步文件。
|
||||||
|
- 添加第一版场景:
|
||||||
|
- `scenes/bootstrap.tscn`
|
||||||
|
- `scenes/ui/login_scene.tscn`
|
||||||
|
- 添加第一版脚本:
|
||||||
|
- `scripts/bootstrap.gd`
|
||||||
|
- `scripts/services/api_client.gd`
|
||||||
|
- `scripts/core/egret_resource_catalog.gd`
|
||||||
|
- `scripts/core/number_formatter.gd`
|
||||||
|
- `scripts/ui/login_scene.gd`
|
||||||
|
- 已完成验证:
|
||||||
|
- Godot 工程导入通过。
|
||||||
|
- 所有 GDScript `--check-only` 通过。
|
||||||
|
- 主场景 headless 启动通过。
|
||||||
|
- Web release 导出通过。
|
||||||
|
- 本地 HTTP 服务访问 `index.html`、`index.wasm`、`index.pck` 均返回 200。
|
||||||
|
- Godot `--write-movie` 录帧成功,登录页可渲染,截图路径:`/tmp/farmgodot_frame00000000.png`。
|
||||||
|
- 根据“UI 完全一致”要求,当前登录页只算预览版,不计入 UI 完成。
|
||||||
|
- 已处理第一批明显不一致:
|
||||||
|
- 输入框去除 Godot 默认黑色样式,改为白鹭输入框底图和 `NinePatchRect` 承载。
|
||||||
|
- 登录按钮改为 `common.png` 中 `c_btn1_png` 图集区域作为底图。
|
||||||
|
- 登录页坐标改以运行时 `default.thm_4ef35e2b.js` 编译皮肤为准,源 EXML 只作为辅助。
|
||||||
|
- Web 导出改用自定义 shell;当前 Godot 预览按 `640 x 960` 全画布验证,避免桌面预览右侧黑边。
|
||||||
|
- 已生成白鹭/Godot 对照截图和差异图:
|
||||||
|
- `docs/ui-baseline/egret-login-page.png`
|
||||||
|
- `docs/ui-baseline/godot-login-page.png`
|
||||||
|
- `docs/ui-baseline/login-page-diff.png`
|
||||||
|
- `docs/ui-baseline/egret-login-canvas.png`
|
||||||
|
- `docs/ui-baseline/godot-login-canvas.png`
|
||||||
|
- `docs/ui-baseline/login-canvas-diff.png`
|
||||||
|
- 当前截图对比结果:
|
||||||
|
- 页面截图:`11206 / 614400` 像素不同,差异率 `0.018239`。
|
||||||
|
- 实际 canvas:`11206 / 460800` 像素不同,差异率 `0.024319`。
|
||||||
|
- 差异主要集中在中文字体渲染、按钮文字和少量贴图边缘采样;因此登录页仍不能标记为 UI 完成。
|
||||||
|
|
||||||
|
## 当前能力
|
||||||
|
|
||||||
|
- Godot 启动后进入登录页预览。
|
||||||
|
- 能解析 Egret `default.res.json` 并统计资源数量。
|
||||||
|
- 登录表单能做账号和密码非空校验。
|
||||||
|
- 已配置本地后端地址:`http://127.0.0.1:18082/index.php?r=`。
|
||||||
|
- 已配置登录路径:`user/login`。
|
||||||
|
- 登录请求已按旧 Egret 协议发送:`application/x-www-form-urlencoded`,body 为 `msg=<base64(JSON)>`。
|
||||||
|
- 登录响应中的 `data` 已按旧客户端逻辑做 Base64 + JSON 解码。
|
||||||
|
- 使用账号 `13800000001 / 123456` 已验证 Godot Web 版可真实登录并进入主农场。
|
||||||
|
- 第一版主农场已接入:
|
||||||
|
- 顶部玩家信息栏、头像、经验条、金币、钻石、战力。
|
||||||
|
- 农场背景、房屋、围栏、狗屋。
|
||||||
|
- 12 块土地显示,已开垦/未开垦状态和扩建入口。
|
||||||
|
- 左侧活动入口、世界入口、右下家园入口。
|
||||||
|
- 按后端 `landList` 渲染作物阶段,当前可显示成熟作物和种子期作物。
|
||||||
|
- 点击空地后显示旧版黄色土地高亮和圆形“播种”菜单。
|
||||||
|
- 点击“播种”后显示旧版右侧种子包,种子列表从 `store-house` 读取。
|
||||||
|
- 点击种子后调用 `farm/sow-seeds`,成功后刷新当前地块作物。
|
||||||
|
- 种子播下后会按 `crop_gather_time` 和作物阶段时间自动刷新作物贴图,不需要刷新页面。
|
||||||
|
- 点击成长中土地后显示旧版圆形土地菜单:铲除、施肥、除虫、除草。
|
||||||
|
- 点击成熟土地后显示旧版“收割”菜单,并调用 `farm/gather-crop`。
|
||||||
|
- 点击已收割或枯萎土地后显示旧版“铲除”菜单,并调用 `farm/clear-land`。
|
||||||
|
- 点击“施肥”后显示旧版右侧化肥包,化肥列表从 `store-house` 读取,并调用 `farm/fertilize`。
|
||||||
|
- 点击“除虫”“除草”后调用 `farm/disease`,分别传原版疾病类型 `1` 和 `2`。
|
||||||
|
- 土地异常状态已渲染原版 `plant_state1/2/3` 图标。
|
||||||
|
- 土地倒计时已按原版长按行为显示,不占用普通点击操作菜单。
|
||||||
|
- 家园菜单已补第一版二级入口和弹窗:
|
||||||
|
- 点击家园后按旧版弧形弹出商店、仓库、好友入口。
|
||||||
|
- 商店弹窗已按 `ShopSkin.exml`、`ShopItemSkin.exml` 迁移第一版,配置来自 `store_list`,买入调用 `store/buy`。
|
||||||
|
- 仓库弹窗已按 `WareHouseSkin.exml`、`WareHouseItemSkin.exml` 迁移第一版,库存来自 `store-house`,出售弹窗按 `SellSkin.exml` 迁移,出售调用 `store-house/sell`。
|
||||||
|
- 好友弹窗已按 `FriendSkin.exml`、`FriendRankItemSkin.exml` 迁移第一版,全国排行调用 `comm/get-level-ranking`,好友排行调用 `friend/friend-list`。
|
||||||
|
- 已生成主农场白鹭/Godot 对照截图:
|
||||||
|
- `docs/ui-baseline/egret-main-page.png`
|
||||||
|
- `docs/ui-baseline/egret-main-canvas.png`
|
||||||
|
- `docs/ui-baseline/egret-main-meta.json`
|
||||||
|
- `docs/ui-baseline/godot-main-page.png`
|
||||||
|
- `docs/ui-baseline/godot-main-canvas.png`
|
||||||
|
- `docs/ui-baseline/godot-main-meta.json`
|
||||||
|
- 已生成种菜流程截图:
|
||||||
|
- `docs/ui-baseline/egret-plant-menu.png`
|
||||||
|
- `docs/ui-baseline/egret-seed-bag.png`
|
||||||
|
- `docs/ui-baseline/egret-after-sow.png`
|
||||||
|
- `docs/ui-baseline/godot-plant-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-seed-bag.png`
|
||||||
|
- `docs/ui-baseline/godot-after-sow.png`
|
||||||
|
- `docs/ui-baseline/godot-plant-flow-meta.json`
|
||||||
|
- `docs/ui-baseline/godot-auto-mature.png`
|
||||||
|
- `docs/ui-baseline/godot-auto-mature-menu.png`
|
||||||
|
- 已生成土地操作流程截图:
|
||||||
|
- `docs/ui-baseline/godot-actions-main.png`
|
||||||
|
- `docs/ui-baseline/godot-countdown-longpress.png`
|
||||||
|
- `docs/ui-baseline/godot-actions-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-after-bug-clean.png`
|
||||||
|
- `docs/ui-baseline/godot-after-grass-clean.png`
|
||||||
|
- `docs/ui-baseline/godot-fertilizer-bag.png`
|
||||||
|
- `docs/ui-baseline/godot-after-fertilize.png`
|
||||||
|
- `docs/ui-baseline/godot-ripe-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-after-harvest.png`
|
||||||
|
- `docs/ui-baseline/godot-after-clear.png`
|
||||||
|
- `docs/ui-baseline/godot-land-actions-flow-meta.json`
|
||||||
|
- 已生成家园菜单弹窗验证截图:
|
||||||
|
- `docs/ui-baseline/godot-shop-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-warehouse-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-friend-panel.png`
|
||||||
|
- 已生成狗窝、房屋升级、土地扩建验证截图:
|
||||||
|
- `docs/ui-baseline/godot-dog-building-extend-main.png`
|
||||||
|
- `docs/ui-baseline/godot-building-upgrade-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-dog-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-dog-food-popup.png`
|
||||||
|
- `docs/ui-baseline/godot-land-extend-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-dog-building-extend-meta.json`
|
||||||
|
- 已生成宠物功能验证截图:
|
||||||
|
- `docs/ui-baseline/godot-pet-main.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-panel.png`
|
||||||
|
- `docs/ui-baseline/godot-pet-doghouse-click.png`
|
||||||
|
- 已生成统一面板背景验证截图:
|
||||||
|
- `docs/ui-baseline/godot-panel-background-home-menu.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-shop.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-warehouse.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-friend.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-pet.png`
|
||||||
|
- `docs/ui-baseline/godot-panel-background-dog.png`
|
||||||
|
|
||||||
|
## 未完成
|
||||||
|
|
||||||
|
- 登录成功后的玩家模型已开始拆到 `PlayerState/FarmState/InventoryState`,但 UI 层仍有部分直接读写字典的旧逻辑。
|
||||||
|
- 主场景入口点击、扩建、浇水、土地升级已接第一版;浇水走 `farm/disease type=0`,当前账号没有干旱土地时只做规则/API 链路验证。
|
||||||
|
- 好友搜索、好友申请、查看好友家园、互动动作只保留入口提示,未接完整二级弹窗和接口。
|
||||||
|
- Egret 图集自动转 `AtlasTexture` 未实现。
|
||||||
|
- EXML 辅助转换工具未实现。
|
||||||
|
- 字体、FNT、音频原始文件已迁入 `assets/egret`,但部分运行时解析和播放逻辑仍未接完。
|
||||||
|
- 登录页已完成第一轮白鹭基准截图对比,但像素差异未归零,不能标记为 UI 完成。
|
||||||
|
- 主农场已完成第一版浏览器截图对照,但未做像素差异归零;左侧入口、顶部字体/FNT、围栏招牌语言仍需继续精调。
|
||||||
|
- 字体、字号、按钮文字效果、图集采样和旧 H5 的 640x1136 缩放差异仍需继续精调。
|
||||||
|
|
||||||
|
## 已解决问题记录
|
||||||
|
|
||||||
|
- Web 导出第一次失败,Godot CLI 只显示空的 configuration errors。
|
||||||
|
- 查 Godot 4.6.2 官方源码后确认原因:`vram_texture_compression/for_mobile=true` 时要求项目启用 ETC2/ASTC 导入设置;当前项目没有启用,`can_export` 返回失败但没有错误文本。
|
||||||
|
- 已按官方 Web exporter 默认值改为 `vram_texture_compression/for_mobile=false`,重新导出通过。
|
||||||
|
- 后端 URL 已从旧客户端 `GameConfig.SERVER_PATH` 定位:
|
||||||
|
- `muchang/farmer/js/main.min_77d7299f.js` 使用 `http://<host>/home/web/index.php?r=`。
|
||||||
|
- 本地 Docker `home` 服务映射到 `127.0.0.1:18082`,所以 Godot 使用 `http://127.0.0.1:18082/index.php?r=`。
|
||||||
|
- 已用 curl 验证 `user/login` 可达,并返回后端 JSON 业务状态。
|
||||||
|
- 种菜链路已按旧客户端确认:
|
||||||
|
- 旧客户端 `BagPanelSkin.exml` 的右侧种子包位置和 `BagIconSkin.exml` 的种子图标样式已迁移。
|
||||||
|
- 旧客户端 `GameView.clickLand -> CoolMenuItem.plant -> OPEN_BAG -> BagIconRender -> farm/sow-seeds` 链路已在 Godot 复刻第一版。
|
||||||
|
- 2026-05-11 使用 `13800000001 / 123456` 在 Godot Web 验证:`user/login`、`store-house`、`farm/sow-seeds` 均返回 HTTP 200。
|
||||||
|
- 为验证播种,临时通过 `store/buy` 买入 1 个金桔种子,播种成功后已调用 `farm/clear-land` 把 1 号地恢复为空地。
|
||||||
|
- 土地操作链路已按旧客户端确认:
|
||||||
|
- 旧客户端 `GameView.getMyFarmMenu` 的土地菜单规则已迁移:空地播种、成长中铲除/施肥/除虫/除草、成熟收割、已收割或枯萎铲除。
|
||||||
|
- 旧客户端 `PlantCdTipSkin.exml` 的长按倒计时提示已迁移,普通点击不再弹倒计时,避免遮挡操作菜单。
|
||||||
|
- 旧客户端 `BagPanelSkin.exml` 的右侧背包位置继续复用,当前支持种子包和化肥包。
|
||||||
|
- `game_config.json` 已作为非资源文件纳入 Web 导出,用于读取种子、作物、化肥、图标和阶段时间配置。
|
||||||
|
- 2026-05-11 使用 `13800000001 / 123456` 在 Godot Web 验证:`farm/disease`、`farm/fertilize`、`farm/gather-crop`、`farm/clear-land` 均返回 HTTP 200 且业务状态成功。
|
||||||
|
- 验证时临时改动的测试账号土地、道具和经验数据已恢复到测试前状态。
|
||||||
|
- 作物自动成熟刷新已确认:
|
||||||
|
- 2026-05-11 参考 Godot `Timer.timeout` 机制,在农场场景增加 1 秒一次的地块视觉状态签名检查,只有阶段、收获状态或异常图标发生变化时才重绘地块。
|
||||||
|
- 使用 `13800000001 / 123456` 在 Godot Web 版播种金桔种子,后端返回 `crop_gather_time = crop_start_time + 22`;页面不刷新等待成熟后,作物贴图自动切换为成熟金桔。
|
||||||
|
- 点击自动成熟后的地块已验证弹出“Harvest”收获菜单;验证结束后已调用 `farm/clear-land` 将 0 号地恢复为空地。
|
||||||
|
- 家园菜单弹窗链路已按旧客户端确认:
|
||||||
|
- 旧客户端 `MainMenu` 的弧形菜单动画已迁移为 Godot Tween,仓库素材继续以仓库内 replacement 素材为准。
|
||||||
|
- 旧客户端 `ShopMediator.buy` 对应 `store/buy` 已接入,2026-05-11 使用测试账号在 Godot Web 点击商店购买金桔种子,HTTP 200 且业务状态成功。
|
||||||
|
- 旧客户端 `WareHouseMediator.sellWareHouseItem` 对应 `store-house/sell` 已接入,仓库物品点击可弹出售面板。
|
||||||
|
- 旧客户端 `FriendMediator.getRankList/getFriendList` 对应 `comm/get-level-ranking`、`friend/friend-list` 已接入;2026-05-11 使用同一 token 直接验证全国排行返回 `total_count=70`、好友排行返回 `total_count=0`,Godot Web 全国排行显示 1/10。
|
||||||
|
- 狗窝、房屋升级和土地扩建第一版已接入:
|
||||||
|
- 狗屋点击打开 `DogSkin` 对应面板;按旧版 `DogSelectFoodSkin` 显示三档狗粮,接口逻辑对应 `user/feed-dog`。
|
||||||
|
- 房屋点击打开 `BuildingSkin` 对应“房屋升级”面板,读取 `farm_level` 配置表,材料和等级不足时按旧版禁用升级按钮;接口逻辑对应 `farm/upgrade`。
|
||||||
|
- 未开垦土地和扩建木牌点击打开 `LandOpenSkin` 对应扩建面板,读取 `land_extend` 配置表,等级/金币不足时禁用扩建按钮;接口逻辑对应 `farm/extend-land`。
|
||||||
|
- 2026-05-11 在 Godot Web 版使用 `13800000001 / 123456` 验证三个入口均能打开,当前账号下一块土地要求 `LV.13 / 1888`,因等级不足未执行不可逆扩建。
|
||||||
|
- 宠物主场景和战宠面板已按旧资源修正:
|
||||||
|
- 场景宠物展示从静态 `petIcon` 改为读取 `assets/swf/dog1.{json,png}` 的 Egret MovieClip 帧,饥饿状态使用趴地动画并加轻微呼吸/语言淡入淡出。
|
||||||
|
- 宠物位置移到狗窝右侧草地区域,点击热区缩小到狗身,避免遮挡土地和抢狗窝牌子点击。
|
||||||
|
- 战宠面板保留 `BattleBaseCompomentSkin` 对应的头像框、属性区、经验条、介绍区、底部宠物卡片资源,主外框和内容底图改用统一透明背景素材。
|
||||||
|
- 战宠基础属性页的经验条按 `BattleProssBar2Skin.exml` 改为九宫格背景 + 裁剪遮罩填充,修复 Godot 纹理按图集原宽度向右溢出的问题。
|
||||||
|
- 对照旧版 `WidgetDog` 逻辑,家园场景宠物只作为动画展示,不再点击打开战宠面板;战宠面板入口保留在世界菜单/竞技相关入口。
|
||||||
|
- 2026-05-12 在 Godot Web 版使用 `13800000001 / 123456` 验证:主场景宠物可见且不压土地;点击家园宠物不打开战宠面板;世界菜单战宠入口可打开面板且经验条不越界;点击狗窝牌子仍打开“亲家护院”狗窝面板。
|
||||||
|
- 统一面板背景素材已接入:
|
||||||
|
- `tools/batch_prepare_icons.py` 增加 `--cutout SOURCE OUTPUT WIDTH HEIGHT`,可直接对绿幕素材抠图并输出指定尺寸透明 PNG。
|
||||||
|
- 两张新素材已输出到 `godot/FarmGodot/assets/replacement/panels/panel_shell.png` 和 `godot/FarmGodot/assets/replacement/panels/panel_content.png`。
|
||||||
|
- `UiBuilder.create_panel_shell()` 统一使用新外框;狗面板手写外框、商店/仓库/好友/充值/公告/世界/宠物等主内容区统一改用新内容底图。
|
||||||
|
- 2026-05-12 通过 Godot Web 截图验证商店、仓库、好友、宠物、狗窝面板均能打开且新背景生效。
|
||||||
|
- 异步面板关闭后的失效节点问题已修复:
|
||||||
|
- `PanelModule` 增加节点存活和当前节点校验,避免面板关闭后接口返回继续调用已释放节点。
|
||||||
|
- `LevelGiftPanel`、公告、日志、好友、兑换记录、宝箱、签到、福利、宠物、世界信息等同类面板已按同一规则补防护。
|
||||||
|
- 2026-05-12 通过相关脚本 `--check-only`、Web 导出、`npm run smoke:godot:web` 和等级礼包快速打开/关闭 Playwright 检查验证。
|
||||||
|
- 房屋升级和用户信息面板本轮修正:
|
||||||
|
- 房屋升级按钮按 `BuildingSkin.exml` 的主内容组坐标上移,避免遮盖房屋贴图。
|
||||||
|
- 用户信息顶部资料区补统一内容底图,避免新面板外框透明中心露出主场景背景。
|
||||||
|
- 用户信息标题改用 `roleinfo` 图集的 `panel_title_role_info_png`,用户 ID 显示清理为整数文本,避免 `600.0` 这类浮点格式露出。
|
||||||
|
- `BoxPanel` 和 `LotteryPanel` 的右侧装饰节点补显式 `TextureRect` 类型,修复 Web 编译时 `_ui.add_texture()` 返回值无法推断导致主场景加载失败的问题。
|
||||||
|
- 2026-05-12 通过 `building_panel.gd`、`player_info_panel.gd`、`box_panel.gd`、`lottery_panel.gd` 脚本检查、Web 导出、Playwright 截图和 `npm run smoke:godot:web` 验证。
|
||||||
|
- 农场主界面入口和作物提示本轮修正:
|
||||||
|
- 种子包按旧版 `BagPanelSkin.exml` 的 `x=526,width=114` 对齐到 640 右边缘,并隐藏内部滚动条。
|
||||||
|
- 生长倒计时提示条按旧版 `PlantCdTipSkin.exml` + `CDBarSkin.exml` 改为背景/填充双九宫格,修复普通拉伸导致的进度条质感不一致。
|
||||||
|
- 左侧“福利中心/Benefits”入口、命中区、回调、面板装配和 Godot 福利面板脚本已移除;smoke 流程改为新的左侧菜单顺序。
|
||||||
|
- 2026-05-13 通过相关脚本 `--check-only`、`verify_p0.gd`、工程导入、Web 导出、`npm run smoke:godot:web` 和 `tools/verify_ui_regressions.gd` 验证。
|
||||||
|
- 背包外部点击关闭已接入:
|
||||||
|
- 种子/化肥背包打开后会启用全屏透明关闭命中层;点击背包以外区域只关闭背包,不再把点击透传到土地或主菜单。
|
||||||
|
- 背包面板本体设置为输入阻挡层,点击背包内部空白、滚动区域或物品不会触发外部关闭。
|
||||||
|
- 2026-05-13 通过 `seed_bag_view.gd` 脚本检查、`verify_p0.gd`、Web 导出、`npm run smoke:godot:web` 和 `tools/verify_ui_regressions.gd` 验证。
|
||||||
|
- 作物收获/生长信息卡片拉伸问题已修复:
|
||||||
|
- 旧版 `PlantCdTipSkin.exml` 使用 `log_itembg_png` 和 `scale9Grid="24,20,4,3"`;该素材原始区域为 53x49,Godot `NinePatchRect` 右/下边距应换算为 25/26,而不是直接使用 4/3。
|
||||||
|
- 已把作物提示卡片背景九宫格改为 `24,20,25,26`,避免收获信息卡片横向拉伸后边角和阴影变形。
|
||||||
|
- 2026-05-13 通过 `plant_tip_view.gd` 脚本检查、`verify_p0.gd`、Web 导出、`npm run smoke:godot:web` 和 `tools/verify_ui_regressions.gd` 验证。
|
||||||
|
- 作物信息气泡常驻逻辑已补齐:
|
||||||
|
- 有作物且未收获/未枯萎的土地会在作物头顶持续展示 `PlantCdTip` 气泡;点击作物弹出操作菜单或打开种子/化肥背包时隐藏。
|
||||||
|
- 操作菜单关闭或操作完成刷新土地后,会按当前土地状态恢复气泡;收获后、空地或只剩枯萎草时不再展示。
|
||||||
|
- 农场视口拖动或土地节点位置变化时,气泡每帧按土地当前全局位置重算,避免停留在旧坐标。
|
||||||
|
- 2026-05-23 通过 `plant_tip_view.gd`、`farm_interaction_coordinator.gd`、`verify_ui_regressions.gd` 脚本检查、`tools/verify_ui_regressions.gd`、`verify_p0.gd`、Web 导出和 `npm run smoke:godot:web` 验证。
|
||||||
|
- Home 菜单点击穿透到土地扩建的问题已修复:
|
||||||
|
- 主场景 `_input` 现在先让 `MainMenuController` 处理 Home 按钮、菜单项和菜单外部关闭命中,命中后直接标记输入已处理,再进入农场土地点击兜底。
|
||||||
|
- Home 弧形菜单打开时,点击 Store/Storage/Friends 等菜单项只触发对应菜单动作;点击菜单外部只关闭菜单,不再继续传给土地扩建入口。
|
||||||
|
- 2026-05-13 通过 `main_menu_controller.gd`、`game_scene.gd`、`verify_ui_regressions.gd` 脚本检查、`tools/verify_ui_regressions.gd`、`verify_p0.gd`、Web 导出和 `npm run smoke:godot:web` 验证。
|
||||||
|
- 顶部功能菜单改为单行布局:
|
||||||
|
- 转盘入口从第二行移动到第一行第三个槽位,顺序为 `Log / Land Up / Wheel / Pack`。
|
||||||
|
- 第二行底部木板 `TopPanelBack` 隐藏,不再占用主场景上方空间。
|
||||||
|
- 2026-05-22 通过 `verify_ui_regressions.gd` 增加单行菜单布局断言,并用脚本检查、`verify_p0.gd`、Web 导出、`npm run smoke:godot:web` 和 smoke 截图 `docs/ui-baseline/smoke/01-main.png` 验证。
|
||||||
|
- 种植失败前台反馈已补齐:
|
||||||
|
- 对照旧版 `plantSeed()` 失败分支 `TipsUtils.showErrorCodeTips(status)` 和 `ServerCode[1009] = "当前等级不足"`,Godot 现在会把后端土地操作错误码转成可见 toast,不再只在控制台输出 warning。
|
||||||
|
- `FarmController` 的播种、收获、铲除、施肥、浇水/除虫/除草失败均复用同一错误提示;播种成功补回旧版“播种成功”提示。
|
||||||
|
- `verify_ui_regressions.gd` 增加种子背包物品点击回调断言和服务端 `1009` 文案断言,覆盖“点击种植没有反应”的交互链路。
|
||||||
|
- 狗窝宠物列表背景板已修复:
|
||||||
|
- 旧版 `DogListItemSkin.exml` 使用 `shop_itembg_png`,位置来自 `assets/common.json` 的 `Rect2(262,303,179,110)`,之前 Godot `TextureRegionCatalog` 没登记该区域,导致列表项取到默认 1x1 纹理并被九宫格拉伸成异常背景。
|
||||||
|
- 已补 `shop_itembg` 图集区域,继续按 EXML 的 `scale9Grid="90,57,4,2"` 渲染狗窝列表项。
|
||||||
|
- 2026-05-22 通过 `texture_region_catalog.gd`、`dog_panel.gd`、`verify_ui_regressions.gd` 脚本检查、`verify_ui_regressions.gd`、`verify_p0.gd`、Web 导出、`npm run smoke:godot:web` 和 Playwright 截图 `docs/ui-baseline/godot-dog-list-bg-fixed.png` 验证。
|
||||||
|
- 访问好友农场链路已接入:
|
||||||
|
- 对照旧版 `FriendItemRender.onTouchTap -> GO_OTHER_FARM -> interaction/get-other-user-info -> OPEN_OTHER_GAME`,好友榜家园/手指按钮现在会请求好友农场数据并切换到访客农场。
|
||||||
|
- 新增 `InteractionApi` 和 `FriendVisitController`,接入 `interaction/get-other-user-info` 和 `interaction/interaction`;好友土地动作按后端 `interaction_type_list` 映射偷菜、放虫、放草、浇水、除虫、除草。
|
||||||
|
- 访客模式隐藏自家 Home/World/左侧活动/顶部功能按钮和建筑扩建热区,只保留旧版 `btn_back_home_png` 回家按钮;返回后恢复自家玩家状态、土地、菜单和命中区。
|
||||||
|
- 2026-05-22 通过相关脚本 `--check-only`、`verify_p0.gd`、工程导入、Web 导出、`tools/verify_ui_regressions.gd`、`npm run smoke:godot:web` 和 Playwright 截图 `docs/ui-baseline/smoke/22-friend-panel.png`、`docs/ui-baseline/smoke/23-friend-visit.png`、`docs/ui-baseline/smoke/24-friend-back-home.png` 验证。
|
||||||
|
- 土地扩建金豆图标约束已修复:
|
||||||
|
- 原版 `LandOpenSkin.exml` 使用 `sicon_gold_png`,图集区域为 35x35;Godot 当前替换素材 `assets/replacement/ui/gold_bean.png` 为 500x500,之前 `TextureRect` 在入树后继承原图最小尺寸,导致扩建弹窗右下角出现超大金豆。
|
||||||
|
- `UiBuilder.add_texture()` 改为先设置 `EXPAND_IGNORE_SIZE` 和伸缩模式,再绑定纹理和显式尺寸;扩建弹窗 `GoldIcon` 明确使用 `STRETCH_KEEP_ASPECT_CENTERED`,保持原版 35x35 容器。
|
||||||
|
- 2026-05-22 通过 `ui_builder.gd`、`building_panel.gd`、`verify_ui_regressions.gd` 脚本检查、`tools/verify_ui_regressions.gd`、`verify_p0.gd`、Web 导出、`npm run smoke:godot:web` 和 Playwright 截图 `docs/ui-baseline/godot-land-open-gold-icon-fixed.png` 验证。
|
||||||
|
|
||||||
|
## 下一步
|
||||||
|
|
||||||
|
1. 继续压登录页像素差异,优先处理按钮文字和底部健康提示字体。
|
||||||
|
2. 对照 `egret-main-page.png` 继续压主农场:左侧入口层级、世界/家园入口、顶部 FNT 字体。
|
||||||
|
3. 继续收敛 `PlayerState/FarmState/InventoryState`,减少 UI 层直接改字典。
|
||||||
|
4. 继续补齐未开垦土地购买/开放细节,并把土地相关 UI 从 `game_scene.gd` 拆到独立模块。
|
||||||
|
5. 补齐好友搜索、好友申请和好友互动日志/赠送等二级链路。
|
||||||
187
docs/godot-migration-rebuild.md
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
# Godot H5 重构文档
|
||||||
|
|
||||||
|
## 1. 结论
|
||||||
|
|
||||||
|
本项目从白鹭/Egret H5 客户端重构为 Godot 4.6.2 + GDScript 客户端。当前目标是海外 H5,不接国内小游戏生态,因此优先选择 Godot Web 单线程导出,避免 Unity Web 学习成本和 Cocos Creator 生态迁移成本。
|
||||||
|
|
||||||
|
UI 验收标准是完全一致:关键页面必须以原白鹭版本截图为基准做像素级对照。只跑通功能但视觉不一致,不能算该页面完成。
|
||||||
|
|
||||||
|
已确认的最新稳定版本:
|
||||||
|
|
||||||
|
- Godot 最新稳定版:`4.6.2-stable`,GitHub Release 发布于 2026-04-01。
|
||||||
|
- 本机安装版本:`4.6.2.stable.official.71f334935`。
|
||||||
|
- 工程路径:`godot/FarmGodot`。
|
||||||
|
|
||||||
|
## 2. 原项目事实
|
||||||
|
|
||||||
|
当前客户端事实来自仓库,不做猜测:
|
||||||
|
|
||||||
|
- 原客户端是白鹭/Egret H5。
|
||||||
|
- 主要资源目录:`muchang/home/web/game/resource`,这是当前新版解密 HTML 的资源基准。
|
||||||
|
- UI 皮肤:`resource/skins/**/*.exml`。
|
||||||
|
- 资源清单:`default.res.json`、`default.thm.json`。
|
||||||
|
- 编译逻辑:`muchang/farmer/js/main.min_77d7299f.js`。
|
||||||
|
- 未发现完整 TypeScript 源码、source map、`egretProperties.json`。
|
||||||
|
|
||||||
|
因此这不是自动转换工程,而是以资源、EXML、运行表现、后端接口为规格重新实现客户端。
|
||||||
|
|
||||||
|
## 3. 第一版范围
|
||||||
|
|
||||||
|
第一版只追求最短闭环:
|
||||||
|
|
||||||
|
1. Godot 工程能被 Godot 4.6.2 打开和导入。
|
||||||
|
2. Web/H5 导出模板可用。
|
||||||
|
3. 登录界面按 `LoginSceneSkin.exml` 和白鹭截图做完全一致复刻。
|
||||||
|
4. 解析 Egret `default.res.json`。
|
||||||
|
5. 表单校验通过。
|
||||||
|
6. 配置后端地址后,可以通过 Godot `HTTPRequest` 调登录接口。
|
||||||
|
7. 登录后进入空主场景,再扩展土地、作物、顶部资源栏。
|
||||||
|
|
||||||
|
## 4. 目录结构
|
||||||
|
|
||||||
|
```text
|
||||||
|
godot/FarmGodot/
|
||||||
|
project.godot
|
||||||
|
export_presets.cfg
|
||||||
|
assets/
|
||||||
|
egret/
|
||||||
|
default.res.json
|
||||||
|
default.thm.json
|
||||||
|
assets/
|
||||||
|
config/
|
||||||
|
fonts/
|
||||||
|
skins/
|
||||||
|
common/
|
||||||
|
preloading/
|
||||||
|
login/
|
||||||
|
common/
|
||||||
|
preloading/
|
||||||
|
scenes/
|
||||||
|
bootstrap.tscn
|
||||||
|
ui/login_scene.tscn
|
||||||
|
scripts/
|
||||||
|
bootstrap.gd
|
||||||
|
core/
|
||||||
|
services/
|
||||||
|
ui/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. 官方 API 依据
|
||||||
|
|
||||||
|
开发时优先使用 Godot 官方文档:
|
||||||
|
|
||||||
|
- Godot 4.6.2 Release:https://github.com/godotengine/godot/releases/tag/4.6.2-stable
|
||||||
|
- Godot Web 导出:https://docs.godotengine.org/en/4.6/tutorials/export/exporting_for_web.html
|
||||||
|
- Godot 自定义 HTML shell:https://docs.godotengine.org/en/4.6/tutorials/platform/web/customizing_html5_shell.html
|
||||||
|
- GDScript 风格指南:https://docs.godotengine.org/en/4.6/tutorials/scripting/gdscript/gdscript_styleguide.html
|
||||||
|
- Nodes and Scenes:https://docs.godotengine.org/en/4.6/getting_started/step_by_step/nodes_and_scenes.html
|
||||||
|
- 多分辨率和 Stretch:https://docs.godotengine.org/en/stable/tutorials/rendering/multiple_resolutions.html
|
||||||
|
- HTTPRequest:https://docs.godotengine.org/en/4.6/tutorials/networking/http_request_class.html
|
||||||
|
- JavaScriptBridge:https://docs.godotengine.org/en/4.6/tutorials/platform/web/javascript_bridge.html
|
||||||
|
- TextureRect:https://docs.godotengine.org/en/4.6/classes/class_texturerect.html
|
||||||
|
- TextureButton:https://docs.godotengine.org/en/4.6/classes/class_texturebutton.html
|
||||||
|
- ScrollContainer:https://docs.godotengine.org/en/4.6/classes/class_scrollcontainer.html
|
||||||
|
- NinePatchRect:https://docs.godotengine.org/en/4.6/classes/class_ninepatchrect.html
|
||||||
|
- Control:https://docs.godotengine.org/en/4.6/classes/class_control.html
|
||||||
|
- AtlasTexture:https://docs.godotengine.org/en/4.6/classes/class_atlastexture.html
|
||||||
|
- Timer:https://docs.godotengine.org/en/4.6/classes/class_timer.html
|
||||||
|
- FileAccess:https://docs.godotengine.org/en/4.6/classes/class_fileaccess.html
|
||||||
|
- JSON:https://docs.godotengine.org/en/4.6/classes/class_json.html
|
||||||
|
|
||||||
|
官方没有覆盖到的自动化测试框架,后续优先评估 GitHub/Godot Asset Library 的 GUT。当前查到 GUT 9.6.0 支持 Godot 4.6.x:https://github.com/bitwes/Gut
|
||||||
|
|
||||||
|
## 6. Web/H5 约束
|
||||||
|
|
||||||
|
根据官方 Web 导出文档:
|
||||||
|
|
||||||
|
- Godot 4 Web 需要浏览器支持 WebAssembly 和 WebGL 2.0。
|
||||||
|
- Godot 4 C# 不能导出 Web,因此本工程只使用 GDScript。
|
||||||
|
- Web 目标只能使用 Compatibility 渲染路径,不能使用 Forward+/Mobile。
|
||||||
|
- Web HTTP 请求受浏览器同源策略和 CORS 限制。
|
||||||
|
- WebSocket 客户端可用,但不能依赖原生 TCP/UDP socket。
|
||||||
|
- 默认使用单线程 Web 导出,避免 SharedArrayBuffer 和 cross-origin isolation 约束。
|
||||||
|
|
||||||
|
## 7. 迁移策略
|
||||||
|
|
||||||
|
### UI
|
||||||
|
|
||||||
|
- EXML 作为规格,不直接当运行时格式。
|
||||||
|
- 如果 EXML 和 `default.thm_*.js` 编译结果不同,以旧 H5 实际运行截图和编译结果为准。
|
||||||
|
- 第一阶段手工复刻关键页面:登录、主场景、顶部资源栏、农场视图。
|
||||||
|
- 页面完成标准是白鹭截图和 Godot 截图在同分辨率下像素级对齐,任何肉眼可见差异都记录为未完成。
|
||||||
|
- 使用浏览器截图对比时,必须记录页面截图、实际 canvas 截图、元数据和 diff 图。
|
||||||
|
- 后续再写 EXML 扫描/辅助转换工具,不追求 100% 自动转换。
|
||||||
|
- Godot UI 使用 `Control`、`TextureRect`、`NinePatchRect`、`Label`、`LineEdit`、`Button`、`TextureButton`、`ScrollContainer`。
|
||||||
|
|
||||||
|
### 资源
|
||||||
|
|
||||||
|
- 原版新版素材完整同步到 `godot/FarmGodot/assets/egret/`,相对路径和 `muchang/home/web/game/resource/` 保持一致。
|
||||||
|
- `default.res.json` 用 `GameConfigCatalog` 和后续 Egret 资源解析器读取。
|
||||||
|
- 普通图片先作为 Godot `Texture2D` 直接导入。
|
||||||
|
- Egret 图集 `png + json` 后续转为 Godot 可引用的 `AtlasTexture` 资源。
|
||||||
|
- 字体、FNT、音频原始文件已迁入;运行时按页面需要逐步接入位图字体、音效和动效。
|
||||||
|
|
||||||
|
### 网络
|
||||||
|
|
||||||
|
- HTTP 统一走 `ApiClient`,内部使用 Godot `HTTPRequest`。
|
||||||
|
- 配置项放在 `project.godot` 的 `farm_game/api/base_url`。
|
||||||
|
- Web 环境必须先验证 CORS。
|
||||||
|
- 旧 PHP/Yii 接口先不改,Godot 端适配请求和响应。
|
||||||
|
|
||||||
|
### 架构
|
||||||
|
|
||||||
|
- `scripts/services` 放网络、配置、账号等服务。
|
||||||
|
- `scripts/core` 放无场景依赖的纯逻辑。
|
||||||
|
- `scripts/ui` 放界面脚本。
|
||||||
|
- 场景负责组合节点,业务逻辑放脚本,数据模型不要写进 UI 节点。
|
||||||
|
|
||||||
|
## 8. 土地交互规范
|
||||||
|
|
||||||
|
土地交互以旧白鹭客户端和后端接口为准,不凭空设计新流程。
|
||||||
|
|
||||||
|
### 原版菜单规则
|
||||||
|
|
||||||
|
- 空地:普通点击显示播种菜单。
|
||||||
|
- 成长中:普通点击显示铲除、施肥;如果有虫害显示除虫;如果有草害显示除草。
|
||||||
|
- 成熟:普通点击显示收割。
|
||||||
|
- 已收割或枯萎:普通点击显示铲除。
|
||||||
|
- 倒计时:按旧客户端长按行为显示 `PlantCdTip`,不能占用普通点击菜单。
|
||||||
|
|
||||||
|
### 接口映射
|
||||||
|
|
||||||
|
- 播种:`farm/sow-seeds`
|
||||||
|
- 收获:`farm/gather-crop`
|
||||||
|
- 铲除:`farm/clear-land`
|
||||||
|
- 施肥:`farm/fertilize`
|
||||||
|
- 除虫/除草:`farm/disease`,虫害类型 `1`,草害类型 `2`
|
||||||
|
- 种子、化肥、作物配置:`game_config.json`
|
||||||
|
- 背包数据:`store-house`
|
||||||
|
|
||||||
|
### Godot 实现约束
|
||||||
|
|
||||||
|
- 土地状态按钮继续由 `Control/Button` 覆盖土地热区,不改变底层贴图布局。
|
||||||
|
- 圆形操作菜单沿用旧版菜单贴图和相对位置,不新增解释性文案。
|
||||||
|
- 作物阶段、种子名称、化肥图标和阶段时间从 `GameConfigCatalog` 读取。
|
||||||
|
- `game_config.json` 通过 Web export include filter 保持原始文件导出;运行时用 `FileAccess` 和 `JSON` 读取。
|
||||||
|
- 长按倒计时使用 `Timer` 识别,进度条和面板使用旧版图集区域与 `NinePatchRect`。
|
||||||
|
- 每个会改后端状态的操作成功后,只刷新当前土地和必要的本地玩家资源,不做整页重载。
|
||||||
|
|
||||||
|
## 9. 验证标准
|
||||||
|
|
||||||
|
每个阶段必须验证:
|
||||||
|
|
||||||
|
- Godot 能导入工程:`godot --headless --path godot/FarmGodot --import --quit`
|
||||||
|
- GDScript 语法能检查:`godot --headless --path godot/FarmGodot --check-only --script <script>`
|
||||||
|
- Web 能导出:`godot --headless --path godot/FarmGodot --export-release Web build/web/index.html`
|
||||||
|
- 浏览器可打开构建产物。
|
||||||
|
- 与 Egret 版本对照截图,逐页修正布局。
|
||||||
|
- 涉及接口的功能必须用真实后端账号验证 HTTP 状态和业务状态,并在测试后恢复测试数据。
|
||||||
|
- UI 像素对比:`NODE_PATH=/tmp/farm3-playwright/node_modules node tools/compare_ui_baseline.mjs docs/ui-baseline/egret-login-page.png docs/ui-baseline/godot-login-page.png docs/ui-baseline/login-page-diff.png`
|
||||||
|
|
||||||
|
## 10. 近期开发顺序
|
||||||
|
|
||||||
|
1. 把登录页像素差异从当前 `1.8239%` 压到可验收。
|
||||||
|
2. 对照主农场截图继续压 UI 差异:顶部 FNT、资源文字对齐、左侧入口、世界/家园入口。
|
||||||
|
3. 建立玩家数据模型,保存 token、玩家基础信息、土地列表、背包摘要。
|
||||||
|
4. 补齐土地剩余交互:浇水、扩建、未开垦土地购买/开放。
|
||||||
|
5. 建立更多页面的白鹭截图和 Godot 截图对比流程。
|
||||||
141
docs/godot-refactor-status-priority.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Godot 重构进度与功能缺口优先级
|
||||||
|
|
||||||
|
更新时间:2026-05-12
|
||||||
|
|
||||||
|
## 依据
|
||||||
|
|
||||||
|
本清单基于当前本地代码和原 H5 参考核对,不按记忆推断。
|
||||||
|
|
||||||
|
- Godot 当前实现:`godot/FarmGodot/scripts/ui/game_scene.gd`
|
||||||
|
- Godot 服务层:`godot/FarmGodot/scripts/services/*.gd`
|
||||||
|
- Godot 配置层:`godot/FarmGodot/scripts/core/game_config_catalog.gd`
|
||||||
|
- 原 H5 面板通知:`muchang/home/web/game/js/main/00-runtime-and-notify.js`
|
||||||
|
- 原 H5 主场景入口:`muchang/home/web/game/js/main/03-game-ui-core.js`
|
||||||
|
- 原 H5 面板和中介:`muchang/home/web/game/js/main/05-config-and-panels.js`、`07-mediators.js`
|
||||||
|
- 原 H5 世界/宠物/游乐园/竞技:`13-world-features.js`、`15-battle-pet-full.js`、`16-amusement-park-full.js`、`17-sports-full.js`
|
||||||
|
- 最近验证截图:`docs/ui-baseline/godot-new2-final-*.png`
|
||||||
|
|
||||||
|
## 当前重构进度
|
||||||
|
|
||||||
|
### 已完成
|
||||||
|
|
||||||
|
- Godot 4.6.2 工程、Web 导出预设和 H5 本地预览流程。
|
||||||
|
- Egret 原资源同步到 `godot/FarmGodot/assets/egret/`。
|
||||||
|
- 自动登录:`13800000001 / 123456`。
|
||||||
|
- 后端协议:`ApiClient` 已按原 H5 `msg=<base64(JSON)>` 方式请求。
|
||||||
|
- 主农场第一版:
|
||||||
|
- 顶部玩家信息、经验、金币、钻石、战力。
|
||||||
|
- 农场背景、房屋、狗屋、围栏、土地、宠物牌。
|
||||||
|
- 左侧活动入口、右下家园入口、左下世界入口。
|
||||||
|
- 双指缩放土地场景,UI 不跟随缩放。
|
||||||
|
- 土地基础玩法:
|
||||||
|
- 播种、收获、铲除、施肥、除虫、除草。
|
||||||
|
- 成长倒计时、成熟自动刷新、成熟点击收获。
|
||||||
|
- 种子包、化肥包、土地异常状态图标。
|
||||||
|
- 家园菜单第一版:
|
||||||
|
- 商店、仓库、好友入口。
|
||||||
|
- 商店购买、仓库出售、好友排行。
|
||||||
|
- 建筑和扩展:
|
||||||
|
- 房屋升级面板和接口。
|
||||||
|
- 土地扩建面板和接口。
|
||||||
|
- 狗窝面板、狗粮喂养。
|
||||||
|
- 活动和系统入口:
|
||||||
|
- 日志、系统公告、福利大厅、兑换金币。
|
||||||
|
- 等级礼包、在线礼包、每日签到、宝箱、幸运转盘。
|
||||||
|
- 宠物列表、宠物显示、宠物喂养、宠物参战。
|
||||||
|
- 世界弹出菜单:投放、收获、喂养、去农场。
|
||||||
|
- 架构拆分:
|
||||||
|
- `scripts/services/`:接口服务层已建立。
|
||||||
|
- `scripts/state/`:玩家、农场、背包状态层已建立。
|
||||||
|
- `scripts/domain/rules/`:土地动作、作物阶段、成本判断已建立。
|
||||||
|
- `scripts/domain/mappers/`:农场和背包数据映射已建立。
|
||||||
|
- `scripts/resources/`:图集区域和纹理缓存已建立。
|
||||||
|
- `scripts/ui/hud/top_bar_view.gd`:顶部 HUD 渲染已迁出。
|
||||||
|
- `scripts/ui/menus/`:主菜单和世界菜单控制器已迁出。
|
||||||
|
- `scripts/ui/common/`:弹窗层、Toast、按钮动效公共逻辑已迁出。
|
||||||
|
- `scripts/ui/farm/farm_viewport_controller.gd`:农场拖动视口、双指/滚轮缩放已迁出。
|
||||||
|
- `scripts/ui/game_scene_runtime_assembler.gd`:HUD、菜单、弹窗、宠物展示、农场缩放、土地网格、土地菜单、背包、种植提示和 hit 路由装配已迁出。
|
||||||
|
- `scripts/ui/game_scene_panel_router.gd`:所有面板入口、弹窗打开/关闭和仓库/好友入口状态已迁出。
|
||||||
|
- `scripts/ui/game_scene_context.gd`:面板共享依赖和 legacy callback 兼容层已收敛。
|
||||||
|
- `scripts/state/player_state.gd`:合并原玩家字段访问器,玩家快照只保留一个权威来源。
|
||||||
|
- `scripts/ui/common/icon_texture_provider.gd`:物品、宠物、作物和房屋图标加载已集中缓存。
|
||||||
|
|
||||||
|
### 部分完成
|
||||||
|
|
||||||
|
- UI 对齐:主场景和大部分面板已能打开并使用原资源,但不是像素级一致。
|
||||||
|
- 动效:主菜单、世界菜单、土地菜单、弹窗有 Tween;仍未覆盖所有原版细节动效。
|
||||||
|
- 好友:只完成排行和列表;搜索、申请、访问好友家园、好友互动仍是占位提示。
|
||||||
|
- 世界功能:只完成菜单和信息型面板;游乐园、竞技场、成就领取、战宠对战还不是完整玩法。
|
||||||
|
- 福利大厅:VIP/卡数据显示和领取已接;购买周卡/月卡已接入充值下单入口,支付完成回调仍需海外平台 SDK。
|
||||||
|
- 兑换金币:兑换和记录已接;UI 仍是 Godot 第一版排版,不是原版完整皮肤。
|
||||||
|
- 资源系统:可读 Egret 图集 JSON 并缓存 `AtlasTexture`;没有批量生成 `.tres` 和 EXML 辅助转换工具。
|
||||||
|
- 架构:服务/状态/规则、公共 UI、运行时装配、面板路由、土地交互和主要面板已拆出;`game_scene.gd` 当前 957 行,已低于 1200 行目标,后续风险集中在旧面板 legacy callbacks。
|
||||||
|
|
||||||
|
### 明确未补齐
|
||||||
|
|
||||||
|
- 充值/支付:原 H5 有 `OPEN_PAY` 和 `pay/pay`;Godot 已接 Top Up、周卡/月卡购买入口和支付下单 URL 跳转,实际支付完成回调仍需接海外平台 SDK。
|
||||||
|
- 换肤/背景:原 H5 有 `OPEN_SKIN` 和 `farm/change-bg`;Godot 当前商店背景 tab 不是完整换肤流程。
|
||||||
|
- 玩家信息:原 H5 有 `OPEN_PLAYER_INFO`;Godot 当前头像点击没有完整角色信息面板。
|
||||||
|
- 好友搜索/申请/请求处理/赠送/互动/访问好友农场:Godot 当前大多是 toast 占位。
|
||||||
|
- 竞技场完整玩法:挑战列表、挑战、周奖励、领奖未补齐。
|
||||||
|
- 游乐园完整玩法:进入、翻牌/抽奖/奖励结算未补齐。
|
||||||
|
- 成就完整玩法:领取成就奖励未做完整交互。
|
||||||
|
- 战宠完整玩法:战斗详情、对战流程、战斗结果未补齐。
|
||||||
|
- 音频、FNT、全部原版动画、所有面板像素级对照未完成。
|
||||||
|
|
||||||
|
## P0:必须优先补齐
|
||||||
|
|
||||||
|
P0 是继续开发和第一版可玩闭环的阻断项。
|
||||||
|
|
||||||
|
| 项目 | 当前状态 | 依据 | 下一步 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 拆分 `game_scene.gd` | P0 完成:土地、背包、公共 UI、菜单、HUD、弹窗层、商店/仓库/好友/建筑/狗/活动/支付/福利/兑换/世界/签到/宝箱/转盘/宠物面板、启动装配、运行时装配、面板路由、hit 路由、土地交互协调、库存 Facade、玩家状态、场景上下文已拆成模块 | `wc -l godot/FarmGodot/scripts/ui/game_scene.gd` 当前低于 1200 行;新增 `GameSceneBootstrap`、`GameSceneRuntimeAssembler`、`GameScenePanelRouter`、`SceneHitRouter`、`FarmInteractionCoordinator`、`PlayerInventoryFacade`、`PlayerState`、`GameSceneContext` | P1 继续把旧面板从 legacy callbacks 迁到显式 Context 方法 |
|
||||||
|
| UI 像素级一致 | 功能入口已按原素材补齐并保留烟测截图;仍需逐页和 Egret 基准压差异 | `docs/ui-baseline/smoke/*.png` | 每个入口固定 Egret/Godot 对照截图,按主场景、土地、活动、家园面板逐页压差异 |
|
||||||
|
| 浇水 | 已完成 | 原 H5 `KICK_WATER -> farm/disease type=0`;`LandActionRules` 已接 `ACTION_WATER` | 干旱土地菜单显示浇水图标,执行 `farm/disease type=0`,刷新土地状态 |
|
||||||
|
| 土地升级 | 已完成第一版闭环 | 原 H5 `OPEN_LAND_UPGRADE -> farm/upgrade-land`;`BuildingApi.upgrade_land()` | 顶部 Land Up 打开原版布局面板,按土地等级/顺位取配置,校验等级/材料/前置土地,成功刷新土地 |
|
||||||
|
| 充值/支付入口 | 已完成第一版闭环 | 原 H5 `OPEN_PAY -> pay/pay`;Godot 新增 `PayApi` | Top Up 和福利卡购买打开充值面板,`pay/pay` 成功后 Web 端用 `JavaScriptBridge` 跳转支付 URL |
|
||||||
|
| 状态一致性 | P0 完成:奖励、消耗、仓库刷新、货币写入走 `PlayerInventoryFacade`,玩家快照字段统一走 `PlayerState` | 主场景内玩家字段不再依赖 `PlayerDataAccessor`,`PlayerInventoryFacade` 也改为引用 `PlayerState` | P1 把世界/好友等跨模块状态继续收敛到显式 State/Facade apply |
|
||||||
|
| 真实 Web 烟测流程 | 已完成 | `tools/smoke_godot_web.mjs` | 覆盖主场景、Top Up、Land Up、福利大厅、土地菜单、世界菜单、缩放;截图输出到 `docs/ui-baseline/smoke/` |
|
||||||
|
|
||||||
|
## P1:第一版完整度补齐
|
||||||
|
|
||||||
|
P1 是原版主要系统补齐项,不一定阻断农场主循环,但会影响“功能逻辑一致”。
|
||||||
|
|
||||||
|
| 项目 | 当前状态 | 依据 | 下一步 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 好友完整系统 | 排行和好友列表已接,搜索/申请/请求/访问/互动未接 | Godot 里 `好友搜索面板后续补齐`、`查看家园`、`互动` 为 toast | 补 `friend/find`、`friend/add`、`friend/get-respond-list`、`friend/respond-list`、`friend/respond`,再做好友农场场景 |
|
||||||
|
| 好友农场和互动 | 无 `SceneNotify.OPEN_OTHER_GAME` 对应完整场景 | 原 H5 `GO_OTHER_FARM`、`interaction/interaction` | 支持访问他人农场、放虫/放草/浇水/除虫/除草互动,区分自己和好友土地菜单 |
|
||||||
|
| 世界-成就 | 只展示列表,没有完整领取/分页/状态 | Godot 有 `fetch_achievements/claim_achievement`,UI 未完整绑定领取 | 补成就详情、领取按钮、领取后状态刷新 |
|
||||||
|
| 世界-竞技场 | 只展示基础数据和排行 | 原 H5 有 `arena/get-challenge-list`、`arena/challenge`、`arena/week-gift-list`、`arena/get-gift` | 补挑战列表、挑战流程、战斗结果、每周奖励 |
|
||||||
|
| 世界-游乐园 | 只展示次数和奖励配置 | 原 H5 有 `comm/enter-pleasure-ground`、`comm/pleasure-ground` | 补进入、玩法步骤、奖励结算和次数扣除 |
|
||||||
|
| 世界-战宠对战 | 宠物列表/喂养/参战已接,对战未接 | 原 H5 有 `pet/battle`、`pet/get-battle-info` | 补战宠对战入口、战斗详情、结果动画 |
|
||||||
|
| 换肤/背景 | 商店背景 tab 和换肤系统未闭环 | 原 H5 `OPEN_SKIN -> farm/change-bg` | 补 SkinPanel、已拥有背景列表、应用背景、购买背景后的状态刷新 |
|
||||||
|
| 玩家信息 | 未做完整角色信息面板 | 原 H5 `OPEN_PLAYER_INFO` | 头像点击打开角色资料,支持昵称/形象信息展示 |
|
||||||
|
| 活动面板细节 | 已能打开,部分逻辑和动效仍简化 | 宝箱、签到、福利、转盘等 Godot UI 为第一版 | 对照原皮肤补齐分页、倒计时、按钮状态、领奖动画、奖励弹窗 |
|
||||||
|
| 商店/仓库完整性 | 基础购买/出售已接 | 原 H5 商店含普通/神秘/背景,仓库含多分类 | 补完整分类、数量选择、使用道具、背景商品、不可售状态 |
|
||||||
|
|
||||||
|
## P2:质量、工具和发布能力
|
||||||
|
|
||||||
|
P2 不阻断第一版功能闭环,但影响长期效率、质量和海外发布。
|
||||||
|
|
||||||
|
| 项目 | 当前状态 | 下一步 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| EXML 辅助转换工具 | 未实现 | 做 EXML 坐标/九宫格/资源名提取工具,减少手写 UI 坐标 |
|
||||||
|
| Egret 图集批量 `.tres` 生成 | 局部使用运行时图集缓存 | 批量生成 Godot 可引用 AtlasTexture 或统一运行时缓存索引 |
|
||||||
|
| FNT/字体一致性 | 部分位图字和字体仍不完全一致 | 系统整理 FNT 解析和 Label 替换规则 |
|
||||||
|
| 音频系统 | 原资源已迁入,运行时播放未完整接入 | 补背景音乐、点击音效、奖励音效、开关设置 |
|
||||||
|
| 动效库 | 基础按钮/点击动效已抽到 `UiMotion`,部分面板和土地动效仍在各自模块 | 继续抽通用弹入、奖励飞字、面板切换动画 |
|
||||||
|
| 自动化测试 | 只有手动命令和截图脚本片段 | 增加 Godot check、Web 导出、Playwright 烟测的一键脚本 |
|
||||||
|
| CI/构建脚本 | 未固化 | 添加本地 `tools/export_web.sh` 或 Makefile,后续接 CI |
|
||||||
|
| 配置环境切换 | 后端地址写在 `project.godot` | 增加 dev/staging/prod 配置方案,避免手动改 base_url |
|
||||||
|
| 海外 SDK | 未接 | 支付、广告、统计、登录平台 SDK 通过 Web JavaScriptBridge 薄封装 |
|
||||||
|
| 代码清理 | 仍有重复/临时逻辑风险 | 清理重复 return、toast 占位、直接字典读写和未使用常量 |
|
||||||
|
| 文档同步 | 旧进度文档部分过期 | 用本文档作为当前优先级源,阶段完成后同步 `README.MD` 和迁移进度 |
|
||||||
|
|
||||||
|
## 建议执行顺序
|
||||||
|
|
||||||
|
1. 已完成:P0-2 浇水和土地升级,完成农场核心土地闭环。
|
||||||
|
2. 已完成:P0-3 充值/支付入口的可替换接口层,Top Up 和福利卡购买不再是占位。
|
||||||
|
3. 已完成:P0-4 Playwright Web 烟测脚本,导出后可固定跑主场景、土地、活动、世界、缩放。
|
||||||
|
4. 已完成:P0-1 `game_scene.gd` 深拆当前阶段,启动装配、hit 路由、土地交互、库存状态写入已迁出。
|
||||||
|
5. P1:按世界功能和好友功能拆独立模块,先做接口闭环,再压 UI。
|
||||||
21
docs/ui-baseline/README.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# UI Baseline
|
||||||
|
|
||||||
|
本目录保存白鹭旧版和 Godot 重构版的登录页截图、元数据和 diff 图。
|
||||||
|
|
||||||
|
当前固定浏览器参数:
|
||||||
|
|
||||||
|
- viewport:`640 x 960`
|
||||||
|
- `deviceScaleFactor: 1`
|
||||||
|
- 白鹭旧版 URL:`http://127.0.0.1:8791/index.html`
|
||||||
|
- Godot H5 URL:`http://127.0.0.1:8792/index.html`
|
||||||
|
- 白鹭实际游戏 canvas:最后一个 `canvas`,当前实测 `480 x 960`
|
||||||
|
- Godot 实际游戏 canvas:`480 x 960` CSS 显示,内部 buffer `640 x 960`
|
||||||
|
|
||||||
|
当前对比命令:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
NODE_PATH=/tmp/farm3-playwright/node_modules node tools/compare_ui_baseline.mjs docs/ui-baseline/egret-login-page.png docs/ui-baseline/godot-login-page.png docs/ui-baseline/login-page-diff.png
|
||||||
|
NODE_PATH=/tmp/farm3-playwright/node_modules node tools/compare_ui_baseline.mjs docs/ui-baseline/egret-login-canvas.png docs/ui-baseline/godot-login-canvas.png docs/ui-baseline/login-canvas-diff.png
|
||||||
|
```
|
||||||
|
|
||||||
|
登录页还没有达到“完全一致”验收标准。当前差异主要集中在字体渲染和贴图采样边缘。
|
||||||
103
docs/ui-baseline/autologin-and-new-html-meta.json
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "request",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"body": "msg=eyJ1c2VybmFtZSI6IjEzODAwMDAwMDAxIiwicGFzc3dvcmQiOiIxMjM0NTYifQ%3D%3D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "request",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=comm/game-config",
|
||||||
|
"body": "msg=eyJtc2ciOjEyMywidG9rZW4iOiIxNTJkZjY4ZjViMzYwYzQ2NmIwMTMwNDNhYjgxNWVlZiJ9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"status": 200,
|
||||||
|
"text": "{\"status\":0,\"server_time\":1778504658,\"data\":\"eyJpZCI6NjAwLCJ1c2VybmFtZSI6IjEzODAwMDAwMDAxIiwicGF5X3Bhc3N3b3JkIjoiJDJ5JDEzJHFzNzlcL3UwM1dmaVNjd0NseXF5cGxlY1lVUVZVRG1CVDQ4NWRod1REQjBJaXNcL0Y2SzRHMXkiLCJyZWFsbmFtZSI6IiIsIm5pY2tuYW1lIjoiMTIzMSIsInd4X25hbWUiOiIiLCJhdmF0YXIiOiIxIiwic2V4IjowLCJnb2xkIjo0Mjk0OTQ1MTc2LCJnZW0iOjc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "request",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"body": "msg=eyJtc2ciOjEyMywidG9rZW4iOiIxNTJkZjY4ZjViMzYwYzQ2NmIwMTMwNDNhYjgxNWVlZiJ9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=comm/game-config",
|
||||||
|
"status": 200,
|
||||||
|
"text": "{\"status\":0,\"server_time\":1778504658,\"data\":\"eyJ2aXBfbGlzdCI6eyIxIjp7ImlkIjoxLCJyZWNoYXJnZV9hbW91bnQiOjMwMCwiZml4ZWRfcmV3YXJkX2lkIjoiMTA1MDAyOjUwMCIsImN5Y2xlX2JvbnVzX2lkMSI6IjEwNTAwMjoxMCIsImN5Y2xlX2JvbnVzX2lkMiI6IjEwMjAwMToxMCIsImN5Y2xlX2JvbnVzX2lkMyI6IjEwMjAwMzoxMCIsInR1cm50YWJsZV9mcmVxdWVuY3kiOjEsInBsYXlncm91bmRfZnJ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "new-html",
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"status": 200,
|
||||||
|
"text": "{\"status\":0,\"server_time\":1778504658,\"data\":\"W3siaWQiOjExNjM0LCJ1c2VyX2lkIjo2MDAsIml0ZW1faWQiOjEwMjAwMSwibmFtZSI6Ilx1OTFkMVx1Njg1NCIsInR5cGUiOjIsIm51bSI6MTg2fSx7ImlkIjoxMTY0NSwidXNlcl9pZCI6NjAwLCJpdGVtX2lkIjoxMDIwMDMsIm5hbWUiOiJcdTU3MjNcdTU5NzNcdTY3OWMiLCJ0eXBlIjoyLCJudW0iOjEwfSx7ImlkIjoxMTYzMiwidXNlcl9pZCI6NjAwLCJpdGV"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "warning",
|
||||||
|
"text": "[.WebGL-0x13c001c7800]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "request",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"body": "msg=eyJwYXNzd29yZCI6IjEyMzQ1NiIsInVzZXJuYW1lIjoiMTM4MDAwMDAwMDEifQ%3D%3D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "warning",
|
||||||
|
"text": "[.WebGL-0x13c001dce00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "console",
|
||||||
|
"level": "warning",
|
||||||
|
"text": "[.WebGL-0x13c001de600]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"status": 200,
|
||||||
|
"text": "{\"status\":0,\"server_time\":1778504665,\"data\":\"eyJpZCI6NjAwLCJ1c2VybmFtZSI6IjEzODAwMDAwMDAxIiwicGF5X3Bhc3N3b3JkIjoiJDJ5JDEzJHFzNzlcL3UwM1dmaVNjd0NseXF5cGxlY1lVUVZVRG1CVDQ4NWRod1REQjBJaXNcL0Y2SzRHMXkiLCJyZWFsbmFtZSI6IiIsIm5pY2tuYW1lIjoiMTIzMSIsInd4X25hbWUiOiIiLCJhdmF0YXIiOiIxIiwic2V4IjowLCJnb2xkIjo0Mjk0OTQ1MTc2LCJnZW0iOjc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "request",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"body": "msg=eyJ0b2tlbiI6ImMxN2FhMDM0YTU4NTEzNjM4NzI1NWYwNTM1MDQ5YTgxIn0%3D"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"page": "godot",
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"status": 200,
|
||||||
|
"text": "{\"status\":0,\"server_time\":1778504666,\"data\":\"W3siaWQiOjExNjM0LCJ1c2VyX2lkIjo2MDAsIml0ZW1faWQiOjEwMjAwMSwibmFtZSI6Ilx1OTFkMVx1Njg1NCIsInR5cGUiOjIsIm51bSI6MTg2fSx7ImlkIjoxMTY0NSwidXNlcl9pZCI6NjAwLCJpdGVtX2lkIjoxMDIwMDMsIm5hbWUiOiJcdTU3MjNcdTU5NzNcdTY3OWMiLCJ0eXBlIjoyLCJudW0iOjEwfSx7ImlkIjoxMTYzMiwidXNlcl9pZCI6NjAwLCJpdGV"
|
||||||
|
}
|
||||||
|
]
|
||||||
BIN
docs/ui-baseline/egret-after-login-canvas.png
Normal file
|
After Width: | Height: | Size: 403 KiB |
33
docs/ui-baseline/egret-after-login-meta.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"url": "http://127.0.0.1:18082/game/index.html",
|
||||||
|
"dpr": 1,
|
||||||
|
"innerWidth": 640,
|
||||||
|
"innerHeight": 960,
|
||||||
|
"bodyClientWidth": 640,
|
||||||
|
"bodyClientHeight": 960,
|
||||||
|
"canvases": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 1136,
|
||||||
|
"cssWidth": 542,
|
||||||
|
"cssHeight": 960,
|
||||||
|
"left": 49,
|
||||||
|
"top": 0,
|
||||||
|
"style": "cursor: inherit; position: absolute; inset: 0px 0px 0px 49px; transform-origin: 0% 0% 0px; width: 542px; height: 960px; transform: rotate(0deg);"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actualCanvas": {
|
||||||
|
"index": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 1136,
|
||||||
|
"cssWidth": 542,
|
||||||
|
"cssHeight": 960,
|
||||||
|
"left": 49,
|
||||||
|
"top": 0,
|
||||||
|
"style": "cursor: inherit; position: absolute; inset: 0px 0px 0px 49px; transform-origin: 0% 0% 0px; width: 542px; height: 960px; transform: rotate(0deg);"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"messages": []
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/egret-after-login-page.png
Normal file
|
After Width: | Height: | Size: 408 KiB |
6
docs/ui-baseline/egret-after-sow-log.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=comm/game-config",
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=farm/sow-seeds"
|
||||||
|
]
|
||||||
BIN
docs/ui-baseline/egret-after-sow.png
Normal file
|
After Width: | Height: | Size: 767 KiB |
BIN
docs/ui-baseline/egret-login-canvas.png
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
docs/ui-baseline/egret-login-debug-after.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
docs/ui-baseline/egret-login-debug-before.png
Normal file
|
After Width: | Height: | Size: 417 KiB |
31
docs/ui-baseline/egret-login-meta-dpr1.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"dpr": 1,
|
||||||
|
"innerWidth": 640,
|
||||||
|
"innerHeight": 960,
|
||||||
|
"bodyClientWidth": 640,
|
||||||
|
"bodyClientHeight": 960,
|
||||||
|
"main": {
|
||||||
|
"styleLeft": "",
|
||||||
|
"width": 480,
|
||||||
|
"height": 960,
|
||||||
|
"left": 0,
|
||||||
|
"top": 0
|
||||||
|
},
|
||||||
|
"canvas": {
|
||||||
|
"width": 736,
|
||||||
|
"height": 1308,
|
||||||
|
"cssWidth": 368,
|
||||||
|
"cssHeight": 654,
|
||||||
|
"left": 3.5,
|
||||||
|
"top": -0.5,
|
||||||
|
"style": "cursor: inherit; position: absolute; top: -0.5px; bottom: 0px; left: 3.5px; right: 0px; transform-origin: 0% 0% 0px; transform: matrix(0.5, 0, 0, 0.5, 0, 0);"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"messages": [
|
||||||
|
"log: this.isOpen:true",
|
||||||
|
"log: {nickName: username}",
|
||||||
|
"log: n",
|
||||||
|
"log: n"
|
||||||
|
]
|
||||||
|
}
|
||||||
48
docs/ui-baseline/egret-login-meta.json
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8791/index.html",
|
||||||
|
"meta": {
|
||||||
|
"dpr": 1,
|
||||||
|
"innerWidth": 640,
|
||||||
|
"innerHeight": 960,
|
||||||
|
"bodyClientWidth": 640,
|
||||||
|
"bodyClientHeight": 960,
|
||||||
|
"canvases": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"width": 736,
|
||||||
|
"height": 1308,
|
||||||
|
"cssWidth": 368,
|
||||||
|
"cssHeight": 654,
|
||||||
|
"left": 3.5,
|
||||||
|
"top": -0.5,
|
||||||
|
"style": "cursor: inherit; position: absolute; top: -0.5px; bottom: 0px; left: 3.5px; right: 0px; transform-origin: 0% 0% 0px; transform: matrix(0.5, 0, 0, 0.5, 0, 0);"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 1,
|
||||||
|
"width": 480,
|
||||||
|
"height": 960,
|
||||||
|
"cssWidth": 480,
|
||||||
|
"cssHeight": 960,
|
||||||
|
"left": 0,
|
||||||
|
"top": 0,
|
||||||
|
"style": "cursor: inherit; position: absolute; inset: 0px; transform-origin: 0% 0% 0px; transform: matrix(1, 0, 0, 1, 0, 0);"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actualCanvas": {
|
||||||
|
"index": 1,
|
||||||
|
"width": 480,
|
||||||
|
"height": 960,
|
||||||
|
"cssWidth": 480,
|
||||||
|
"cssHeight": 960,
|
||||||
|
"left": 0,
|
||||||
|
"top": 0,
|
||||||
|
"style": "cursor: inherit; position: absolute; inset: 0px; transform-origin: 0% 0% 0px; transform: matrix(1, 0, 0, 1, 0, 0);"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"messages": [
|
||||||
|
"log: this.isOpen:true",
|
||||||
|
"log: {nickName: username}",
|
||||||
|
"log: n",
|
||||||
|
"log: n"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/egret-login-page-dpr1.png
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
docs/ui-baseline/egret-login-page.png
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
docs/ui-baseline/egret-main-canvas.png
Normal file
|
After Width: | Height: | Size: 753 KiB |
32
docs/ui-baseline/egret-main-meta.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"url": "http://127.0.0.1:18082/game/index.html?v=1778497178141",
|
||||||
|
"title": "天才农场",
|
||||||
|
"canvas": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 1136,
|
||||||
|
"left": 49,
|
||||||
|
"top": 0,
|
||||||
|
"cssWidth": 542,
|
||||||
|
"cssHeight": 960
|
||||||
|
},
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"tag": "TEXTAREA",
|
||||||
|
"type": "textarea",
|
||||||
|
"value": "",
|
||||||
|
"display": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tag": "INPUT",
|
||||||
|
"type": "text",
|
||||||
|
"value": "",
|
||||||
|
"display": "block"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"logs": [
|
||||||
|
"response: 200 http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"requestfinished: http://127.0.0.1:18082/index.php?r=user/login"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/egret-main-page.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
1
docs/ui-baseline/egret-plant-click-log.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
BIN
docs/ui-baseline/egret-plant-click-p1.png
Normal file
|
After Width: | Height: | Size: 769 KiB |
BIN
docs/ui-baseline/egret-plant-click-p2.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
docs/ui-baseline/egret-plant-click-p3.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
docs/ui-baseline/egret-plant-click-p4.png
Normal file
|
After Width: | Height: | Size: 764 KiB |
BIN
docs/ui-baseline/egret-plant-menu.png
Normal file
|
After Width: | Height: | Size: 769 KiB |
5
docs/ui-baseline/egret-seed-bag-log.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=comm/game-config",
|
||||||
|
"200 http://127.0.0.1:18082/index.php?r=store-house"
|
||||||
|
]
|
||||||
BIN
docs/ui-baseline/egret-seed-bag.png
Normal file
|
After Width: | Height: | Size: 727 KiB |
BIN
docs/ui-baseline/godot-actions-main.png
Normal file
|
After Width: | Height: | Size: 834 KiB |
BIN
docs/ui-baseline/godot-actions-menu.png
Normal file
|
After Width: | Height: | Size: 847 KiB |
BIN
docs/ui-baseline/godot-activity-box.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity-compose.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity-factory.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity-final-box.png
Normal file
|
After Width: | Height: | Size: 418 KiB |
BIN
docs/ui-baseline/godot-activity-final-compose.png
Normal file
|
After Width: | Height: | Size: 593 KiB |
BIN
docs/ui-baseline/godot-activity-final-factory.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
docs/ui-baseline/godot-activity-final-level-gift.png
Normal file
|
After Width: | Height: | Size: 492 KiB |
BIN
docs/ui-baseline/godot-activity-final-log.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
docs/ui-baseline/godot-activity-final-lottery.png
Normal file
|
After Width: | Height: | Size: 549 KiB |
BIN
docs/ui-baseline/godot-activity-final-main.png
Normal file
|
After Width: | Height: | Size: 853 KiB |
BIN
docs/ui-baseline/godot-activity-final-online-gift.png
Normal file
|
After Width: | Height: | Size: 533 KiB |
BIN
docs/ui-baseline/godot-activity-final-pet-display-or-panel.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
docs/ui-baseline/godot-activity-final-sign.png
Normal file
|
After Width: | Height: | Size: 470 KiB |
451
docs/ui-baseline/godot-activity-final-smoke-meta.json
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8792/index.html",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-main.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 8,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"x": 235,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-log.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"x": 560,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-level-gift.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"x": 247,
|
||||||
|
"y": 232,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-factory.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"x": 345,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-compose.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"x": 457,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-lottery.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"x": 560,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-box.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"x": 43,
|
||||||
|
"y": 472,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-sign.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"x": 43,
|
||||||
|
"y": 558,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-online-gift.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"x": 489,
|
||||||
|
"y": 546,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-final-pet-display-or-panel.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 5,
|
||||||
|
"errorCount": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001c9000]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001db600]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001dda00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": "ERROR: The object does not have any 'meta' values with the key 'idle_tween'."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "error",
|
||||||
|
"text": " at: get_meta (core/object/object.cpp:1155)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/godot-activity-final2-log.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
docs/ui-baseline/godot-activity-final2-main.png
Normal file
|
After Width: | Height: | Size: 853 KiB |
BIN
docs/ui-baseline/godot-activity-final2-pet.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
30
docs/ui-baseline/godot-activity-final2-smoke-meta.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"errors": [],
|
||||||
|
"warningsOrErrors": [
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x10c001c8a00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x10c001db600]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x10c001dda00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"errors": [],
|
||||||
|
"warningsOrErrors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet",
|
||||||
|
"errors": [],
|
||||||
|
"warningsOrErrors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
BIN
docs/ui-baseline/godot-activity-level-gift.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity-lottery.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity-main.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity-online-gift.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity-pet-display-or-panel.png
Normal file
|
After Width: | Height: | Size: 735 KiB |
BIN
docs/ui-baseline/godot-activity-sign.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
116
docs/ui-baseline/godot-activity-smoke-meta.json
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8792/index.html",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-main.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-log.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-level-gift.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-factory.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-compose.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-lottery.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-box.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-sign.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-online-gift.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"shot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity-pet-display-or-panel.png",
|
||||||
|
"canvasCount": 1,
|
||||||
|
"canvasBox": {
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/godot-activity2-box.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity2-compose.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity2-factory.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity2-level-gift.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity2-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity2-lottery.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity2-main.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity2-online-gift.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity2-pet-display-or-panel.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity2-sign.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
92
docs/ui-baseline/godot-activity2-smoke-meta.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8792/index.html",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"x": 235,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-log.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"x": 560,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-level-gift.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"x": 247,
|
||||||
|
"y": 232,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-factory.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"x": 345,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-compose.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"x": 457,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-lottery.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"x": 560,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-box.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"x": 43,
|
||||||
|
"y": 226,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-sign.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"x": 43,
|
||||||
|
"y": 312,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-online-gift.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"x": 489,
|
||||||
|
"y": 546,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity2-pet-display-or-panel.png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x104001c9000]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x104001db600]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x104001dda00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/godot-activity3-box.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity3-compose.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity3-factory.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity3-house-click.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity3-land-click.png
Normal file
|
After Width: | Height: | Size: 735 KiB |
BIN
docs/ui-baseline/godot-activity3-level-gift.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity3-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity3-lottery.png
Normal file
|
After Width: | Height: | Size: 399 KiB |
BIN
docs/ui-baseline/godot-activity3-main.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity3-online-gift.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity3-pet-display-or-panel.png
Normal file
|
After Width: | Height: | Size: 735 KiB |
BIN
docs/ui-baseline/godot-activity3-sign.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
371
docs/ui-baseline/godot-activity3-smoke-meta.json
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8792/index.html",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-main.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 6,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"x": 235,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-log.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"x": 560,
|
||||||
|
"y": 145,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-level-gift.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"x": 247,
|
||||||
|
"y": 232,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-factory.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"x": 345,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-compose.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"x": 457,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-lottery.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"x": 560,
|
||||||
|
"y": 235,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-box.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"x": 43,
|
||||||
|
"y": 226,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-sign.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"x": 43,
|
||||||
|
"y": 312,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-online-gift.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"x": 489,
|
||||||
|
"y": 546,
|
||||||
|
"screenshot": "/Users/hy/Documents/farm3/docs/ui-baseline/godot-activity3-pet-display-or-panel.png",
|
||||||
|
"canvasInfo": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960,
|
||||||
|
"clientWidth": 640,
|
||||||
|
"clientHeight": 960
|
||||||
|
},
|
||||||
|
"consoleCount": 3,
|
||||||
|
"errorCount": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001c9000]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001dbc00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "warning",
|
||||||
|
"text": "[.WebGL-0x11c001de000]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "log",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"name": "main",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "log",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "level-gift",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "factory",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "compose",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lottery",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "box",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sign",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "online-gift",
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pet-display-or-panel",
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
docs/ui-baseline/godot-activity4-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity5-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity6-log.png
Normal file
|
After Width: | Height: | Size: 844 KiB |
BIN
docs/ui-baseline/godot-activity7-log.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
docs/ui-baseline/godot-after-bug-clean.png
Normal file
|
After Width: | Height: | Size: 834 KiB |
BIN
docs/ui-baseline/godot-after-clear.png
Normal file
|
After Width: | Height: | Size: 827 KiB |
BIN
docs/ui-baseline/godot-after-fertilize.png
Normal file
|
After Width: | Height: | Size: 834 KiB |
BIN
docs/ui-baseline/godot-after-grass-clean.png
Normal file
|
After Width: | Height: | Size: 833 KiB |
BIN
docs/ui-baseline/godot-after-harvest.png
Normal file
|
After Width: | Height: | Size: 830 KiB |
BIN
docs/ui-baseline/godot-after-sow.png
Normal file
|
After Width: | Height: | Size: 832 KiB |
BIN
docs/ui-baseline/godot-all-green-icons-main.png
Normal file
|
After Width: | Height: | Size: 846 KiB |
42
docs/ui-baseline/godot-all-green-icons-meta.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "[.WebGL-0x134001c9c00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "Godot Engine v4.6.2.stable.official.71f334935 - https://godotengine.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "OpenGL API OpenGL ES 3.0 (WebGL 2.0 (OpenGL ES 3.0 Chromium)) - Compatibility - Using Device: WebKit - WebKit WebGL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "Build configuration: Emscripten 4.0.20, single-threaded, no GDExtension support."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "[.WebGL-0x134001dce00]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "console",
|
||||||
|
"text": "[.WebGL-0x134001df200]GL Driver Message (OpenGL, Performance, GL_CLOSE_PATH_NV, High): GPU stall due to ReadPixels (this message will no longer repeat)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=user/login",
|
||||||
|
"status": 200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "response",
|
||||||
|
"url": "http://127.0.0.1:18082/index.php?r=store-house",
|
||||||
|
"status": 200
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"width": 640,
|
||||||
|
"height": 960
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 844 KiB |