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

@ -236,6 +236,11 @@ def compile_ir(ir, dic):
r["resultRewardIds"] = rid_str
if rac:
r["roleActionCode"] = rac
elif kind == "scene":
# 导出 gateP2 决策 D3scene 多轨演出段需 P3 引擎(StoryTimelineData/Director)支持,
# P2 阶段只编排+白模预览,不做会被 P3 替换的临时降级器。拦在 zip 导出前。
raise CompileError("节点 %s 是 scene 演出段scene 暂需 P3 引擎支持,未上线前勿用于导出"
"(可继续编排+白模预览,但含 scene 的事件无法编译成 game_event_data" % tid)
else:
raise CompileError("未知节点 kind: %r (节点 %s)" % (kind, tid))
@ -260,6 +265,11 @@ def extract_texts(ir):
add(n.get("text"))
for o in n.get("options", []):
add(o.get("text"))
if n.get("kind") == "scene": # P2补抽 scene 内 dialogue/narration 文本
for tk in n.get("tracks", []) or []:
for clip in tk.get("clips", []) or []:
if clip.get("kind") in ("dialogue", "narration"):
add(clip.get("text"))
walk_nodes(ir.get("nodes", []))
for s in ir.get("sequences", []):