work-making-of
Official neta-search/work-making-of
Use it in Cohub
Paste this into your agent's chat — it fetches the skill and follows it.
Use the skill: work-making-of. Run `npx -y @neta-art/neta-search-cli@latest skills use neta-search/work-making-of --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.copy
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use neta-search/work-making-ofcopy
Summary
Turn your creation process into a video that shows the conversation, the drafts, and what changed.
Works from your chat history: each line you typed appears on screen, then the images or versions it generated fall onto a board. Shows what went wrong and how you fixed it: rejected drafts marked with ✗, new versions side by side with old ones, zoomed in to see the difference. Two formats: video works become a card-pulling reveal (flip 3 cards per round, circle the problem, show the final cut at the end). Web apps get a board with comparisons and a playable demo. Works best when the chat is still in the world and the work went through visible changes: early drafts that didn't work, revisions, multiple published versions. Delivers a finished video and a poster showing every step laid out. No new images generated; it only uses what you already made.
SKILL.md
# 作品创作过程片(Work Replay)
## 开工规矩(先读,两条路都适用)
**不问,直接做。** 不弹问卷、不跑 questionnaire skill、不用文字摆 A/B/C 让用户挑。片长、讲几轮、用什么当「原话」,都按本文件和 guide 自己定,交付时一句话说明你是怎么定的。
**唯一可以停下来问的情况**:用户点名的作品,在这个世界里(加上用户给的链接)既找不到作品本身,也找不到它的任何产物。这时用一句话问作品名或 Chat 链接,然后结束这一轮;不拉素材、不渲染。
**找不到原话时,按顺序往下取,不要问:**
1. 生成它的 Chat 在 → 用用户原话(正常流程)。
2. Chat 不在、拉不到,但产物在(作品记录 `works/<id>.json` 里的 `content` 就是生成提示词,`pull-assets.py` 会自动带上;旧格式世界是 `artifacts/media/*.json` 里的 `prompt`;或作品发布过版本)→ 每一拍打出**这件产物自己的生成提示词**:一字不改,太长只能用……截断;用「手写一拍」(`guide/story-json.md`)写 `say`,`who` 写「生成提示词」,不冒充用户原话。按创建时间排;有 V1→V2 改版照常做对比。
3. 连提示词也没有的产物(世界创建时导入的素材、上传的图)→ 用它自己的标题(作品名、素材名)当这一拍的字,`who` 写「素材」,按创建时间排。
4. 始终做**用户点名的那件作品**。不换成世界里别的作品,也不为了「有过程可讲」先把作品重做一遍。
走了 2 或 3 时,交付时说一句:「这件作品的对话不在这个世界里,片子里打出来的是每件产物真正的生成提示词 / 标题。」
**片子语言跟用户走**:用户用什么语言跟你说话,片子上的字就用什么语言——英文用户(例如开场句是英文)就全片英文。开工命令带 `--lang en`(`gacha-start.sh` / `gacha-draft.py` / `draft.py`),gacha.json / story.json 里会写好 `"lang": "en"`,渲染器的界面字(牌库、按键、星级、卡背、印章、画板件数、时间……)随之换成英文;你写的标题、轮名、提示、字幕、标签、片尾也全用英文。**原话照原样,不翻译**。check / build 在 `lang: en` 时见到你写的字里有汉字会直接拦下。
**明确不做**:
- 不重做、改写、重新发布原作品——过程片只讲已经发生过的事
- 不删开工前就有的文件(包括原作品目录里的文件),只在自己的 `$P` 目录里写东西
- 不改世界设定(`world/WORLD.md` 的 frontmatter,不跑 `neta config set`;旧格式世界是 `manifest.worldConfig`)
- 不为凑画面生成新图
**交付用交接卡**:照 interaction-components skill 的 Link 写法发卡,正文里不要再贴同一个链接。成片一张卡、总览图一张卡;`target` 用 `{"type":"external-url","url":"<publish.sh 打印的 ✓ 那个地址>"}`,`presentation.name` 写「《作品名》· 创作过程片」/「《作品名》· 总览图」。只用这一轮工具真打印出来的地址,不要自己拼。
## 先分路(第一件事)
| 作品是什么 | 走哪条 | 读什么 |
|---|---|---|
| **一段一段生成的视频**(Chat 里助手发的是 mp4) | **抽卡版** | `guide/gacha.md`,照 9 步做;范例 `examples/video-gacha*/` |
| 网页、游戏、互动作品、工具 | 画板版 | 本文件下面的「步骤」+ `guide/fun.md` |
抽卡版是最新、用户确认过的做法;下面「画板版」的内容**不适用于视频作品**。
## 抽卡版速查(细节、完成标志都在 `guide/gacha.md`)
**怎么判断**:作品是一段一段**生成的视频**(Chat 里助手发的是 mp4),就走抽卡;网页 / 游戏 / 工具走下面的画板流程。
抽卡版 = 每生成一次视频算抽一张牌,3 轮 × 3 张翻牌 + 结尾完整放成片,90~130 秒。命令一览(细节和完成标志在 gacha.md):
```bash
bash $SK/scripts/gacha-start.sh <spaceId> <sessionId> $P --lang en|zh # 1~4 环境 + 拉每一抽 + 起草 gacha.json + 圈框总图(2 分钟)
# 5 读 src/takes.json 的文字 + 1~2 张看片图,整份写好 gacha.json
python3 $SK/scripts/gacha-ring.py $P --set "13:box=…" --set … # 读 rings 总图,一条命令改完不对的框
python3 $SK/scripts/gacha-check.py $P # 6 检查,⚠ 也改完
bash $SK/scripts/gacha.sh $P ; bash $SK/scripts/gacha.sh $P --status # 8 后台渲染(3~4 分钟,自动出总览图)
```
目标:10 分钟内出片。
最容易犯的错:
1. **框和原话对不上**:每个圈写 `hl`(原话里的原样片段),不圈自己看出来的问题;`t` 从 segs 起点算;先看冻结帧再量框;声音类问题不圈
2. **原话截断或改字**(check 会拦)
3. **片尾讲成制作账**:片尾只放「一句话讲作品 +《作品名》」,「抽了几次」只在开头规则卡里说
4. **结尾成片太碎**:收下的段从头放到尾(默认 `full`),不要拼 12 秒剪辑
5. **不要做快进**:没进 3 轮的抽直接不出现
6. **节奏太快**:用户两次说过太快
7. **片子语言和用户不一致**:英文用户却出了满屏「生成牌库 / 再抽一手 / 稀有」——开工没带 `--lang en`
---
# 画板版(网页 / 游戏 / 工具)
**观众看完要感觉到**:这个作品是一句一句话聊出来的,中间卡住过、来回改过,作品本身一直在变,最后真的成了、能玩。
**最容易做坏的方式**:平铺。一拍落一批图,一拍又落一批,镜头一直很远,每张图都看不清,也看不出改了什么。这样的片子是流水账。
所以这个 skill 有两层:
- **画板层**:东西越堆越多(落下、✗、✓、件数涨)。这是“量”。
- **屏幕层**:盖在画板上,让人**看清楚**——特写、改前改后对比、作品试玩、章节卡。这是“质”。
`$SK` = 本文件所在目录。用到时再读:
- `$SK/guide/fun.md`:**编排**(镜头怎么配、三幕怎么分、节奏)和怎么挑好玩的拍。写 story.json 之前必读
- `$SK/guide/gacha.md`:**视频作品走这条**——把「每生成一次视频」做成抽一张牌,3 轮 + 成片收尾
- `$SK/guide/story-json.md`:story.json 每个字段
- `$SK/guide/style.md`:配色和字体怎么跟着作品走
## 核心:每一拍 = 一句原话 + 这句话真正生成的产物 + 一个镜头
工具会查每件产物是**哪一轮对话生成的**,作品的每个版本是**哪一轮发布的**。所以一拍只要写:
```json
{"turn": "#4.8", "title": "样稿", "reject": "#4.7"}
```
输入框打出 #4.8 这句原话 → 落下这一轮生成的图 → #4.7 那一批打 ✗ → **自动把 #4.7 和 #4.8 并排放大对比** → 如果这一轮发布了新版本,画框和右上角小窗自动换成新版本。
镜头大多是自动的(见 fun.md):重做了被否掉的东西 → 自动对比;落下一大批 → 自动挑 3 张特写;作品有版本 → 自动跟着换。你要做的是**分幕、挑试玩的时刻、把平的几拍并成连发**。
---
## 步骤
### 第 0 步 · 环境 + 看一遍演示(第一次用时做,3 分钟)
下面所有命令里的 `$SK` 都是**这份 SKILL.md 所在的目录**:用 `skills use` 拿到的就是它打印的那个目录(从 picker 来的在 `/tmp/neta-skills/…` 下),装在世界里的才是 `/workspace/.agents/skills/work-making-of`。不要写死成后者。
```bash
SK="<skill-dir>" # 换成这份 SKILL.md 所在的目录(skills use 打印的那个目录)
bash $SK/scripts/doctor.sh
bash $SK/scripts/new.sh /workspace/_demo --demo
node $SK/tools/build-story.js /workspace/_demo && bash $SK/scripts/pv.sh /workspace/_demo
```
对照 `/workspace/_demo/board/story.json` 看 `/workspace/_demo/out/pv-*.jpg`:倒叙开场、章节卡、对比、连发、作品小窗、试玩、结尾对比,全在里面。
**完成标志**:doctor 打印“环境就绪”;build 打印“✓ 没有警告”。
### 第 1 步 · 建项目,拉素材和版本
找到作品所在的 space id(`cohub://spaces/<id>`,或 `cohub spaces ls --json` 按名字找)。作品跨了几个 space 就用逗号连起来。
```bash
P=/workspace/<作品英文名>-making-of # 必须在 /workspace 下
bash $SK/scripts/new.sh $P
bash $SK/scripts/pull.sh <spaceId> $P # 先不带目录:列出哪些目录放着产物
bash $SK/scripts/pull.sh <spaceId> $P <目录1> <目录2> # 带上挑好的目录(几分钟)
python3 $SK/scripts/pull-versions.py <spaceId> $P # 作品发布过的每个版本(几分钟)
```
- 挑目录:要**生成过程中产出的**(`world/media/studio/works`,旧格式世界是 `artifacts/media`;生成图的 `assets/`、`images/`、验收截图 `qa/`)。作品代码里打包的素材目录不要
- `world/media/studio/` 下的文件:`pull-assets.py` 会按 `manifest.json` 的作品索引读每条作品记录,用记录里的 `createdAt` 当时间、`content` 当生成提示词。迁移过来的世界里,这些文件的修改时间全是迁移那一刻,不能拿来排序
- `pull-versions.py`:作品发布成 App 才有版本。它会列出所有 App,自动挑版本最多的当“主作品”(不对就在命令最后写 slug)。场景/地图之类单独发布的 App 加 `--also slug1 slug2` 当普通产物。看一眼 `$P/out/versions.jpg`:**每一版都应该是作品画面,不是加载页、不是白屏**。截坏了的删掉 `board/hd/ver_v<N>.jpg` 重跑
- 没发布过 App:没有版本也能做,作品画面靠 `frame.flip` 翻验收截图
**完成标志**:pull.sh 打印“✓ 拉齐了”,配对里「猜」不多;有版本的话 `src/versions.txt` 每版都对上了原话。
### 第 2 步 · 自动起草(已经编排好)
```bash
python3 $SK/scripts/draft.py $P --lang en|zh # 用户说英文就 en
```
它挑 12~14 拍,并且已经:配好 ✗、分好三幕、连着平铺的拍并成 `montage`、关键版本加了 `"try": true`。打印最后一行是录试玩的命令。
然后**你自己读一遍** `$P/out/beats-1.jpg`(每行:左边原话,右边这句话生成的图)和 `src/turns.txt`,按 `guide/fun.md` 改。不用发给用户确认,直接往下做。
### 第 3 步 · 填占位、写字幕
**作品里有视频**(生成的视频、作品本身就是视频):拍法不一样,**少看挑选过程,多放片子本身**——每一场戏几句话快速连发,然后全屏放用户点头的那一版最好看的 5 秒(`play`,带原声)。先读 fun.md 第 3.5 节。命令:
```bash
python3 $SK/scripts/cut-videos.py $P # 切帧 + 原声;读看片图 out/videos-*.jpg
python3 $SK/scripts/find-highlights.py $P <要放的视频id …> # 挑最好看的几秒;读 out/highlights-*.jpg 核对
python3 $SK/scripts/cut-videos.py $P # 写好 play 以后再跑一次:要全屏放的自动切成 24 帧
```
`story.json` 里所有 `<<…>>` 都要填(不填 build 会拦下):
1. `open.cap`:倒叙开场那一句(≤14 字,「这个游戏,是聊出来的。」)
2. `act`:三幕的名字,「第二幕 · 卡住了」,2~5 个字,说这一段的处境,不说做了什么
3. 每个 `title`:区块标题(「原片截图」「样稿」);`title` 顶部是片尾作品名 + 一句话;`frame.label`
4. 4~6 拍加 `cap` 字幕(写法见 fun.md)
### 第 4 步 · 录试玩
```bash
node $SK/tools/shoot.js --clips $P v12 v40 # draft.py 打印的那一行
```
它打开那一版,自动点「开始/进入/出牌」这类按钮,录 6 秒,记下每次点在哪(片子里的鼠标就照这个动)。**录完挑中间一帧看**:`ls $P/board/clips/v12/`,read 一张。点错了(点进设置、点了没反应)就写 `board/clips/v12.steps.json` 手动指定点哪里再录(格式见 `tools/shoot.js` 开头)。
没有版本的作品:`"try": {"stills": ["截图id1", "截图id2"]}` 用验收截图翻页代替。
### 第 5 步 · 检查、预览
```bash
node $SK/tools/build-story.js $P && bash $SK/scripts/pv.sh $P
```
build 打印每一拍「原话 → 画面变化」和警告,**有警告就改,直到“✓ 没有警告”**。警告里会写改法(连着几拍太平、没有对比、没有试玩、没分幕……)。
逐张看 `$P/out/pv-*.jpg`:
- [ ] 开头 3 秒是成品,然后倒带回空画板
- [ ] 每句原话发出去,画面上真的有东西落下或变化,而且**落下的图就是这句话要的东西**
- [ ] 至少 2 次对比:放大的两张图,一眼看得出差在哪
- [ ] 右上角小窗里的作品在变(有版本时);试玩窗口里真的在玩,鼠标点的地方对
- [ ] 没有连着 3 拍长得一样
- [ ] 结尾:第一版 → 最后一版扫过去,然后收进画框、实机、标题
### 第 6 步 · 结尾、声音、渲染、交付
- **实机**(结尾最好看):用 `$SK/tools/record.js` 录 5~8 秒,写 `ending.footage`(见 story-json.md)。有了它,倒叙开场也会用它。没录就用最后一版截图
- **BGM**:作品自己的音乐放成 `$P/audio/bgm.mp3`(单个 HTML 内嵌的用 `python3 $SK/tools/extract-audio.py <作品.html> $P/audio` 取)
- **配色**(可选):`$SK/guide/style.md`
```bash
bash $SK/scripts/render.sh $P # 后台渲染,5~10 分钟
bash $SK/scripts/status.sh $P # 每 1~2 分钟看一次,直到“✓ 渲染完成”
bash $SK/scripts/publish.sh $P/out/film.mp4 <作品名>-making-of/film-v1.mp4
bash $SK/scripts/publish.sh $P/out/sheet-full.jpg <作品名>-making-of/sheet-v1.jpg
```
回复用户(不贴本地路径):成片和总览图各发一张交接卡(见上面「开工规矩 · 交付用交接卡」,正文不再贴链接);说明「画板摆法是片子重排的,原话、产物、版本都是真的、一一对应」;试玩是自动点的还是手动指定的;请用户试听(你听不到声音)。
---
## 铁律
1. **原话一字不改**,只能用……截断
2. **只放这句话真正生成的产物、真正发布过的版本**。不生成新图来凑;不把 A 句话的图安到 B 句话上
3. **每一拍都要有可见变化**
4. **看得清**:一拍落下一大批之后,要有特写或对比让人看清其中几张。全片不能只有“落下”这一种镜头
5. **一定要有翻车**,而且翻车要有对比:旧的 ✗ 和新的 ✓ 并排放大
6. **数字能数出来**。字幕里的数字,在画面上数得到
7. **别读大图**:只看 `out/` 里缩好的图
## 沙箱的坑
- 沙箱重启后 `/tmp/pp`(puppeteer)会丢:重跑 `doctor.sh`
- **不要 `pkill -f chrome` / `pkill -f node`**:同一个 workspace 里可能有别的会话在渲染,会一起被杀掉。只杀自己启动的进程(记下 PID)
- `link-assets.py` 的工具调用缓存在 `src/calls.json`;`pull-versions.py` 已截过的版本不重截(删 `board/hd/ver_v<N>.jpg` 才会重截)
- 任务中断了:看 `$P/board/summary.txt`、`$P/out/beats.txt` 就知道做到哪了
- **沙箱内存 4GB**:渲染类任务最多开 2~3 个进程,多了会被静默杀掉(进程突然消失、numpy/PIL 报没装);依赖由 `doctor.sh` 装到 `/workspace/.pylib/<Python 版本>`,别装 `--user`(重连会丢);沙箱换过 Python 版本,报 `_imaging` / numpy 导入错就重跑 `doctor.sh`
- 抽卡版 `gacha.sh` 起的是后台守护进程,自己补段、自己拼;`--status` 看进度。十几分钟没进展是出事了,不是算力慢
## 目录
```
SKILL.md
guide/ fun.md(编排 + 挑拍) story-json.md(字段) style.md(配色) gacha.md(视频作品的抽卡版)
scripts/ doctor.sh new.sh gacha-start.sh / gacha-pull.py / gacha-draft.py / gacha-ring.py / gacha-check.py / gacha.sh(抽卡版:一键开工 / 拉 / 起草 / 圈框预览调框 / 检查 / 后台渲染) pull.sh(拉齐素材) pull-versions.py(作品版本) cut-videos.py(视频切帧 + 原声 + 看片图) find-highlights.py(视频挑最好看的几秒) draft.py(起草+编排) sheet.py(自查用的分镜图)
pv.sh render.sh status.sh publish.sh
pull.sh 内部:find-dirs.py pull-quotes.py pull-assets.py link-assets.py find-moments.py
tools/ gacha/render.py(抽卡版渲染器,读 gacha.json) build-story.js(检查) shoot.js(版本截图 / 录试玩) record.js(录实机) preview.js render.js palette.py extract-audio.py
tools/board/ 画板引擎:board-engine.js(画板、镜头) board-screens.js(屏幕层:特写/对比/章节/试玩/重抽/小窗/倒叙) auto-story.js(读 story.json)
examples/ niulai/(真实项目) advanced/(手写 story.js 的原版)
```
Show more