通关展厅游戏生成器
一句话:一句话、一份大纲或一套题库 → 一个能发给学生的单文件 HTML 闯关游戏,背景由博物馆资源自动配。
三种起点,同一条流水线:
| 你手上有什么 | 入口 | 到成品要几步 |
|---|---|---|
| 一句话(学科 + 年级 + 内容) | 出题 → scaffold 出骨架 → fill 填题 |
一轮对话 |
| 一份题库(Word/PDF/表格) | 抽取成 course.json |
半天 |
已有 course.json |
doctor 一条命令 |
1 分钟 |
已有产物案例:七年级上册历史《历史通关展厅》(4 单元 / 31 关 / 135 题 / 9MB,断网放映,公开课用)。
> 环境要求:只要 node 22+,别的都不用装。
> 不需要 npm install、不需要联网、零第三方依赖,脚本只用 node 内置模块。
> 没装 node 的电脑:双击根目录 启动.bat(壳经 PowerShell 运行,Windows 7+ 自带、无需安装)——它会自动在本机找 Node(PATH → 官方安装目录 → fnm / nvm / Volta / scoop / 本机 WorkBuddy 便携版),找到就直接进引导菜单;找不到会提示去 nodejs.org 装,并告诉你怎么直接看成品(examples/demo-output.html)。
> 启动.bat 是给「不会用命令行的人」准备的入口:做新展厅全程菜单引导,非技术同事拿到压缩包也能用。
> 验收命令:node -v 能出版本号即可开工。
一、功能范围(做与不做)
做
- 学科闯关 / 答题 / 史料判断 / 单元复习 / 单词默写 / 概念辨析,凡「题库 → 游戏」的转化。
- 从零起盘:scaffold.js 把「单元—章节—关卡」大纲变成合法 course.json,fill.js 按单元分批填题。
- 门厅式多单元结构(1~6 个单元,各带主题色与向导)。
- 关卡内:开场对白 → 逐题判断 → 判题解析 → 通关星级 → 知识卡解锁 → 错题本 → 打印复习单。
- 离线顾问:只给提示不给答案,本地关键词检索,不联网、不编造。
- 背景自动生成:按每关的关卡名 / 副标题 / 题干,从博物馆资源库匹配一件文物,生成该关专属的纹样 + 器形 + 色调背景(详见 references/background-and-museum.md)。
- 背景出处标注:侧栏显示「背景取自 ‹文物名› · ‹馆名› · ‹年代›」,并声明按元数据再绘、非文物图像。
- 一条命令验收:doctor.js 跑完数据校验、构建、产物校验、交付体检,直接回答「能不能发」。
- 单文件交付:断网可放映、手机平板免安装、进度存在本机。
不做(明确边界,别硬塞)
- 不做账号系统、不做班级排行榜(要联网就另走云服务)。
- 不做自动判分上传、不做多人对战。
- 不是通用「刷题 App」:不支持填空/简答自动判分,题目一律单选。
- 不下载、不内嵌馆藏照片:背景是按元数据再绘的抽象 SVG,不是文物图像复制品;要真实配图请自行准备并内联。
- 不做写实复原:生成图不追求考古准确度,只用来「定调」,不用于展示文物长什么样。
- 不替用户编教材页码:src 里拿不准的课次,写「依据:本课重点」,不要瞎编「第 87 页」。
- 不改用户题目原意:用户给的题,只补 hint/fb/src,不擅自换题干。
二、输入 / 输出
| 内容 | |
|---|---|
| 输入 A(最简) | 一句话或一份 outline.json:标题 + 单元 → 章节 → 关卡名(三十行可覆盖一个学期) |
| 输入 B(标准) | 一份 course.json:meta(标题、副标题、版本)+ units[](单元 → 章节 → 关卡 → 题目)。字段见 references/question-schema.md |
| 输入 C(可选) | 博物馆资源库 assets/museum/resources.json(自带 42 条=36 条中国史 + 6 条通用,--museum 可换);关卡可用 museum / bg 字段指定某件文物 |
| 输出 | 一个自包含 .html(默认命名 标题-YYYYMMDD.html),内含门厅壳 + 各单元页面 + 每关背景 SVG,零外链 |
| 附带 | fill 的写入回执(哪几关写进去了)、doctor 的交付体检(体积/题量/占位/背景命中)、背景匹配报告(--bg-report) |
| 可选 | 教师端看板、公众号教程页(references/legacy/ 里有旧版参考,按需改) |
三、核心逻辑(七条,改代码前先读)
-
一层 JSON,两层页面
course.json→build.js为每个单元渲染一份独立 HTML → 全部塞进外层壳的<script id="pdata">。
点卡片时iframe.srcdoc = pages[id],location.hash = #u1可直达、可单发一个单元。 -
先骨架,后内容
结构(层级、字段名、必填项、id、主色)由scaffold.js生成,内容(题干、选项、解析)才由人或 AI 写。
混在一起的结果是:一处缩进错了,整份数据报废。分开之后,报错只会指向「你写的那句话」,不会指向结构。 -
火种 = 容错,迷雾 = 进度
每关初始火种 100,答错扣 20,归零本关重来(错题已入库,不白错)。
迷雾层数 = 本关题数,答对拨开一层;全拨开通关,按正确率给 1~3 星。 -
判题即教学
点了选项立刻给两段:fb(为什么对/错)+src(依据课次或方法论提示)。
错答时额外展示正解与正解解析——错要错得明白,这是它区别于普通刷题的地方。 -
顾问只给台阶
hint是唯一数据源。检索用「二字组重叠数」打分,命中最相近的一题就给那题的hint,从不直接输出答案。
这是刻意的:给答案等于废掉思考,公开课上也不好交代。 -
一切留在本机
进度写localStorage['tg_<unitId>'],无网络请求、无埋点。断网 = 功能完整。 -
背景=元数据再绘,不是图片
每关的关卡名(权重 5)、副标题(3)、章节与单元时代(2)、对白与题干(1)拼成语料,与资源库keywords打分,≥4 分才认一件文物。命中后用它的palette生成色调光斑、motif生成 400×400 平铺纹样、form生成 1200×800 器形线描——全是构建期生成的 SVG 字符串,零位图、零外链、单关 <8KB。
匹配不上就降级(单元主色 + 通用纹样),绝不因此让构建或游戏失败;降级时不显示假出处。
细节与五级降级矩阵见references/background-and-museum.md。
四、使用场景(挑一个照着走)
场景 A:老师有一套题,想做成复习游戏
1. 把题目按 references/question-schema.md 填进 course.json(或让 agent 从 Word/PDF 题库抽取并结构化)。
2. node scripts/validate.js course.json 修到全绿。
3. node scripts/build.js course.json 通关展厅-20261101.html。
4. 打开产物自己走一遍第一关,确认题干/解析/加扣分符合预期,再发给学生。
场景 A′:手上只有一句话,什么都没有
1. 写 30 行 outline.json(只需单元 / 章节 / 关卡名)。
2. node scripts/scaffold.js outline.json course.json --tags "史料实证,时空观念,历史解释"。
3. 分批写题:node scripts/fill.js course.json u1-题目.json(一次一个单元)。
4. node scripts/doctor.js course.json 通关展厅-20261101.html → 看到「可以交付」为止。
完整流程见 references/auto-pipeline.md。
场景 B:公开课 / 示范课现场
- 提前用 #u3 直达要讲的那个单元,避免现场翻菜单。
- 断网演练一次:拔网线后刷新,确认还能玩(本来就零外链)。
- 备一份「全对路线」,避免现场卡在难题上;references/question-schema.md 的口径部分有出题建议。
场景 C:单元复习 / 假期作业
- 让学生自带设备打开链接或本地文件,进度各存各的。
- 通关后点「打印复习单」,把错题和知识卡打成一张 A4,纸质留档。
场景 D:换成别的学科(已用七年级上册地理实测跑通)
- 只需换 course.json,模板一行都不用动。
- 别人最快上手的方式:打开 examples/geo-output.html 看成品(七年级上册地理,2 单元 / 4 关 / 12 题)——它的数据是 examples/geo-course.json、大纲是 examples/geo-outline.json、其中第 1 关的真题见 examples/geo-fill-sample.json(演示 fill.js 的填法)。
- 门厅 / 封面 / 地图 / 火种 / 迷雾 / 星级 / 知识卡 / 错题本 / 打印 / 背景层结构与历史版完全一致,只有文字和向导名不同。地理版实测:3 题全对 → ★★★、火种 100/100、出处降级为「古舆图(通用)」且不编造文物名。
- 背景:资源库末尾 6 条 gen-*(卷轴 / 印 / 舆图 / 瓷 / 钱 / 陶片)就是给非历史学科兜底的;不够就照格式加条目,只写元数据、不用准备图。
- 向导可以是任何学科符号(一块化石、一支试管、一个齿轮)。
场景 E:想要文物质感,但不想找图、怕版权
1. 什么都不用配置,build.js 默认就会按每关文本自动配背景。
2. --bg-report 报告.json 看匹配结果,哪关没配上,加一行 "museum": "文物名" 即可。
3. 背景是参数化 SVG,没有馆藏照片,对外发表、做成校本教材都不必单独处理图片授权。
4. 觉得背景太抢或太淡,按 references/background-and-museum.md 第 7.4 节调 2~3 个数值即可。
场景 F:把这个 skill 交给别人用
- 对方需要的只有三样:一份 outline.json、他自己的学科知识、一条 doctor.js 命令。
- 不用懂 JS、不用装依赖(有 node 就行)、不用联网。
- 他不该改的是:模板结构、判题逻辑、背景生成器;他该改的只有 course.json 里的文字。
- 交付话术模板在 references/auto-pipeline.md 第四节,可直接抄。
- 换压缩包给别人时:整个目录打包,解压后双击 启动.bat 就有引导菜单(自动找 Node,没有就给下载提示 + 看成品通道);会命令行的人仍然可以直接 node scripts/doctor.js,两条路都通,没有安装步骤。
- 使用说明.txt 是给非技术同事看的一页纸(三种用法对号入座 + 常见问题),打包时已在包里,转发时不用另写。
五、工作流(agent 照此执行)
- 澄清(信息不全就先问,最多问 3 个):
学科与年级、几个单元 / 每关几题、题库来源(用户给 / 让我出 / 从文档抽)。
缺省就按默认值走:每关 3 题、一章 2~3 关、向导取单元代表性器物——别让用户填表。 - 出骨架:
outline.json→node scripts/scaffold.js outline.json course.json --tags "…"。
已有题库则跳过,直接按 schema 组织course.json。 - 分批填题:一次一个单元 →
node scripts/fill.js course.json u1-题目.json。
每批写完跑一次validate.js,错在哪一关会直接报出来。 - 一键验收:
node scripts/doctor.js course.json <输出名-YYYYMMDD.html>。
退出码 0=可交付,2=还有【待填】,1=有硬错误(按提示改)。 - 看背景报告:doctor 会报「命中 N 关 / 降级 N 关」。降级的要么加
"museum": "文物名",要么给资源库补keywords;也可以接受降级——不影响玩法。 - 自测:见第七节 checklist,至少走通「门厅 → 单元 → 一关 → 结算 → 返回」。
- 交付:给文件 + 一句「怎么发、怎么打开、体积多少」。
命令行(Windows 下 node 在 C:\Users\<用户>\.workbuddy\binaries\node\versions\<ver>\node.exe,已在 PATH 时直接 node):
# 从零起盘
node scripts/scaffold.js outline.json course.json --tags "史料实证,时空观念,历史解释"
node scripts/fill.js course.json u1-题目.json --dry # 先看会写到哪几关
node scripts/fill.js course.json u1-题目.json # 写入(自动留一次 .bak)
# 一条命令验收(体检 + 构建 + 复查)
node scripts/doctor.js course.json 通关展厅-20261101.html
# 分步做(要单独控制时)
node scripts/validate.js course.json
node scripts/build.js course.json 通关展厅-20261101.html --bg-report 背景报告.json
node scripts/validate.js course.json 通关展厅-20261101.html
# 背景相关开关
# --museum <路径> 换一份资源库
# --no-bg 关闭背景(排查用,回落到纯渐变)
# --bg-report <路径> 输出逐关匹配报告 JSON
六、硬约束与已知坑
硬约束
- 单文件、零外链:validate.js 会扫 http(s):// 引用(背景 SVG 只允许 xmlns 命名空间,不允许任何 href="http)。
- ≤10MB:体积几乎全来自内联图片。先把图压到 150KB 以内再内联,同一张图只存一份。背景 SVG 单关 <8KB,不是体积大头。
- 移动端:模板已做流式布局(<860px 隐藏侧栏、HUD 单列),改样式后必须在 390 宽下看一眼有没有横向滚动。
- 背景不得影响可读性:遮罩层 .bg-veil 不要去掉,纹样 A 值不要超过 0.12。
踩过的坑(按出现频率)
1. 内联 JSON 里出现 </script> → 页面直接白屏。build.js 已把 < 转成 \u003c,手改产物时别破坏。
2. iframe 高度塌成 150px → 必须显式 height:calc(100% - 46px);用 100vh 在移动端会被地址栏坑。
3. <span> 当容器量高度:内联元素不吃 height,进度条会撑成 156px 把卡片顶破。条、块一律 display:block。
4. 全对却卡在「结算」 → 空队列保护:最后一题答完要直接进结算,不能再去取下一题。
5. localStorage 在无痕/隐私模式不持久 → 门厅说明里写清「换个浏览器或关掉无痕」。
6. 微信「文件预览」打不开脚本 → 让学生「用浏览器打开」,或托管成链接/二维码。
7. 同名目录反复解压套娃 → 交付目录与压缩包一律带日期:通关展厅-YYYYMMDD。
8. SVG 塞进 data URI 必须 encodeURIComponent → 色值里的 # 会把 URL 截断,背景直接消失(表现为「配了但看不见」)。
9. 纹样 opacity 别超过 0.12 → 超过就像给整页罩了层网格,正文发花。首版用 0.16 实测压字,降到 0.085 才合适;同时 .bg-motif 必须带径向 mask-image,让中央干净。
10. xmlns="http://www.w3.org/2000/svg" 不是外链 → 校验器若按 http 全串扫描会全部误报,要用 href="http / url(http 这类真正引资源的模式。
11. 器形放右下会被侧栏面板压住 → 落在左下空白区(background-position:left … bottom)才看得见;右侧是侧栏,别放。
12. 旧数据没有 bg 字段 → paintBG 必须早退而不是报错,否则老产物一进关卡就白屏。
13. scaffold 生成的占位题能通过 validate → 结构合法但内容是空的。validate 查不出「写了但没写对内容」,所以交付前必须看 doctor 的【待填】计数,且逐题读过一遍。
14. fill.js 按关卡名定位,不按序号(序号只是备用)→ 改了关卡名要同步改填题文件,否则它会报「找不到关卡」并列出可选名字。这是设计如此:宁可报错,也不要悄悄写到隔壁关。
15. 窄屏(<860px)会隐藏右侧栏,版权声明会跟着消失 → 侧栏里的「背景取自…非文物图像」在手机端看不见。已加 #bgTag:窄屏时改成屏幕底部一行小字(通栏、padding-right 避开右下角顾问按钮、pointer-events:none),离开关卡页由 go() 清空。改背景层时必须同时看 390 宽,用 Emulation.setDeviceMetricsOverride 真机模拟,别用 headless 窗口宽度(它会被钳制到 492)。
七、交付 checklist
- [ ]
doctor.js退出码为 0,且没有【待填】 - [ ] 每一道题都读过:干扰项不是「荒谬项」,解析指出了错在哪一步
- [ ]
validate.js数据检查全绿(每题 1 个正确项、每题有 hint、无空题干) - [ ] 产物体积 ≤10MB,零外链(校验器「背景零外链」也要 OK)
- [ ] 门厅卡片数、关卡数、题数与 JSON 一致
- [ ] 走通一关:剧情 → 选项 → 判题解析 → 下一题 → 关卡结算(星级/正确率)
- [ ] 故意答错一题:火种 −20、错题进错题本、迷雾不减
- [ ] 回地图:该关出现星星,下一关解锁
- [ ] 顾问:问一个知识点,只给提示不给答案
- [ ] 背景:进两关,确认背景随关卡变化、侧栏「背景取自…」出处正确
- [ ] 背景:截图目视确认纹样/器形没压住题干与选项
- [ ] 背景:
--bg-report里降级关卡已确认(补了 museum/keywords,或接受降级) - [ ] 390 宽手机视口:无横向溢出,选项可点
- [ ] 断网刷新仍可玩
- [ ] 文件名带
YYYYMMDD版本号
八、目录结构
SKILL.md ← 本文件
启动.bat ← 免安装版入口:双击出引导菜单(壳,纯 ASCII,任何语言版 Windows 可解析)
launcher.ps1 ← 启动器主逻辑(PowerShell 5.1+,Windows 7+ 自带;必须保持 UTF-8 带 BOM)
使用说明.txt ← 给使用者的一页纸:三种用法对号入座 + 常见问题
projects/ ← 用户项目目录(启动.bat 自动创建:outline / course / questions + 成品)
templates/shell.html ← 门厅壳(卡片/路由/进度)
templates/unit.html ← 单元引擎(剧情/判题/结算/顾问/背景层)
scripts/scaffold.js ← 大纲 → 合法 course.json 骨架(题目为占位)
scripts/fill.js ← 按单元分批填题(定位不到就报错,不乱写)
scripts/doctor.js ← 一条命令:校验 → 构建 → 复查 → 交付体检
scripts/build.js ← course.json → 单文件 HTML(含背景装配)
scripts/validate.js ← 数据 + 产物校验(含背景引用与外链)
scripts/museum.js ← 背景生成器:资源匹配 + 纹样/器形 SVG + 降级
assets/museum/resources.json ← 博物馆资源库(42 条元数据,无图片)
references/question-schema.md ← 字段规范与出题口径
references/background-and-museum.md ← 背景机制的完整说明(职责/输入输出/降级矩阵)
references/auto-pipeline.md ← 一句话 → 成品的自动流程(给 agent 的操作手册)
examples/demo-course.json ← 可直接跑的样例(2 单元 / 5 关 / 15 题)
examples/demo-output.html ← 上面这份样例的产物,双击即可看效果
examples/outline-sample.json ← 骨架样例:拿它跑 scaffold 就能生成一份新 course.json
examples/geo-outline.json ← 跨学科样例大纲(七年级上册地理)
examples/geo-course.json ← 上面大纲生成的骨架,第 1 关已填真题
examples/geo-fill-sample.json ← 演示 fill.js 怎么把真题写进关卡
examples/geo-output.html ← 地理版成品:**同一套架构、完全不同的内容**,双击即可看
references/legacy/ ← 旧版参考:四单元完整壳、教师端看板、早期 schema(大项目再翻)
先看效果再动手:直接打开 examples/demo-output.html,玩一遍就知道这套东西长什么样;要改内容只动 examples/demo-course.json,重跑 doctor 即可。