godofcong-1/erark/draw-aa-map
Claude Code and agent skill by godofcong-1/erark
- community
Checking that the SKILL.md file is still in the repository.
创建或调整 erArk 的 AA 地图(data/map/*/Map),包括给区块新增房间、重排整张版面、修正竖墙错位。当需要画地图/改地图/加房间,或玩家反馈地图显示歪掉、排版错乱时使用。
Install
npx vskill@latest install godofcong-1/erark/draw-aa-mapSKILL.md
Skill Instructions
你是 erArk 的 AA 地图排版助手。完整原理说明见 地图系统 的「AA 地图排版」一节。
第零步:先记住这条铁律
AA 地图的排版由字体的实际字宽决定,不是由 `wcwidth.wcswidth` 决定。
MapDrawLine.width 走 Script/Core/text_handle.py:65 get_text_index()(即 wcswidth),但它不参与行内排版。see_map_panel.py:97-109 只用全局 max_width 算出一个所有行共用的居中空格前缀,之后逐段原样输出,不做任何裁剪或补齐。因此行内对齐 100% 由字体字宽决定。
永远不要用"数列数"的方式判断对齐——这正是历史上重画后实机仍然歪掉的原因。必须用 tools/map_aa_check.py 按像素校验。
核心模型:U 单位
在 等距更纱黑体 SC 下字符分成两个互不通约的度量族:
| 度量族 | 代表字符 | 字号 20 下 | |
|---|---|---|---|
| 框线族 | ═ ║ │ ┃ ┄ ┅ ┆ ┇ ─ ━、▓ ♂ ♀ ¤ ▁、U+2002 | 13 px | |
| 框线族(全角) | 汉字、○ ● □ ▣ ♲ ◎ ◇、- ~ ← → ↗ ↘ | 26 px | |
| ASCII 族 | ASCII 空格、~、-、数字、字母 | 14 px | |
| ASCII 族(双宽) | ☸ ➷ ➹ ✪ | 28 px |
两族在字号 18/22/24/26/30 下碰巧同宽,在 14/16/20/40 下不同宽。当前 config.ini 反算出的字号正好是 20(font_size = int(window_width / text_width) * 2 = int(2000/190)*2),所以每出现一个 ASCII 空格就相对框线漂移 1px。
令 U = 框线字符宽度,只用恒为 1U / 2U 的字符即可在任意字号下对齐:
| 宽度 | 可用字符 | |
|---|---|---|
| 1U | 框线 ═ ║ │ ┃ ┄ ┅ ┆ ┇ ─ ━、▓ ♂ ♀ ¤ ▁、U+2002 EN SPACE(留白)、≈ ∼ ∽ ⊙ ⊕ | |
| 2U | 汉字、○ ● □ ▣ ♲ ◎ ◉ ◍ ◇ ◈、~ 〜 ﹏ ⌒、← → ↗ ↘ ↖ ↙、- _ < >、U+3000 | |
| 禁用 | ASCII 空格、~、-、数字字母、☸ ➷ ➹ ✪ |
留白一律用 U+2002 EN SPACE 替代 ASCII 空格,这是消除大范围错位的关键。
U+2002 与普通空格肉眼完全一样,手抄/复制粘贴极易被静默换回 ASCII 空格。因此这类地图必须由脚本生成,绝不可手改 `Map` 文件。
实施步骤
第一步:摸清现状
同时读一遍目标 data/map/<区块>/Map 与 Map.json,弄清现有房间的相对位置与连通关系。参考画得比较规整的 data/map/仓储/Map、data/map/疗养庭院/Map。
第二步:设计列规划(用 U 数,不是字符数)
先把版面写成一张列规划表再动手,例如:
要点:
- 上下排尽量共用竖墙列位,观感更整齐。
- 每个房间格的内容宽度 = 该格的 U 数;汉字算 2U,框线/留白算 1U。
- 门(可通行)用虚线
┄/┆,实墙用═/║,必须与 `Map.json` 的 `PathEdge` 一致。 - 总宽必须 ≤
text_width(190),否则 Tk 会按字符软换行、整张图崩坏。
第三步:写生成脚本
不要手写 `Map` 文件。 以 tools/map_aa_build_training.py 为模板新建生成脚本,按 U 数拼装:
脚本必须在写入前自检三件事,任一不满足就报错退出、不写文件:
- 每个含竖墙的行 U 数一致
- 全图不含 ASCII 空格
- 不含裸
<...>(会被富文本正则吞掉)
文件格式:UTF-8 无 BOM + CRLF + 末尾无换行。
第四步:像素校验(必做)
它会在 10 个字号下逐字符累加像素位置,检查各竖墙行的总宽与每堵墙的位置是否一致,超差会指出具体哪行哪堵墙差多少,并以非零退出码结束。
期望:每个字号下含竖墙的行总宽只有一个值。
第五步:若同时新增了场景,补两个数据文件
- 新建
data/map/<区块>/<房间名>/Scene.json——照抄同类场景,字段含义见地图系统.md。目录名必须与<mapbutton>里的名字完全一致,否则map_handle.py:363会无限递归抛RecursionError。 data/map/<区块>/Map.json的PathEdge加双向边。
通常不需要改任何 CSV、po 或 Python:constant.place_data 由 SceneTag 自动生成。
第六步:重建缓存(必做,否则改动 100% 不生效)
map_config.init_map_data() 只判断四个缓存文件是否全部存在,没有任何 mtime/hash 校验,不删缓存就完全不生效且无任何报错:
第二层缓存:save_handle.py:496-516只在场景增删或scene_tag/scene_img/room_area变化时才刷新存档里的map_data。只改 AA 图而不动 `Scene.json` 时,老存档读出来仍是旧地图,必须用新档验证。
第七步:收尾
update.log加一行(新增房间记「新增:(地图)…」,重排版面记「调整:(地图)…」)- 若改动较大,在
plan/下留实施记录,可参考plan/done/plan_01_训练场新增休息室.md
陷阱速查
| 陷阱 | 依据 | |
|---|---|---|
<mapbutton> 标签零宽,只有中间的名字参与排版 | map_config.py:199 | |
行尾空白被 str.rstrip() 吃掉,包括 U+2002——别靠行尾补齐 | map_config.py:243 | |
行首公共空格被裁,但只认 ASCII 空格(lstrip(" ")),U+2002 不受影响 | map_config.py:246 | |
裸 <...> 会被 re.sub(r"<[^>]+>","") 静默吞掉;要画尖括号用全角 <> | rich_text.py:233 | |
未闭合的 <mapbutton> 会让该按钮及本行后续文本静默丢失 | map_config.py:203 | |
按钮名 ≠ 子目录名 → RecursionError,不是友好报错 | map_handle.py:363 | |
有 Map.json 就必须有同目录 Map,否则 FileNotFoundError | map_config.py:90 | |
_pad_map_lines_to_max_width() 是死代码,从未被调用 | map_config.py:345 |
常见取舍
- 想保留某个 ASCII 族字符(如
➷➹的观感):可以,但要把它放在最右侧的格子里,这样左侧所有竖墙不受影响,只有该行最右端偏移 2px;然后用--tol 2校验并在文档里写明确切代价。 - 场景名是数字(如入口
0):无法改(是目录名)。把它放在没有竖墙的标签行上即可,不产生可见错位。 - 想给新房间加等级门禁:
Facility_open.csv是按 `SceneName` 匹配的,加进去会连坐所有同名场景(项目里有 9 个"休息室")。需要单独门禁必须起独立SceneName。
完成前自查
- [ ]
tools/map_aa_check.py <地图名>通过(或在已知容差内通过,且代价已写进文档) - [ ] 全图无 ASCII 空格
- [ ] 每个
<mapbutton>的名字都能对应到同级子目录 - [ ]
Map.json的PathEdge与 AA 图上画的门一一对应,且是双向边 - [ ] 四个缓存已删除并重建,
init_data.py无报错 - [ ] 生成脚本已保留在
tools/下,便于以后再改
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryChecking.github/skills/draw-aa-map/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/godofcong-1/erark/draw-aa-map)