下载 App
修改于10/203 浏览综合 包含 AI 合成内容

【聚光灯21天】DAY 13 · H5 版一天做完六个页面,和一次「资产先瘦身再上线」

TapTap
DAY 12 封存了 Lua 版、开了 H5 的壳。今天把整个游戏在浏览器里重建了一遍。
一天之内:六个页面(主菜单 / 选择页 / 对局页 / 设置 / 存档 / 结算)、
朝代罗盘、配音与 BGM 两套音频系统、七套浏览器验收测试、四条资产管线。

一、为什么能一天做完

因为规则早就写好了,今天只做"渲染层"。
DAY 12 说清了这件事的来龙去脉:这个项目的规则真源一直是 JS(prot/engine.js),
Lua 是它的逐位移植。所以 H5 版:
ts复制
ts
// h5/vite.config.ts alias: { '@engine': resolve(repoRoot, 'prot/engine.js'), // 规则:原样复用 '@data': resolve(repoRoot, 'prot/lua-data'), // 数据:原样 import }
不拷贝、不转译。 prot/ 的测试因此继续守护同一份代码 —— H5 与 Node 跑的是同一个 engine.js。
于是今天的活就变成了纯粹的**“把状态渲染成 DOM”**。game/session.ts 933 行,
控制流严格对齐已封存的 scripts/qingshi/ui/game.lua 的 handleRoute。

二、六个页面 + 罗盘

模块行数说明
ui/menu.ts263主菜单
ui/select.ts286选择页(剧本卡 + 难度 + 入局漩涡)
ui/wheel.ts299朝代罗盘
ui/settings.ts115设置页
ui/savepage.ts107存档页
ui/cast.ts77立绘列
game/session.ts933会话与流程
game/audio.ts155BGM
game/voice.ts188配音
game/saves.ts201存档
game/settings.ts126设置
样式 2,481 行(art / base / game / menu / save / select / settings / stage)。

罗盘:DOM 移植,手感参数逐项对齐

罗盘是最难的一块。wheel.ts 头注写得很清楚 —— 模型与手感参数与 Lua 完全一致:
  • 朝代名固定在自己的方位(第 1 项在正上方),不随盘转
  • 盘面(环带 + 烘焙在顶部的指针)旋转,由指针去指当前选中的那一格
  • 拖拽跟手 → 松手惯性 → 欠阻尼弹簧吸附(冲过再回摆)→ 整体归位
  • 拖拽位移极小视为点击;中心盘为中枢死区
与 Lua 的差异只在渲染层:NanoVG 即时绘制换成 DOM + CSS transform,
每帧只写 transform/位置,不重排布局。
这块的手感在 Lua 版调了很多轮(DAY 8 的"罗盘四版"),今天照搬结论,不重新调。
这就是封存说明里"已验证的视觉规则照搬"那条的实际兑现。

三、资产:先瘦身,再上线

TapTap
这是今天最"硬"的一块。美术给的原件不能直接上网页 —— 差了两个数量级。

三条管线,三个不同的理由

① 美术图:build-assets.py —— 74 张源图 131MB → WebP
源图是 2848×1602 的 PNG,单张背景 6–8MB。直接引用的话,对局页光背景就要下 6MB,
首屏根本没法看。统一转 WebP + 限制最大边(如背景 1920px、立绘 620×860),
整站美术预算压到几 MB 量级。
每张图单独配质量参数(背景 72 / 卡片 84 / 标题 90),不是一刀切。
② BGM:build-audio.py —— 41.3MB → 每曲约 1.4MB
源是 vorbis 160kb/s、3分23秒的完整曲子,单个 3.2–4.0MB,十一个合计 41.3MB。
转码这里有个踩出来的结论:
同码率下 opus 比 aac 省 17%(48k vs 64k),省下的比换格式更重要。
还有一条反直觉的:固定码率对 libopus 意义重大 —— 加 -ac 1(强制单声道)不会变小,
因为比特率是总量,单声道只会让每声道分到更多码,听起来更糟。要省只能降码率。
为什么要出两种格式:
  • opus 只能装进 webm/ogg —— 而且这个 ffmpeg 构建往 m4a 里塞 opus 会写出一个 0 字节的坏文件(加 -strict -2 也不行)
  • opus 在 Safari 上支持不稳,aac/m4a 才是通用兜底
所以两套都出,运行时用 canPlayType 探测,只会下载其中一个。
③ 配音:build-voice.py —— 249MB → 试点单章 2.5MB
这条最讲究。先做试点,不一次转全量:
全量 opus 后约 100MB,一轮全流程出问题就得整体回退。
单章约 2.5MB、41 条,足够验证切片/预取/排队这套机制。
码率取舍也写明了:源是 mono vorbis 96kb/s;opus 32k mono 降到约 40%
(24k 能到 50%,但齿音上能听出来,不值),aac 48k mono 兜底。

四、音频的两条"物理约束"

写 audio.ts / voice.ts 时,真正决定代码形状的不是功能,是浏览器的物理约束:

BGM:自动播放策略

没有用户手势之前 play() 会被拒。 所以音乐不在页面加载时启动,
而是在玩家点「入局」之后 —— 那一下 click 就是合法手势。
另外两条:只下纯音乐版(vocal 版 ~1.5MB 做成可选开关,默认不预载);
不阻塞交互(<audio> 由浏览器流式取,加载期间游戏照常玩)。

配音:缓冲窗口只有几百毫秒

点完选项到下一句播出来,中间没有留给你下载的时间。 所以必须提前把本章切片拉下来,
而不是播到哪下到哪。
还有一条:串行播放,不能并发 —— 一章 41 条如果一次性并发拉,会把连接池打满。

一个"不维护清单"的设计

配音切片名纯靠推导得出:
intro_<N>        → chapter.intro[N]
<事件id>_s<N>    → event.segs[N-1]
<事件id>_o<N>    → event.options[N-1].res
所以不需要额外维护一份清单文件 —— src 侧用 import.meta.glob 建索引,
查不到就是没有这条配音,天然降级。
用 glob 而不是「预生成一份 index.json」的理由:
清单会漂移,glob 不会。

五、测试:七套浏览器验收 + 一套纯 Node

prot/ 的测试验规则(引擎/数据/契约);h5/tests/ 验**“浏览器里真的能玩、真的不塌”**。
测试验什么
chain.cjs李斯第一章全链路(序章→词条→行动卡→关键事件→选项→属性增减→章末)
viewports.cjs8 种视口下布局不塌
backtrack.cjs回溯按钮 → 确认浮层 → 回章首
save.cjs存读档
audio.cjsBGM 格式选择与加载
voice.cjs配音切片与降级
reveal.cjs渐显动线
scenarios.cjs纯 Node:剧本轻量表漂移
七套浏览器 + 一套纯 Node = 1,325 行,全部自建 CDP,不引 Playwright/Puppeteer。
dev-check.cjs 专门盯 dev 模式 —— 因为三套测试都跑 dist/ 构建产物,
vite dev 路径平时没人碰。而已知历史问题就是 dev 下 @engine 的 UMD 拿不到 default 导出而白屏。

六、今天的数据

项值
H5 源码6,192 行(14 个 .ts + 8 个 .css)
浏览器验收1,325 行 / 7 套 + 1 套纯 Node
资产管线4 条(build-assets / build-audio / build-voice / shot.cjs)
美术131MB PNG → WebP(整站压到几 MB)
BGM41.3MB → 每曲 ~1.4MB(webm/m4a 双格式)
配音249MB → 试点单章 2.5MB
H5 资源总量45MB(bgm 35M / voice 7.1M / char 837K / lua 485K)
Lua 版已封存,prot 三门禁仍全绿(SYNTAX 27 / API OK / REPLAY 100/100)

今天最值钱的一条

"换载体"之所以能一天做完六个页面,不是因为写得快,是因为规则不在渲染层里。
DAY 6 把规则抽成 JS 真源 + Lua 移植,当时只是为了做对拍网。
但 DAY 12 换载体、DAY 13 一天重建六个页面 —— 这份"规则与渲染分离"的架构,
决定了项目的迁移成本。
同样地,今天资产管线的价值也不在"转了个格式",而在把物理约束想清楚再写代码:
自动播放策略决定了音乐何时启动;几百毫秒的缓冲窗口决定了配音必须预取;
opus 在 Safari 不稳决定了必须出双格式。
先想清楚"约束是什么",代码形状自己就出来了。

明天

  1. 配音全量转码 —— 试点已验证机制,--all 跑全量(约 100MB,谨慎)
  2. 浏览器验收常跑 —— 七套进日常,尤其 dev-check(盯 dev 白屏)
  3. 首屏体积预算 —— 美术已瘦身,再核一遍首屏实际下载量
  4. 成就图标 64 缺失 —— P3 美术批次待补(见 docs/已知问题-成就图标契约.md)
horizontal linehorizontal line
载体:H5(Vite + TypeScript),规则引擎复用 prot/engine.js · 状态:六页面 + 罗盘 + 双音频系统 + 七套浏览器验收;资产管线四条 · Lua 版封存中(prot 三门禁全绿)
【童谣镇】聚光灯第二次开发日志截图
【童谣镇】聚光灯第二次开发日志
开发进度: 美术 1、主角人物立绘已细化完成 2、所有NPC的QQ人形象与呼吸动画已设计完成 3、大部分UI界面已设计完成 4、面包房建模与树屋建模以及基础房屋、路灯、树木模型已完成。 5、制作过场动效,制作通用动效材质ing 6、广场资产替换、永续桥和植被的资产替换、房屋资产替换,河流制作 7、学校模型的材质完成 8、石墩子、小道具模型制作ing 9、NPC正比胸像绘制ing 策划 1、任务系统
11 赞
10 回复
《气味之城》开发日志#1|为什么"涌现"和猫是天作之合截图
《气味之城》开发日志#1|为什么"涌现"和猫是天作之合
大家好,我是一个人报名了 2026 聚光灯 21 天游戏创作挑战 的独立开发者。今年主题公布那一刻我就笑出了声——涌现。因为我已经想做这个游戏很久了: 《气味之城》:你不是猫神,你只是一只猫。 先说一个所有养猫人都懂的事实:你永远无法"教会"一只猫任何它自己不想学会的事。但你家猫可能自己学会了——听见冰箱开门就瞬移到厨房;你心情不好时过来踩奶;凌晨三点准时在你身上练马拉松。没人教过它,这些行为是它
3 赞
6 回复
《卡牌工业》开发日志 01|从“涌现”到产线对打截图
《卡牌工业》开发日志 01|从“涌现”到产线对打
大家好,我们正在用 Godot 做一个暂名《卡牌工业》的游戏。目前已经跑通了最小的生产与战斗循环,也做了两轮迭代。这篇先记录一下:面对“涌现”这个题目,我们讨论过什么,又为什么最后收敛到卡牌和工厂。 第一步:头脑风暴,涌现可以是什么? 刚看到“涌现”这个题目时,我们的想法几乎朝每个方向散开了。塔防、物理搭建、探索、解谜、经济系统、叙事,甚至增量游戏,都能让简单规则在玩家的操作中长出新的结果。再想下
1 回复
00:07
雨天決行 开发者日志02-人工智能的自我修养截图
雨天決行 开发者日志02-人工智能的自我修养
又和大家见面啦!第二篇日志,说实话一开始不知道该怎么编排,但团队里惊喜的成果越来越多,我们已经迫不及待把更新的内容端上来给大家啦!那么事不宜迟,快来看看都有什么新情报吧ദ്ദി˶ー̀֊ー́ )✧ 一.美术(重磅升级) 以主美小为的生命力作为燃料(bushi)本次美术组取得了大进程!首先是各个ui界面的优化和细化,上次大家看到时还只是初具雏形的草稿,现在大多都完整起来了哦! 同时,随着配色的补全,手
43 赞
36 回复
00:34
《荒原复苏指南》开发日志④:关卡演示堂堂袭来!!截图
《荒原复苏指南》开发日志④:关卡演示堂堂袭来!!
- 人类曾因掌握元素合成技术而一度辉煌,又因滥用元素能量而逐渐从内里衰败。 - 30世纪80年代。社会文化充斥着激进乐观主义与庞大机械美学,在这里,污染和能源共生,幸福与痛苦并存。官方广播和宣传画里依旧在宣扬“科学将战胜一切”、“元素能量将再造新农田”的口号,而世界主城却已经因为污染过度而濒临崩溃、空间挤压严重。为了寻找新的生存空间与无污染能源,官方启动了“重构拓荒计划”。 - 玩家将作为前线拓展
18 赞
6 回复
《源墨名出》开发者日志 01|情绪会变成颜色,也会淤成一团墨截图
《源墨名出》开发者日志 01|情绪会变成颜色,也会淤成一团墨
大家好,这里是脑洞俱乐部,很高兴能够站在这里与大家一同参加本次聚光灯大赛。 10 月 1 号题目公布 ——「涌现」。我们盯着这两个字沉默了三分钟,然后有人说:要不,我们聊聊情绪吧。 于是就有了《源墨名出》 我们是怎么理解 "涌现" 的? 我们觉得,情绪这东西本来是看不见的。但当它被你看见、被你说出口、被人接住的时候,它就 "涌现" 成了具体的样子 —— 我们让它涌现成了颜色。 红是愤怒,橙是喜悦,
15 赞
13 回复
【2026聚光灯日志01】什么叫你把手牌,骰子和战棋融合了?截图
【2026聚光灯日志01】什么叫你把手牌,骰子和战棋融合了?
大家好啊,我是官方小编,一位还在学校的独自开发的苦逼带学生 这次算是第二次正式参加GameJam,而这回的比赛主题是【涌现】 嗯…老实说,一开始我还真只是从中文语义上来看,理解成“大量的出现”,直到询问ai哦哦哦我这就才想起来还有英文的“整体大于部分之和”意思来着 说起这个主题的意思,立马想起的类 吸血鬼幸存者 ,或者是 文明 系列的各种爆怪,爆兵的设计,即大量的出现敌人或者单位 而从第二个
4 赞
4 回复
00:10
群迹·上取其下,下取其上截图
群迹·上取其下,下取其上
#聚光灯gamejam开发者日志 向大家汇报一下今日进度,目前在和蚁群的默认移动算法进行斗智斗勇。或许是我的AI对蚂蚁有别样的理解,其实最初写出的方案更接近于围绕着恒星公转的行星。 哦我还以为文章里可以插入多支视频视频,想要展示一些其它的运动方式,可惜了。那么就简单在上方传一个比较典型的,有点类似于蟑螂的运行方式。 目前仍在解决蚁群的随机运动,和玩家可操纵性之间的平衡问题。以及如各位所见,目前的
4 赞
1 回复
00:30
《失心》游戏开发者日志01|游戏UI迭代及实机演示截图
《失心》游戏开发者日志01|游戏UI迭代及实机演示
进入《失心》之前,玩家首先看到的是我们工作室 UNLOOK 的标识。我们将原来的标识转成 SVG,并让其中的红色瞳点转动、观察,再逐步显露完整字形,希望这个短暂的开场能带出一点好奇和不安。 这次《失心》的开局 UI,我们围绕小灵通(因为游戏的主要交互道具就是小灵通)做了几轮调整,希望玩家从打开游戏开始,就能感受到故事里的年代和气氛(故事年代背景为2000s)。 早期版本先确定了一个方向:把菜单放进
15 赞
10 回复
关注破1000了,谢谢大家!聊聊接下来的更新截图
关注破1000了,谢谢大家!聊聊接下来的更新
大家好,我们是 Black Field。 截至目前,《矿井小队:MinerBuddy》的热度已经超过1300,关注也超过1000人了。谢谢大家愿意来试玩,还花时间给我们写评价、提建议。 最近新收到的反馈我们也在看:视角用着别扭、教程里炮塔摆放后仍然无法推进、摆放位置提示不清楚,还有成就册里宝石稀有度的字太小。这些都是实实在在影响体验的问题,尤其是卡在教程、反复尝试也过不去的朋友,确实给大家添麻烦了
4 赞
1 回复