Files
gplan-2/tools/godot_user_dir.py
DKChan 8bfd249402 工程(user目录隔离): 每个代码面 worktree 独立 Godot user 目录+系统测试 V3d 缺帧修正
- 机制: tools/setup_worktree_userdir.sh 在建区后生成 game/override.cfg(use_custom_user_dir + 唯一名 DungeonSweeper_<区名>_<绝对路径 sha1 前 8>), 主工作区 no-op 保持真实档原位; .gitignore 收 game/override.cfg
- 闸壳: run_all_gates.sh 参数解析后先自检/自愈本区隔离, 建不起来 exit 1(fail-closed)——并行批共用一套夹具/日志/截图目录会互相踩盘, 是假红的根源
- 读取面: 新增 tools/godot_user_dir.py 统一解析(有 override→custom dir, 无→默认 appdata/Godot/app_userdata/<config/name>); parity_anchor.py 与 analyze_playtest.py 的硬编码 APPDATA 路径改为调用它
- 流程: process-conventions §1 第 1 条(建区即跑 setup)与 §3 环境基线第 4 条(闸壳自检); iter 技能冷检出三件套→四件套(.zcode/.qoder 两份本机副本已同步, 不入 git)
- 系统测试 V3d: 隔离后空 user 目录(无 settings.cfg)使 reduced_motion 取默认 false, 实查暴露 V3d 真实缺陷——测试同步驱动整场战斗后同帧 flush, RowPacer._was_pumping 从未置真, 演播后排窗的 pump_ended 边沿不触发, _end_overlay 永不打开; 旧绿只因本机 settings.cfg reduced=true 让排播走 consume_now 快路绕过队列。补一帧 await process_frame 让泵先观测到非空队列再 flush, 恢复真实边沿路径
- 取证: 隔离空目录下 00 冒烟 17/17、02 单元与集成 62 套全绿、03 探针 --click 全绿; 01 系统测试修正前 70/1 红(仅 V3d)、修正后 reduced=true 与 false 两档均 70/70 绿
2026-10-27 05:23:13 +08:00

27 lines
1.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""解析 Godot 的 user:// 根目录——与 game/override.cfg 的隔离口径同一份。
无 override.cfg(主工作区)→ %APPDATA%/Godot/app_userdata/<project.godot 的 config/name>;
有 override.cfg(代码面 worktree,由 tools/setup_worktree_userdir.sh 生成)→ %APPDATA%/<custom_user_dir_name>。
"""
import os
import re
from pathlib import Path
def _project_name(repo_root: Path) -> str:
text = (Path(repo_root) / "game" / "project.godot").read_text(encoding="utf-8", errors="replace")
m = re.search(r'^config/name="([^"]*)"', text, re.M)
return m.group(1) if m else "DungeonSweeperVerticalSlice"
def resolve_user_dir(repo_root: Path) -> Path:
base = Path(os.environ.get("APPDATA") or (Path.home() / "AppData" / "Roaming"))
override = Path(repo_root) / "game" / "override.cfg"
if override.is_file():
text = override.read_text(encoding="utf-8", errors="replace")
custom = re.search(r'^config/use_custom_user_dir=true\s*$', text, re.M)
name = re.search(r'^config/custom_user_dir_name="([^"]*)"', text, re.M)
if custom and name and name.group(1):
return base / name.group(1)
return base / "Godot" / "app_userdata" / _project_name(Path(repo_root))