Files
story-edit-web/web
邓雨鹏 e6ec743564 feat(timeline): 交互式分支演出 + 从任意节点开始 + 时间轴分面板/自适应
- 交互分支:播到选择/战斗/随机节点暂停,在镜头下方弹按钮手选,点完接对应分支续演
- 从任意节点开始:单击节点选中→「从选中处开始」或双击节点,立即从该处播放;
  起始位置按从开头到该节点途中的走位重放算出(角色站在应有位置),已离线验证
- 布局分两块(上舞台/下时间轴),时间轴 playhead 仅播放时居中、暂停可自由滚
- 时间轴自适应宽度按钮(整条压进可视区)+鼠标滚轮横向滚动,解决长时间轴够不着节点
- 演示事件 QY_TLDEMO 扩充两条分支(和解→随机夜晚/拔剑→战斗胜败),去掉对焦NP1
2026-06-13 18:54:32 +08:00
..

Story 事件协作 Web 编辑器M5

设计:docs/plans/2026-06-06-story-event-pipeline-design.md§5.1/§6, D1D4/D8 计划:docs/plans/2026-06-08-story-event-M5-web-editor-plan.md

少数人各凭专属口令(口令即身份,改动自动署名)在网页里审校/编辑剧情事件 → 静态校验 + 剧本试走(零引擎)→ 一键编译 所有 confirmed 事件成 .events.json + .i18n.tsv 打包下载。校验/编译走 ir_core,与 CLI ir_compile.py)逐字节同口径。

起服务

cd tools/event_authoring/web
pip install -r requirements.txt
# Windows PowerShell: $env:STORY_WEB_USERS="bia:口令A,ljl:口令B"
set STORY_WEB_USERS=bia:口令A,ljl:口令B   # 必填;未配置则拒绝启动
uvicorn app:app --host 0.0.0.0 --port 8787

浏览器打开 http://<host>:8787,输入自己的专属口令进入(服务端按口令认人, updated_by 自动署名;口令要求 ≥8 位且互不相同cookie 只存随机会话 token 不存口令; 从 STORY_WEB_USERS 移除某人即吊销其所有会话)。

用法

  1. 导入 IR:右上「导入 IR」粘贴单个或数组形式的 IR JSONsamples/*.ir.json)。
  2. 审校/编辑:左栏选事件 → 中栏分支树 → 点节点在右栏改文案/增删节点/下拉改分支/角色表/点位下拉。
  3. 校验:与 CLI 同口径(断链、选项无兜底、未登记 kind、未声明角色、点位缺失、out_ref 失效…)。
  4. 试走:从首节点走,点选项/掷随机/手选战斗胜负,实时累计银两/道具/友好度账面与结局。
  5. 确认/丢弃改事件状态pending/confirmed/discarded
  6. 导出 confirmed:编译所有 confirmed → story_export.zip;任一 confirmed 校验不过则整体拒绝。

导出后把 {group}.events.json 放进 Assets/StreamingAssets/Story/Config/(或 Qiyu/ 子目录), {group}.i18n.tsv 的韩文翻译合并进 Assets/StreamingAssets/i18n/ko.tsv

数据

  • 事件存 SQLite story_events.db(本目录,已 gitignore末次写入生效不做锁
  • 词典 ../ir_dictionary.json、点位集 Assets/StreamingAssets/Story/PointSets/*.points.json 只读引用。

Docker 部署M6

单容器FastAPI + 静态前端 + SQLite + 纯 Python 编译器)。构建上下文是 tools/event_authoring(需含 ir_core/ir_dictionary.json/web)。

cd tools/event_authoring/web
STORY_WEB_USERS="bia:口令A,ljl:口令B" docker compose up -d --build
# 或不用 compose
#   docker build -f web/Dockerfile -t story-event-web ..
#   docker run -d -p 8787:8787 -e STORY_WEB_USERS="bia:口令A,ljl:口令B" \
#     -v "$PWD/web/data:/data" \
#     -v "$PWD/Assets/StreamingAssets/Story/PointSets:/pointsets:ro" story-event-web
  • ./data:/dataSQLite 持久化,容器重建不丢事件,勿删 …/PointSets:/pointsets:ro(开发侧点位集只读;缺失时坐标校验降级为警告)。
  • 环境变量STORY_WEB_USERS(必填,名字1:口令1,名字2:口令2,未配置拒绝启动)、 STORY_WEB_PORT(宿主端口,默认 8787STORY_DB_PATH(默认 /data/story_events.db)、STORY_POINTSETS_DIR(默认 /pointsets)、 可选 TZ=Asia/Shanghai(否则 updated_at 按 UTC 显示)。
  • NAS + VPSNAS 跑容器VPS 用反代/frp/Cloudflare Tunnel 把 8787 映射出去。点位集更新只需 同步文件到 NAS 的 /pointsets 卷路径,无需重建镜像。备份=拷 data/story_events.db

API鉴权后

POST /api/login · GET /api/dictionary · GET /api/pointsets · POST /api/import · GET /api/events?status= · GET /api/events/{group} · PUT /api/events/{group} · POST /api/events/{group}/status · POST /api/validate · POST /api/export

非目标(见设计)

容器化部署M6、多人账号/并发锁、手拖画布、引擎侧新语义、把坐标嵌进 events.json。