设计
自动剪辑现在真正成了短视频
每一局结束的对局本来就会变成竖屏短片,只是看上去都一个样。现在每条片子都有开场钩子、关键金额提示,并以一张结尾卡片收束。

通俗版
opolyx 会把结束的对局做成竖屏精彩片段并自动发布。这部分早已运转。问题在于,连看三条的感觉和看一条差不多。
- 大约 40% 的画面是围绕居中棋盘的空白背景;
- 片子从对局中途一次随意的掷骰开始——而那一帧同时就是封面图;
- 高潮读不出来:一笔 12,000 的租金只是小信息流里的一行灰字;
- 每个事件占用的时间一样长,于是铺垫和高光同样冗长;
- 它们没有声音、没有结尾,文案和话题标签也从不改变。
现在每条片子都是被"导演"出来的,而不是原样倒出:开场用一个钩子告诉你即将看到什么,棋盘填满画面,金额与重大事件在发生的瞬间被标注出来,最后以一张告诉你去哪玩的卡片收尾。节奏会略过记账式的琐碎步骤,在关键时刻放慢——包括在你已经能猜到结果之前的一小段定格。
14–27 s
片长,按时刻裁定
3
套轮换版式
40%
过去空着的画面比例
文案、标题和话题标签现在都从词库中抽取,而不是只有一句;当同一局产生多条片子时,会挑选主题彼此不同的片段,而不是同一次破产的三个视角。
你无需做任何事就可能出现在片子里——每一局结束的对局都符合条件,片子会自动发布到 YouTube、Instagram 和 TikTok。
技术细节
渲染器是一台小型 VPS 上的 worker,它用无界面 Chromium 加载线上站点并录制回放路由。这正是杠杆所在:片子的全部外观都是网页代码,因此随普通部署一起生效,完全不需要动 worker。
关键在于把"锚点时刻"找回来。回放路由只收到一个时间范围,而不是"那个时刻"——因此页面会在完整事件日志上重新运行引擎自带的精彩时刻评分,并取该窗口内得分最高的点。这可以被证明能还原 worker 当初挑选的时刻,也正因如此,视觉部分才能在完全不触碰 worker 的情况下上线。
ts
// lib/clip/pacing.ts — screen time is a function of what the event is
const BOOKKEEPING = 110; // turn_ended, dice_rolled: skim
const NORMAL = 320;
const ANCHOR_MIN = 1400; // the moment the clip exists for
const PREDICT_FREEZE = 600; // "what happens next?" before a guessable payoff
export function paceFor(event: DomainEvent, isAnchor: boolean): number {
if (isAnchor) return Math.max(ANCHOR_MIN, NORMAL);
return isBookkeeping(event) ? BOOKKEEPING : NORMAL;
}| 此前 | 现在 | |
|---|---|---|
| 结构 | 一段连续回放 | 钩子、正片、结尾卡片 |
| 节奏 | 700 毫秒 × 65 个事件 | 按事件权重 110–1400 毫秒 |
| 时长 | 始终约 45 秒 | 14–27 秒,按需裁定 |
| 发布文案 | 一句文案、四个固定标签 | 每条片子按种子取自词库 |
| 音频 | 在代码里被强制关闭 | 游戏音效,可选背景音乐 |
筛选逻辑也变了:当一局产生多个候选时刻时,挑选器会保留每种不同类型中最好的一个,于是同一场比赛不再产出三条几乎一样的破产片段。
文案词库刻意只用英语:片子以固定语言渲染,把它们放在翻译目录之外,就不会影响站点的文本对齐数量。要做本地化片子,得先有各语言的社交账号。
