feat(timeline): P2 并行编排——scene 多轨编辑器 + 白模重叠预览

剧情 Timeline P2 前端 + 共享内核(与 SGame 源真同步):
- ir_core/IR_SCHEMA/样张:scene v0.3 + scene 校验 + 导出 gate(D3),与 SGame 仓逐字一致
- timeline.js:appendScene 按 authored start 铺多轨 clip(自然重叠预览),move from 同 actor 跨轨续连(D4);
  drawStage 改逐 actor 查对话→多人气泡同时计时;导出 _clipDur 纯函数;show() 加 startId 参;常量加 CAMERA_DUR
- scene_edit.js(新):演出段编辑模态——拖 clip 改 start(吸附 0.1s)、拖右缘改 dur、增删 clip/轨道、
  选中属性条精确编辑、客户端轻量 lint(镜像 validate.py)、▶ 预览此段(复用播放核)
- graph.js:scene 节点(KIND_CN/summary/nodeInner 列轨道)+双击进编辑模态
- form.js:右栏 renderScene 精确数值编辑(轨道/clip 的 start/dur/kind/目标)+打开编辑器按钮
- app.py export:捕获 CompileError 并入 report(scene 被拦时不再 500)
- test_scene.js:离线 10 断言全过(重叠确凿/晚 1.5s 起步/from 续连);gitignore 忽略本地 _localdemo.db

待浏览器目测拖拽编辑落 IR + 白模重叠演出。
This commit is contained in:
2026-06-13 22:34:29 +08:00
parent 06e639f0df
commit 021080dd56
14 changed files with 841 additions and 16 deletions

View File

@ -0,0 +1,45 @@
{
"id": "QY_SCENE",
"title": "并行演出段演示",
"theme": "P2 多轨时间线A 走、1.5s 后 B 才走,两者时间重叠",
"scale": "演示",
"roles": [
{ "slot": "NP1", "name": "神秘剑客", "archetype": "负伤外门高手", "camp": 0 },
{ "slot": "NP2", "name": "客栈小二", "archetype": "市井路人", "camp": 0 }
],
"stage": { "type": "客栈·夜", "point_set": "QY_TLDEMO" },
"nodes": [
{ "id": "n_open", "kind": "narration", "speaker": "P1", "text": "夜色深沉,雨点敲打着客栈的窗棂。两道身影几乎同时动了起来。", "next": "sc_demo" },
{
"id": "sc_demo",
"kind": "scene",
"next": "n_choice",
"tracks": [
{ "id": "tk_p1", "actor": "P1", "clips": [
{ "id": "c_p1move", "kind": "move", "start": 0, "to": "PT_CENTER" },
{ "id": "c_p1say", "kind": "dialogue", "start": 0.5, "text": "(这客栈看着冷清,却处处透着古怪……我先到中堂看看。)" }
] },
{ "id": "tk_np1", "actor": "NP1", "clips": [
{ "id": "c_np1move", "kind": "move", "start": 1.5, "to": "PT_DOOR" },
{ "id": "c_np1say", "kind": "dialogue", "start": 3.0, "text": "阁下留步。在下身负旧伤,想借贵宝地歇一晚,天明即走。" }
] },
{ "id": "tk_np2", "actor": "NP2", "clips": [
{ "id": "c_np2say", "kind": "dialogue", "start": 4.5, "text": "二位客官,里边请,小的这就去沏壶热茶!" }
] },
{ "id": "tk_cam", "role": "camera", "clips": [
{ "id": "c_cam0", "kind": "camera", "start": 0, "focus": "PT_CENTER", "dur": 6.0 }
] }
]
},
{ "id": "n_choice", "kind": "choice", "options": [
{ "text": "收剑,请他进来歇脚", "goto": "end_peace" },
{ "text": "拔剑相向,喝令他离开", "goto": "end_fight" }
] }
],
"endings": [
{ "id": "end_peace", "summary": "结义同盟,平安一夜", "grants": [], "result": "success" },
{ "id": "end_fight", "summary": "刀剑相向,剑客败退雨夜", "grants": [], "result": "fail" }
]
}