character-drink-play
Verified @xinsong854/character-drink-play-2
With improvements from @siosan
Use it in Cohub
Paste this into your agent's chat — it fetches the skill and follows it.
Use the skill: character-drink-play. Run `npx -y @neta-art/neta-search-cli@latest skills use @xinsong854/character-drink-play-2 --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 @xinsong854/character-drink-play-2copy
Summary
Turn a character in your world into a signature drink, shown on a 3D stand you can spin by dragging.
Pick a character and get one custom drink designed from their look, personality, history and favorite colors, with each design choice explained. You get a web page with the drink on a display stand. Drag to rotate it 360° and switch between several drinks. Two recipes: a fantasy recipe that fits your world, and a real-life version using only edible, easy-to-find ingredients. You can ask for either or both. Details like a slowly spinning or floating decoration appear only if they truly suit the character. Otherwise nothing moves. Works best with characters that have a portrait and written notes: a striking palette, a signature object, a clear personality.
Improvements from other creators
This version: thanks to @siosan.
Siosan @siosan 1 adopted suggestion · in this version
SKILL.md
# 角色特调饮品 · Skill
**版本 0.1.2 · 试用版。** 安装到任意 Space 后,用户说一句话,Agent 读取该 Space 里目标角色的资料,为每位角色设计一杯饮品,并制作展台网页、设计说明与配方。
安装本身不扫描、不联网、不发布。只有用户调用后才读取 Space 资料。
## 产物
- 一个登记好的 Studio 网页作品,目录 `works/webs/drink-<slug>/`(老世界是 `works/web/`),浏览器入口在 `public/`:展台网页。`procedural` 路线只需要 `config.json`;`glb` 路线另有 `characters/<id>/drink.glb`。
- 设计说明:每杯一份,列出每个设计件的依据(事实 / 推断 / 创作)、配方和动态清单。
- `work/drink-play/<run>/`:来源索引、角色档案、Blender 工程与烘焙中间件、QA 截图、报告。私有,不发布。
## 何时停下来问用户
这一节是“停不停”的唯一依据,流程里不再另设确认关卡。
**制作前必须知道的决定:**
- 目标角色明确。开场没有点出具体角色名就算不明确(“这个世界里的角色”“全部”都算),要先列候选名单。
- 路线(`procedural` / `glb`)。
- 配方类型(`concept` / `real-world` / `both`)。
**默认值(用户没提就用它,不为此停下):** 路线 `procedural`,除非用户提到 Blender、GLB 或烘焙;配方类型 `both`;动态为零。液面波纹开关、甜度、可选装饰这类用户没问的细节,按设计自行决定,在交付里列为可调。
**必须停下的情况:**
1. 上面的必须决定有一项没有,且没有默认值可用。
2. 同名、多版本,或设定冲突会改变饮品的主意象。
3. 角色的核心符号或禁忌不清楚,无法决定主色与主意象。
4. 配方涉及危险物质、药物、毒物,或世界观里不可食用的东西要求做成“现实配方”。此时改为概念配方,或替换为可食用原料。
5. 要对世界之外公开分享(`cohub-apps`)。注意:登记并发布成 Studio 作品不属于这一条,它是每次交付都要做的,不用问。
要停时,把缺的项在**一条消息**里问完,在写 pack、跑 Blender 或 `work init` 之前结束这一轮,等用户回话。以上都不成立就不停,直接做到交付。
## 流程
`SKILL` 为本技能目录(即 SKILL.md 所在目录),`SPACE_ROOT` 为目标 Space 的工作目录(通常是 `/workspace`)。
### 1. 取材(只读)
```bash
SKILL="${SKILL:?先设成本 SKILL.md 所在目录(skills use 打印的那个)}"
RUN="$SPACE_ROOT/work/drink-play/$(date +%Y%m%d-%H%M%S)"; mkdir -p "$RUN"
node "$SKILL/tools/intake.mjs" scan --root "$SPACE_ROOT" --out "$RUN/source-index.json"
```
扫描只列出文件和候选人物,不代表已经读懂。读完角色正文和立绘后再进入下一步。
- 从立绘取配色(主色 2–3 个)和标志物。每个色样记录取自哪张图、哪个区域。
- 资料里没有的饮食喜好写“未知”。不能由饮品设计倒推角色喜好。
- 小说、EPUB、长设定集优先用已安装的 `book-to-world`(Full 档)整理,再核对回角色。见 `references/space-intake.md`。
### 2. 角色档案与设计映射
按 `templates/dossier.example.json` 写 `$RUN/dossier.json`,每条事实标注 `basis`(`explicit` / `visual` / `inferred`)与 `visibility`(`public` / `private` / `undecided`),并给出证据。
```bash
node "$SKILL/tools/intake.mjs" validate --dossier "$RUN/dossier.json"
```
设计映射写在 `$RUN/design/<id>.md`,方法见 `references/design-mapping.md`。每个设计件都要回答三件事:为什么是这个角色、外观是什么、用什么工艺实现。
### 3. 路线与配方
| 路线 | 条件 | 产物 |
|---|---|---|
| `procedural` | 默认。不需要 Blender,几何由 `scene` 配置实时生成 | 可拖动展台 |
| `glb` | 有 Blender 4.2 或 4.5 LTS,并需要烘焙质感 | 烘焙 GLB + 展台 |
没有 WebGL 时只能交付静态截图,并明确写“未提供可拖动 3D 展台”。
配方分三类,必须标明:
- `concept`:世界观概念配方,不暗示可以饮用。
- `real-world`:现实可调制版本,所有原料可食用、可获得,不含药物或危险操作。
- `both`:两者都给,分开书写。
### 4. 方案
按“何时停下来问用户”判断:有必须停下的情况,就把缺的项和暂定方案一起发出,结束这一轮;否则把方案摘要写在消息里,接着制作、QA、发布,不停。
方案包括:角色、饮品名、五个槽位的设计与依据、配方类型、动态清单(默认为零)、用了哪些默认值、不会做的事。
### 5. 制作
- pack 的 `locale` 写用户开场的语言(内置 `zh`、`en`;其他语言在 pack 的 `ui` 里给出全部界面文字,键名见 `tools/ui-strings.mjs`)。pack 标题、饮品名、tagline、设计说明、配方、表现范围都用这个语言写;角色名等专名保留原样。展台的按钮、状态、页脚由构建器按 `locale` 填入。
- `procedural`:按 `templates/pack.example.json` 写 `scene`(容器剖面、三色液体、装饰、动态)。
- `glb`:把 `templates/build_drink.py` 复制到 `$RUN/drink/<id>/build/`,按设计改造骨架。骨架里的占位件(底座、插饰、闪光)按设计保留或删除,不能留下没有依据的默认元素。运行方法见 `references/BLENDER.md` 与 `references/BAKE.md`。
### 6. 组装
先登记作品目录(只写一个 `meta.json`,状态为制作中),再把展台组装进去。不要自己挑 `works/` 下的目录名,也不要手写 `meta.json`。`--title` 用用户的语言写,和 pack 的 `locale` 一致:
```bash
cd "$SPACE_ROOT"
WORK=$(node /mods/neta/neta work init web works/web/drink-<slug> --entry public/index.html --title "<作品标题>" \
| node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const j=s.split("\n").filter(l=>l.startsWith("{")).map(l=>JSON.parse(l)).find(j=>j.data&&j.data.workDir);if(!j){console.error(s);process.exit(1)}console.log(j.data.workDir)})')
echo "$WORK" # 新世界是 works/webs/drink-<slug>,老世界是 works/web/drink-<slug>;以命令给出的为准
node "$SKILL/tools/create-project.mjs" --check-only --pack "$RUN/pack.json" \
--dossier "$RUN/dossier.json" --source-root "$RUN"
node "$SKILL/tools/create-project.mjs" --pack "$RUN/pack.json" \
--dossier "$RUN/dossier.json" --source-root "$RUN" --out "$WORK"
```
`--out` 必须是 `work init` 刚建的目录(里面只有 `meta.json`)。重做时不要再 `work init`:`WORK` 用已有的作品目录,加 `--update`,之后重新 QA、重新发布。构建器只复制 pack 明确列出的素材,并校验 GLB 文件头、拒绝越界路径、外部 URL 与像档案的 JSON。
### 7. QA
按 `references/QA.md` 执行。最低要求:
- 页面无控制台错误、无 404;每杯都能切换;拖动与复位正常。
- 动态元素按设计运行,且默认关闭的动态不出现。
- 设计说明只显示 public 依据;公开目录里没有档案字段。
- 页面可见文字和作品标题都是用户的语言:英文用户的页面里没有连续 4 个及以上的中日韩文字(`--check-only` 的 `warnings` 会列出来)。
- glb 路线:`glb_check.py` 通过,材质没有丢贴图。
- 窄屏可以操作,截图与设计说明一致。
### 8. 交付
QA 通过后,把 `public/` 发布成 Studio 作品。**只组装出网页、没有登记发布,算没交付**:用户在 Studio 里看不到作品卡,打不开也分享不了。
```bash
cd "$SPACE_ROOT"
node /mods/neta/neta work publish web "$WORK" --from "$WORK/public"
```
- 输出 `"ok":true`、`meta.json` 里 `status` 变成 `ready` 才算发布成功。失败时按报错修(例如 `world_slug_required` 要先给世界设 slug),不要退回去交文件卡。
- 只发布 `public/`。档案、来源索引、`project-state.json`、`revisions/` 都不会进作品。
- 用 `interaction-components` 交一张**作品卡**:`{"type": "work", "workId": "<作品目录名,即 drink-<slug>>"}`。不要交 `world-file` 文件卡,也不要贴 `index.html` 路径。
- 发布成 Studio 作品和"对世界之外公开分享"是两回事。前者每次都做;后者要用户明确同意,再用 `cohub-apps`。
- 交付说明:设计说明(含依据)、配方、动态清单、用了哪些默认值(可调)、未验证项。交付说明和作品卡的 fallback / presentation 文字都按下面“回话语言”一条写。
## 硬规则
- **回话语言。** 看用户开场用的语言,之后每一条回话都用它写:方案、进度、交付说明(设计、配方、动态清单、未验证项)以及作品卡文字。专名和用户给的原话保留原样。
- 每杯从零设计。只读本角色的资料与本杯的设计文档,不沿用其他角色的符号、配方或动态。
- 装饰要能回答“为什么是这个角色”。只为风格服务的装饰要标明是创作。
- 动态元素默认为零。只有角色意象里真的会动的东西才能开启,并引用 public 事实。
- 现实配方的原料必须可食用,不给出危险操作。
## 已知边界
- 现实配方只是参考。具体调制的安全性由用户自行确认。
- `glb` 路线依赖 Blender。本包已在 Blender 4.2.1 上验证构建与烘焙;其它版本需先跑冒烟。
- `glb` 路线在 0.1 版只渲染烘焙模型、玻璃与液面,`scene.json` 中的闪光、指针、漂浮物尚未接入网页。
- `procedural` 路线的动态只支持 `spin` 与 `float` 两种运动。
- 0.1 版只用合成角色跑通了 procedural 与 glb 两条路线(组装、浏览器渲染、烘焙、GLB 检查)。对本 Space 的真实角色只做了扫描,没有做过完整制作与验收。
## 首次使用
在 Blender 路线前先确认版本与烘焙冒烟:`BLENDER_BIN -b --version`,并按 `references/BAKE.md` 跑低分辨率烘焙(`256 4`)。
## 文件
- `tools/intake.mjs`:扫描 Space、校验角色档案
- `tools/create-project.mjs`:由档案与 pack 组装展台项目
- `tools/shot.mjs`:无头浏览器截图与页面状态检查
- `runtime/`:展台网页(`index.html`、`app.js`、`style.css`、`vendor/` 里的 three.js r186 模块)
- `templates/`:`build_drink.py`(建模骨架)、`bake_export.py`(烘焙导出)、`qa/glb_check.py`(材质检查)、档案与 pack 示例
- `references/`:取材、设计映射、Blender、烘焙、QA
Show more