DESIGN.md@tools/readme_art · git:20261012.ecb73f7 · 2026-10-12 · sha256 205e7f79fe5eb404

DESIGN.md@tools/readme_art git:20261012.ecb73f7A

Immutable. This exact content never changes and is served at /api/v1/blob/205e7f79fe5eb404.

# README 图片:设计规范与制作流程

本目录生成仓库首页 `README.md` 用到的 8 张图,输出到 `.github/readme-lofi/`。这里记录风格规范、各张图的版式、动效、文案规矩和改图流程,供以后改图时对照。

这些是开发工具,不进 Skill 发布包;运行时仍然只用 Python 标准库。

## 1. 文件

| 文件 | 作用 |
|---|---|
| `source/bedroom.webp` | 用户提供的像素风黄昏卧室图(2000×778),所有图的素材来源 |
| `readme_overlay.py` | 生成首图 `hero.svg`:原图 + 标题 + 像素标语 + 动效 + 卖点条 + 三栏特性 |
| `overlay_fx.py` | 首图的动效图层(楼灯、霓虹、闹钟、屏幕、浮尘、音符)和标题、标语的时间轴 |
| `pxtext.py` | 像素中文字:用系统字体按 1 位点阵渲染,再合并成 SVG 方块路径 |
| `readme_px_room.py` | 早期手绘卧室首图的脚本。现在只借用其中的卖点条和三栏特性代码(`readme_overlay.py` 截取并执行),单独运行时输出到 `reports/tmp/readme_art/`,不会覆盖正式图 |
| `lofi_set.py` | 生成其余的图:5 张分区横幅、软木板世界墙 `worlds.svg`、磁带架 `inventory.svg`、世界库合图 `world-library.svg`、架构图 `architecture.svg` |
| `pixkit.py` | 像素画布、抖动、渐变、SVG 外壳等公共工具 |

`lofi_set.py` 里的 `v_proof`、`v_why` 等函数是旧版手绘横幅插画,现在的横幅改用原图局部,这些函数已不调用。

## 2. 重新生成

需要 Python 3.10+ 和 Pillow(只在开发机上用),字体用 Windows 自带的微软雅黑粗体 `msyhbd.ttc`。

```bash
export PYTHONPYCACHEPREFIX=.pycache PYTHONIOENCODING=utf-8
python tools/readme_art/readme_overlay.py
python tools/readme_art/lofi_set.py
```

两个脚本的输出是确定的(随机数都用固定种子)。改脚本之前先跑一遍,用 `git status .github/readme-lofi` 确认没有差异,再动手改。

## 3. 总体原则

- **原图只裁不改**:用户的卧室图原样嵌入(base64 webp)。字、光、动效都是叠在上面的 SVG 图层。横幅和磁带架的窗景是原图裁出来的局部,裁片用无损 webp 编码,并用 `image-rendering:pixelated` 保持像素锐利。
- **一套配色**:所有图共用首图的“紫光 + 灰字”配色,不再出现金、黄、青这类高饱和色。
- **背景**:所有图都用同一种黄昏渐变背景(用户 2026-10-04 从三个方案里选定,替换了原来的竖条纹墙纸)。脚本保留 `README_BG=wall`(竖条纹)和 `README_BG=mosaic`(原图马赛克)两个备选,配合 `README_OUT=<目录>` 输出到别处做对比。
- **像素一致**:线条、分隔线都用 2px 像素点阵,不用平滑细线。
- **动效克制**:只用 SMIL(`<animate>`、`<animateTransform>`),因为 GitHub 用 `<img>` 显示 SVG 时只有 SMIL 能播。循环要慢、彼此错开,不能大面积闪烁。
- **单张体积**:首图约 300 KB,其余每张 70–130 KB,全套约 1 MB。

## 4. 配色

| 用途 | 颜色 |
|---|---|
| 大标题字芯 | `#ecebef` |
| 大标题描边与光晕 | `#a29dab` |
| 大标题投影(右下偏移约 size/16 像素) | `#4e4a56` |
| 副标题 | `#c4bfcc` |
| 紫光(氛围光、18+ 徽章) | `#a874ff` |
| 点阵线渐变 | `#a874ff` → `#ff6fae` → `#a874ff` |
| 串灯 | `#c9a2ff`、`#ff8fc4`、`#e9dcff` |
| 背景(黄昏渐变) | 自上而下 `#110d22` `#181130` `#21153c` `#2c1946` `#391c4c` `#461e4e` `#542150`,8px 一格的 4×4 Bayer 抖动过渡;上方三分之二撒少量 4px 星星 `#e9dcff`,2.5–5 秒明灭 |
| 软木板分类条(偏灰紫) | `#8c7a9e`、`#9a7394`、`#6f78a0`、`#8579b0`、`#76708e` |
| 磁带外壳(低饱和) | `#8e5f78`、`#4f6f80`、`#8a7550`、`#6a6290`、`#87574f`、`#5d7258`、`#82607e`、`#55628a`、`#8a6a58`、`#56786f` |
| 磁带标签 | 底 `#221c28`,数字白色,说明 `#c4bfcc` |

首图卖点条:18+ 徽章与边框为紫色,“尺度全开”等字为浅灰 `#ebe8ef`,光晕灰 `#a39dad`,分隔圆点 `#c4bfcc`;三栏图标整体透明度 0.8。

## 5. 字体

- 标题与正文用系统无衬线字体栈:`-apple-system, Segoe UI, PingFang SC, Microsoft YaHei`,字重 800。
- 首图英文名 `ADULT TENSION` 用 Arial Black,54px,黑字 `#0b0710` 配浅粉描边 `#ffe3f0`(5px,描边在下)。
- 首图标语是“漫画像素字”:微软雅黑粗体 14px,1 位点阵渲染后放大 2 倍,白字,只加柔和阴影,不加描边(描边版被否掉了)。

## 6. 各图版式

### 首图 `hero.svg`(1280×710)

- 上部是原图,缩放到 1280 宽。
- 人物右侧的窗上是黑色 `ADULT TENSION`,两行居中,x≈1300×缩放比。
- 人物左侧床头上方是两行像素标语“专为高张力、强连续性 / 成人互动叙事打造”,第二行缩进 1 字。
- 图下是卖点条:顶边是 2px 紫粉点阵线(下面两行逐级变淡的抖动点),右侧有点阵分隔线,每 7 秒一道淡光扫过。
- 卖点条下方是三栏特性:活人感 NPC、数百个深度世界、自运行状态机,分隔线也是点阵。

### 分区横幅 `section-*.svg`(1200×176)

- 左侧 440px 是原图局部,从 72% 处开始向右淡出到墙面。
- 右侧是标题(46px)和副标题(20px),都右对齐,距右边约 48px。
- 背后有一团淡紫光,顶边是点阵线加一道每 6 秒扫过的高光,五张错开起点。所有图都不挂串灯(用户 2026-10-04 要求去掉)。

| 横幅 | 标题 / 副标题 | 原图裁切框 | 画面 |
|---|---|---|---|
| `section-worlds` | 内置世界库 / 跨时代独立世界框架和上千项素材 | (990,0,1390,168) | 窗外城市 |
| `section-proof` | 体验切片 / 真实会话交付实录 | (1180,222,1490,352) | 显示器 |
| `section-why` | 为什么不会崩盘 / 模型写故事,本地引擎守事实 | (70,300,470,468) | 闹钟和书桌 |
| `section-start` | 怎么开始 / 不用记语法,直接说大白话 | (610,190,1050,375) | 抱吉他的人物 |
| `section-install` | 安装 / 只需交给 AI 操作,原生 SKILL | (1440,280,1800,431) | 笔记本 |

### 世界墙 `worlds.svg`(1200×2464)

- 标题“211 个世界”(实际世界数)居中,副标题“选一个直接开局,或者说‘自定义世界’当场写一个”。
- 软木板分七栏:历史风云、都市暗流、当代市井、职场百态、聚光灯下、科幻与极限、异界幻想。每栏是一张分类条(写着栏名和世界数)加若干单行便签,一个世界一张;标题的世界数按 `REGIONS` 自动统计。新世界要加进某一栏,便签上用 README 速览表里的短名(过长的可在板上再缩短)。
- 世界全部是正式发布,便签上的粉色图钉表示已开放(每三颗有一颗呼吸发光,免得动画太多);图例只有一条“全部已开放,可直接开局”。

### 世界库合图 `world-library.svg`(1200×3152)

README 实际用的是这张:`section-worlds`、`worlds`、`inventory` 三张从上到下拼成一张,共用一面墙、一个圆角外框和一层暗角;横幅左侧的原图裁片在底边 60px 内淡入背景,所以三段之间没有缝。三张单图仍会生成,只作为拼图的零件。

### 磁带架 `inventory.svg`(1200×512)

- 标题“两千余项素材”左对齐,副标题“地点、人物、钩子和规矩,每次开局都从同一个世界里组合”。
- 两层木架,每层 5 盒磁带,标签上是素材数量和类别。
- 右上角的窗景是原图裁片 (1410,0,1710,95)。

### 架构图 `architecture.svg`(1200×912)

- 标题“SKILL架构”居中,副标题“无需理会,当正常SKILL使用就行”。
- 三种卡片:米色便签纸是运行时以外的东西(玩家、宿主、`SKILL.md`、`tools/`、`content-src/`),紫灰面板是运行时的六层,青灰面板是数据(用户数据目录、编译好的世界包)。左侧色条分别是粉、紫、青,左下角有图例。
- 六层装在一个带螺丝的机箱里,机箱顶上贴着“runtime/ · 只用 Python 标准库”的胶带。右侧黄便签写三条保证:一回合 = 一次事务、重试不会重复推进、同一种子同一结果。
- 连线是 1 格宽的像素线加像素箭头,每条线上有一个发光小方块沿箭头方向循环移动;通往数据的两条线是青色,其余灰白。
- 内容和代码对应:层名就是 `runtime/adult_tension/` 下的包名。层次或数据流变了要同步改图。

## 7. 动效

首图的标题和标语共用 16 秒一轮:

| 元素 | 动作 |
|---|---|
| ADULT TENSION | 0.3 秒起逐字点亮(每字间隔 0.09 秒),约 9 秒时第 3、10 个字母闪一下,15.6 秒全部暗回 0.15 |
| 像素标语 | 2 秒起逐字打出(每字 0.12 秒),15.6 秒清空 |
| 窗外楼灯 | 约 30 处亮块随机明灭 |
| 霓虹招牌 | 5 处光晕呼吸,偶尔断电闪一下 |
| 闹钟 | 秒位 10 秒一轮、十位 60 秒一轮,冒号闪烁 |
| 显示器 / 笔记本 | 显示器微光起伏加扫描线;笔记本屏幕上 12 根柱子上下跳 |
| 浮尘、音符 | 16 粒细尘漂浮;吉他上飘出 3 个像素音符 |
| 三栏图标 | NPC 4.6 秒眨一次眼,地球 3.2 秒转一圈(4 帧),齿轮 12 秒转一圈 |

其余图:标题每 6 秒偶尔闪一下(降到 0.55 再回来);点阵线上有高光扫过;世界墙的图钉微光呼吸;磁带轮转动;架构图的连线上有数据方块流动。

已知问题:不播动画的地方(例如部分 Markdown 预览器),首图会停在第一帧,标题只有 0.15 的亮度,标语看不见。修法是把默认状态改成“全亮”,动画从全亮开始暗下再点亮。

## 8. 文案规矩

- 世界墙标题写实际世界数(由 `REGIONS` 统计),其他地方写“数百个世界”这类说法。
- 不写“破甲”一类说法。
- 素材数量都是下限(写成“160+”这类)。
- 只引用真实试玩记录里的原话。
- 图里出现的菜单项、命令必须是真实存在的命令。

## 9. 改图流程

1. 改脚本,跑生成命令。
2. 把图复制到 `reports/tmp/` 下的临时页面,起本地静态服务器,在浏览器里逐张查看,必要时放大细节。看完删掉临时页面。
3. 整页效果用审阅稿(模拟 GitHub README 的 HTML 页面)给用户看,用户确认后再改 `README.md`。
4. 提交前先扫描密钥;推送前扫描全部历史。每次推送都要用户明确同意。

## 10. 版权提醒

原图显示器和墙上海报里的角色像同人图,首图和“体验切片”横幅都能看到。公开使用前要确认使用权,没有的话就换掉或打码。