This commit is contained in:
2026-09-22 17:45:29 +08:00
parent 2ecab991f8
commit b11da48e23
8 changed files with 328 additions and 197 deletions
+53
View File
@@ -51,6 +51,59 @@
GDScript 对动态成员访问极其宽容(`Node` 上调脚本方法、`Node3D.new()` 设脚本属性都不报错),
所以「编译通过」不等于「语义正确」,逻辑对错还得靠人读。
### UI 改为节点配置(用户要求:不要代码生成 UI)
- 新增 `autoload/net.tscn`(根 `Net` 是 CanvasLayer,layer=20):
`Menu`(CenterContainer→PanelContainer→VBox: Title/AddressEdit/HostButton/JoinButton/StatusLabel/HintLabel)
+ `Hud`(Control→VBox: StatusLabel/HintLabel)。两个按钮的 `pressed` 在 .tscn 里连接到 `Net`。
- `autoload/net.gd` 重写:`extends CanvasLayer`,删掉全部 `_build_*`,改为 `@onready` 节点引用 + 状态更新
(`_on_host_button_pressed` / `_on_join_button_pressed` 由场景信号触发)。
- **`project.godot` 的 autoload 改成指向场景**:`Net="*res://autoload/net.tscn"`(原来指向 net.gd)。
这样 `Net` 这个全局名就是那个 CanvasLayer 根节点,`/root/Net` 路径不变,`main.gd`/`player.gd` 无需改动。
- 建场景的做法:`scene_manage(create)` → `batch_execute`(13 个 create_node) → `batch_execute`(29 个 set_property,`undo=false`)
→ `signal_manage(connect)` ×2 → `script_attach` → `scene_save`。Godot 自己序列化,比手写 .tscn 可靠。
- 验证:双实例 headless 联调通过(主机/客户端各自一个「本地操控」,日志镜像);编辑器内运行零报错。
- 文档同步:`联机框架使用指南.md` 文件地图;`联机实战教程-由浅入深.md` 关卡 3 / 关卡 9 改成「在编辑器加节点」写法。
### 玩家的 UI 也改成节点配置(同一轮完成)
- `player.tscn` 新增 `Hud (CanvasLayer)` → `HealthLabel (Label)`(位置 16,56)。
- `player.gd`:删掉 `_make_health_label()`(原来用代码建 CanvasLayer + Label),
改为 `@onready var _hud: CanvasLayer = $Hud` / `@onready var _health_label: Label = $Hud/HealthLabel`;
远端分支加 `_hud.visible = false`(否则 N 份血条叠在同一屏幕坐标,显示的是别人的血量);
本地分支末尾补 `_refresh_health_label()`(`@onready` 赋值晚于同步写入,那次 setter 会被 null 判断跳过)。
- `_report_identity()` 详细自检已恢复。
- 确认 `player_sync.tres` 现在有 3 个字段:`.:position`、`Body:rotation`、`.:health`(用户自己加的,正确)。
- 文档同步:`联机实战教程-由浅入深.md` 关卡 1 改成「先在 player.tscn 里加 Hud/HealthLabel 节点」;
`联机框架使用指南.md` 的 player.tscn 结构图。
### 反复出现的坑:编辑器把外部写盘的内容覆盖回去
`net.gd` 用 MCP `script_create` 写成功后,磁盘上又变回了旧版(`extends Node` + `_build_ui` 全在)。
原因:编辑器的**脚本编辑器标签页里缓存着旧文本**,资源 reload ≠ 标签页文本刷新,
之后一次保存就把旧文本写回去了。而且工具返回的 `reloaded: true` 会让人误以为已经生效。
**规避办法**:
1. 每次写完立刻从磁盘回读校验(Grep/Read 关键行),别信工具的 `reloaded`。
2. 改 Godot 项目里的脚本/场景一律走 godot-ai MCP,不要用外部写盘。
3. 交付时提醒用户:如果编辑器标签页里还是旧内容,关掉标签页重开(或重启编辑器),
并且在确认内容更新之前不要按 Ctrl+S。
`net.gd` 一共被还原了**两次**(第二次在 17:41~17:43 之间,导致 `git status` 里
`autoload/net.gd` 一度没有差异)。第二次修复后连续观察 30 秒无变化才确认落地。
排查时用:读文件首行 + 查 `_build_ui` + 看 size/mtime,隔一段时间对比。
### 仓库状态(供用户查证)
- `.gitignore` 只忽略 `.godot/` 和 `/android/`,业务文件不会被忽略。
- 最后一个提交是 `2ecab99`(17:32「扣血同步」,用户的关卡 1);此后所有改动**都还没提交**,
且 `origin/master...master` = `0 0`,即**一个都没推送**。
- 未提交清单:`autoload/net.gd`(-121 行)、`player/player.gd`、`player/player.tscn`、
`project.godot`、两份 docs、`.workbuddy/memory/...`;**`autoload/net.tscn` 是 untracked(新文件)**。
- 用户说「git 上看不到差异」,很可能是因为:① 看的是远端网页(没推送);
② GUI 客户端默认不显示 untracked 文件,而 `autoload/net.tscn` 正是新文件。
### godot-ai MCP 使用注意(重要)