feat: version campaigns and document original puzzle design

Restore v0.1 and v0.2 archives with separate progress, publish the curved v0.3 campaign, and document the original 24-level design with reproducible evidence. Refine board presentation and movement, and keep video lab tooling within its own directory.
This commit is contained in:
cabinw
2026-09-09 13:17:30 +08:00
parent 70b021d4cc
commit e92cccba82
52 changed files with 76449 additions and 15076 deletions
+235
View File
@@ -0,0 +1,235 @@
# v0.1 · 最初 24 关的设计理念
**原始 24 关围绕“旋转换路、逐层让路、解开交织轨道”组织体验。** 玩家先找出当前能离场的棋子,移开它们改变占用关系,再通过旋转底盘改变路线,逐步把整盘解开。每一次操作都应能让玩家理解后续条件发生了什么变化。
这是对原始实现的设计归纳。本文以初始提交 `ef2724b` 的说明、生成器、规则、测试及原始 24 关布局为依据,记录已实现的结构与可继承的理念,供后续关卡优化对照。本次只整理文档和分析证据,未修改任何版本的关卡。
## 1. 先明确原版的核心体验
原版让玩家处理三个互相影响的问题:
1. **路线问题:** 这枚棋子从箭头方向出发,沿途会走到哪里?
2. **空间问题:** 它的整个身体能否通过?需要先移开哪一枚棋子?
3. **朝向问题:** 当前路线走不通,底盘换一个朝向后,哪些出口和阻挡关系会改变?
核心体验可以归纳为:**看懂关系 → 找到突破口 → 让局面松开 → 换一个朝向继续解。** 其中“局面松开”既可以来自移走障碍,也可以来自重新接通轨道。长路径的成功离场,则把之前逐步清理的结果展示出来。
原版采用轻量点击与 60° 整盘旋转,规则动作少,但同一套轨道与棋子会形成多阶段关系。以下章节将“历史明确规定”“布局中实际存在的结构”“本次体验解释”分别说明,不把后来的制作标准反写为原始要求。
## 2. 六项设计支柱
### 2.1 旋转承担解题作用
**历史事实:** 生成器会剔除不需要旋转的候选,原测试也要求每一关在不旋转时无法清空。24 关全部至少需要 1 次旋转;其中 12 关需要 1 次、8 关需要 2 次、4 关需要 3 次。
旋转时,上层棋子的位置和箭头保持不变,下层的格子位置与轨道连接整体变化。玩家重新判断的是路线、出口和阻挡,而不只是观看盘面转动。
**设计归纳:** 旋转是关卡内容的一部分,应与当前清场状态发生联系。原版存在“清掉一批,再换路”的阶段,也存在“转过去移走一个关键棋子,再转回来”的结构。后者说明同一个朝向在不同占用状态下会产生不同的解题机会。
### 2.2 棋子之间存在可推演的让路关系
**历史事实:** 最初 24 关开局合计 404 枚棋子,只有 125 枚可以直接离场,约占 30.9%。每关都有可行开局,但都无法仅靠初始朝向一路清空。参考解答包含 3–13 个消除批次。
这里的“批次”指求解器在一个状态下找到的全部可离场棋子;移除这批后,再寻找下一批。它是结构指标,不能当作玩家必须严格执行的唯一点击顺序,也不等于真人思考次数。
**设计归纳:** 棋子的价值同时来自自身路线和它为其他棋子占据的空间。一个容易移走的棋子也可能承担关键的让路作用。玩家的收获包含“原来移走它,就能放出后面这一串”。
原求解器依赖一个重要性质:安全移走棋子只会减少障碍,不会凭空破坏其他路线。因此,关系可以复杂,但并不要求玩家担心一次合法消除永久毁掉关卡。关卡可以有多种安全操作顺序。
### 2.3 判断完整的移动空间
**历史明确规定:** 棋子整个顶面参与连续碰撞检测,路径经过的格子为空,也可能在转角或经过相邻格之间时擦到另一枚棋子。交叉轨道不会自动换线,颜色不参与解题规则。
**布局事实:** 原版 24 关均有初始侧擦阻挡,共涉及 119 枚棋子。此处统计的是:实际发生阻挡,但阻挡棋子所在格不属于移动棋子的独立中心路线所经过的格子。
**设计归纳:** 玩家既要读线,也要判断棋子的宽度和通行空间。这里产生的是空间关系题。后续表现可以把接触位置和阻挡对象解释得更清楚;是否保留某类侧擦结构,需要结合可读性讨论,不能把“碰撞规则存在”和“所有擦碰都容易看懂”混为一谈。
### 2.4 短出口、让路棋子与长绕行共同组成内容
**历史事实:** 原生成器给候选路径的经过格数加权,偏向更长的路线;它并没有“每关至少多少比例经过弯道”的要求。固定原引擎回放 24 关,404 次成功消除中有 227 次经过弯道,占 56.2%;其余是直出。最长一条成功路径有 16 次转弯。
直出与弯轨在原版中共同工作。容易离场的外围棋子可能先释放空间;更深处的路线在障碍移开和朝向变化后才可贯通。不能仅从一枚棋子自身走得短,就判定它没有解题作用。
**设计归纳:** 需要关注“这条路线怎样参与整盘关系”。弯道数量可以描述阅读量,但无法单独代表旋转价值、解锁关系或阶段变化。原版长绕行所带来的观察内容,也不能用大量彼此独立的单弯路径完全替代。
### 2.5 同一盘面可以经历多个解题阶段
原版允许当前朝向下出现无法直接离场的状态,只要可以通过后续旋转完成。初始独立路线中共有 6 个闭环,分别出现在第 1、6、7、16、20、21 关。
其中第 1 关“清到最后一枚后,它的路线仍为闭环,向右转一次后离场”被明确写入历史测试。闭环在初始独立路线中就已存在,移除棋子不会让轨道新形成闭环。第 22 关的参考解还包含“转一次仍无出口,再转一次才有出口”的阶段。原版没有要求每一枚棋子在所有六个朝向下都能独立离场,也没有承诺每次必要旋转立刻获得出口。
**设计归纳:** 局部走不通可以构成换路理由,阶段之间可以有关联。但这种状态也可能使玩家不理解最后一枚为何走不了,需要清楚的路线反馈。闭环是否适合第一关、连续旋转如何给出线索,属于后续教学和反馈问题;原版存在这些结构,不等于必须原样复制它们的呈现缺点。
### 2.6 后期加深关系,盘面体量较早稳定
**历史事实:** 首章混合 19 格与 37 格,第 5、8 关已使用 37 格;第二、三章均为 37 格。最大棋子数出现在第 15 关,共 24 枚;最终关为 18 枚。第三章的全部关卡需要 2–3 次旋转。
**设计归纳:** 原版后期主要增加需要追踪的关系、绕行程度与旋转阶段。相同大小的盘面可以逐渐表达更复杂的题目,关卡体量不必不断增长。规模、空间密度、路线长度和关系深度应分别说明。
## 3. 用原关卡理解这些原则
### 第 1 关:先让路,再理解旋转换路
19 格、5 枚棋子,历史分数 25。以原数据 ID 标识棋子,参考解如下;ID 仅方便设计师在数据和工坊中核对。
| 阶段 | 实际状态 | 所表达的关系 |
| --- | --- | --- |
| 开局 | `t0`、`t2`、`t4` 可离场;`t1` 被 `t0` 挡住 | 有明确入口,同时有一层让路关系 |
| 先清理 | 移走开局可行棋子,`t1` 获得出口 | 成功消除改变其他棋子的条件 |
| 剩最后一枚 | `t3` 在这个朝向的独立轨道是闭环 | 清空障碍后,路线问题仍需处理 |
| 向右转 60° | `t3` 获得出口,随后离场 | 旋转改变路线,完成整关 |
这关把“让路”与“换路”放在同一局里。最初版本的教学重点包含旋转的必要性。如今 v0.3 第 1 关的“8 枚全可走、各转一个弯”则承担另一种教学目标:认识沿轨转向。两者的结构功能不同。
### 第 17 关:回到原朝向,局面已经不同
20 枚棋子,最少需要 2 次旋转。参考解先清理到剩余 5 枚,再出现以下过程:
```mermaid
flowchart LR
A[原朝向:剩 5 枚,无出口] -->|向右转 60°| B[t1 获得出口]
B -->|移走 t1| C[剩 4 枚,当前无出口]
C -->|向左转 60°| D[回到原朝向,t0 获得出口]
D --> E[继续逐步清空]
```
这一例最能表达旋转与消除的相互作用:回到同一个朝向不等于回到同一个局面,因为棋子的占用已经变化。解题对象是“朝向与剩余棋子共同构成的状态”。
### 第 24 关:在固定体量中分阶段解开长路
37 格、18 枚棋子,历史分数 75。参考解先移走 7 枚,随后经历三次向右旋转;三次旋转分别发生在剩余 11、9、6 枚时。每一阶段先处理当时打开的出口,再继续换路。
最后一段中出现 12、13、14、15 次转弯的成功路径。这些长路径与先前清场、换路形成连续关系。最终关的棋子数少于第 15 关,却包含更多旋转阶段与更长的绕行,说明原版高潮来自关系组合。
## 4. 原始章节与难度递进
历史地图分为三章,每章 8 关。原版整体按旧评分非递减排列,没有后来的“挑战—释放—长局回报”六拍结构。
| 章节 | 历史分数 | 实际盘面 | 最少旋转 | 平均消除批次 | 开局可离场比例逐关均值 |
| --- | --- | --- | --- | ---: | ---: |
| 转盘初体验(1–8) | 25–49 | 19 / 37 格 | 1–2 次 | 5.75 | 40.6% |
| 糖果回旋(9–16) | 50–59 | 37 格 | 1–2 次 | 8.63 | 30.8% |
| 碰撞大挑战(17–24) | 60–75 | 37 格 | 2–3 次 | 10.38 | 27.3% |
上述逐关比例均值与全体棋子的加权比例 30.9% 使用不同口径。批次数也是参考解的结构信息;这些数字支持“后期关系更深、初始选择比例更少”的归纳,不能据此宣称已经验证玩家感到更有趣或更流畅。
章节名称提供了体验主题,但原制作过程主要是程序生成、可解性筛选和评分排序。没有证据证明 24 关最初就有逐关人工编写、逐项隔离新机制的教学剧本。本文的案例解读是对已存在结构的整理。
## 5. 原版怎样生成与筛选关卡
1. 为六边形格子随机生成完整的六端口配对,保持轨道连续和交叉不换线规则。
2. 逆向插入棋子:新加入的棋子必须能在已有棋子存在时先离场,以建立可解布局。
3. 候选位置和方向按随机项与经过格数加权,从靠前候选中抽取,让盘面保留变化与绕行。
4. 将初始底盘旋转 1–3 次,重新求解,剔除不可达以及无需旋转即可完成的候选。
5. 按旧步数规则,为最短解之外留出一定余量,再计算难度。
6. 按评分排序,选取 24 关,并使用完整动作序列回放验证。
生成脚本中的目标棋子数不是最终棋子数:逆向插入可能提前停止。原始脚本给 37 格候选设置过 16–33 枚的目标范围,但实际发布的 24 关最多 24 枚。解释已发布版本时,以归档布局为准。
原版的硬要求是:**规则一致、确实可解、每关必须旋转、整体评分递进。** 弯路覆盖率、六朝向全部无闭环、参考决策状态不许侧擦、相邻消除间最多一次旋转,都不是当时的发布标准。
## 6. 历史评分与尝试成本
原评分同时考虑以下六项:
| 因素 | 上限 | 原始意图或作用 |
| --- | ---: | --- |
| 棋子规模 | 15 | 用棋子数量粗略描述处理量;没有直接按棋盘面积加分 |
| 平均转弯 | 20 | 描述初始朝向下、忽略占用的路线追踪量 |
| 解锁层数 | 20 | 描述参考解的分批释放过程 |
| 初始阻塞 | 15 | 可立即离场的选择越少,分数越高 |
| 必要旋转 | 20 | 将换路需求作为重要的挑战来源 |
| 步数压力 | 10 | 可用步数越接近最短解,容错越少 |
历史最短步数是“棋子数 + 最少旋转数”。当时成功点击、失败试路和旋转都扣步,实际关卡在最优解以外留有 2–7 步余量。撤销恢复状态,没有倒计时。
这些是历史实现事实。**当前已经采用的免费旋转、免费失败试路规则继续有效;整理原版理念不构成恢复扣步惩罚的决定。** 旋转是否免费,与关卡是否需要玩家判断何时换路,是可以分别设计的两个问题。
同样,原版把规模和尝试压力计入难度,也不意味着后续必须恢复旧公式。保留清晰的空间与路线关系,可以与规模、工作量分开计量以及起伏式节奏同时成立。原评分从未经过真人通关率校准,不能被当作客观心理难度。
## 7. 后续两版具体改变了什么
下表统一使用固定的原始引擎复算,以隔离后续评分和碰撞实现变化。布局来源及哈希见[分析证据](v0.1-design-evidence.json)。后两版的参考回放使用充足额度,只比较路线结构;不将旧扣步规则重新应用到现行玩法。
| 结构指标 | v0.1 原始 24 关 | v0.2 直线较多版 | v0.3 弯轨观察版 |
| --- | ---: | ---: | ---: |
| 必须旋转才能完成 | 24 / 24 关 | 16 / 48 关 | 16 / 48 关 |
| 参考消除批次数范围 | 3–13 | 1–5 | 1–6 |
| 初始可离场棋子占全部棋子比例 | 30.9% | 38.6% | 44.8% |
| 成功消除路径经过弯道的比例 | 56.2% | 7.0% | 75.1% |
| 每条弯轨成功路径的平均转弯数 | 3.75 | 1.45 | 1.25 |
这些结果说明:v0.2 明显增加了宽松直出;v0.3 增加了真实弯轨路径,但这些弯轨平均更短,必须换路的关卡占比和分批释放层次仍低于原版。**弯道占比提高,不能单独证明原来的解谜关系已经恢复。**
后续制作还采用了全六朝向独立路线无闭环、参考决策状态排除侧擦、限制连续无进展旋转等筛选。这些要求着眼于减少难以解释的反馈,也同时缩小了可用的空间和换路结构。后续优化需要分别审视可读性、关系深度和舒缓节奏,不能用一个“更好走”的条件替代全部目标。
这里记录的是设计方向的变化及结构证据,没有真人通关率或体验数据来决定哪组数值最优。
## 8. 留给下一轮优化的对照基准
以下是基于原版整理的检查问题,供下一轮逐关讨论,不是本轮自动执行的新生成门槛。
| 要保留的设计价值 | 评审时应能说明 |
| --- | --- |
| 旋转有解题意义 | 哪个局面需要换路?转动后改变了谁的出口或阻挡? |
| 移除会改变局面 | 哪些棋子承担让路作用?它们离场后释放了什么? |
| 路线承担实际内容 | 短出口与长绕行各自负责什么?弯道是否参与后续关系? |
| 同一盘面有阶段 | 清理、换路、继续清理之间如何关联?是否存在值得理解的状态变化? |
| 空间关系可读 | 玩家能否解释真实接触位置?反馈不足时,应改表现还是改布局? |
| 难度可控 | 这一关主要增加的是关系深度、路线追踪、选择压力,还是工作量? |
需要在下一轮另行确定的内容包括:每关必转是否保留为全局要求,教学和舒缓关如何例外;闭环和连续旋转在什么条件下适用;碰撞可读性如何改进;长路线如何兼顾观察与动画节奏;原有解题结构怎样融入后续的大盘和起伏节奏。
免费旋转、免费失败试路,以及已经恢复的三版独立关卡与进度保持现状。后续可在此基准上优化并发布新版本,原始 24 关归档继续保留。
## 9. 原始 24 关结构清单
“开局可走”表示初始朝向下真实无碰撞离场的数量;“批次”来自原求解器参考解;“旧分数”用原评分重算,不能与当前界面分数直接比较。
| 关 | 名称 | 格数 | 棋子 | 开局可走 | 必要旋转 | 消除批次 | 旧分数 |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 1 | 转一转,路就通了 | 19 | 5 | 3 | 1 | 3 | 25 |
| 2 | 换个方向 | 19 | 6 | 3 | 1 | 4 | 31 |
| 3 | 弯道别碰头 | 19 | 12 | 6 | 2 | 5 | 38 |
| 4 | 给我让条路 | 19 | 13 | 5 | 1 | 8 | 44 |
| 5 | 粉色回旋 | 37 | 16 | 5 | 1 | 5 | 45 |
| 6 | 蓝色小径 | 19 | 12 | 3 | 1 | 8 | 47 |
| 7 | 向左看齐 | 19 | 11 | 4 | 2 | 7 | 49 |
| 8 | 转角遇见光 | 37 | 18 | 6 | 1 | 6 | 49 |
| 9 | 第一圈冒险 | 37 | 18 | 7 | 1 | 9 | 50 |
| 10 | 旋转甜甜圈 | 37 | 21 | 8 | 1 | 8 | 51 |
| 11 | 差一点擦肩 | 37 | 18 | 6 | 1 | 8 | 52 |
| 12 | 紫色回廊 | 37 | 19 | 6 | 1 | 9 | 53 |
| 13 | 再转一次 | 37 | 20 | 5 | 1 | 9 | 54 |
| 14 | 绕开拥挤 | 37 | 17 | 5 | 2 | 8 | 55 |
| 15 | 小心翼翼 | 37 | 24 | 5 | 1 | 11 | 57 |
| 16 | 别挤在一起 | 37 | 17 | 5 | 2 | 7 | 59 |
| 17 | 糖果交响曲 | 37 | 20 | 7 | 2 | 9 | 60 |
| 18 | 盘旋之间 | 37 | 21 | 7 | 2 | 12 | 61 |
| 19 | 左右逢源 | 37 | 17 | 4 | 2 | 8 | 62 |
| 20 | 寻找缝隙 | 37 | 21 | 7 | 3 | 10 | 66 |
| 21 | 回转大挑战 | 37 | 20 | 5 | 3 | 10 | 68 |
| 22 | 紧密相连 | 37 | 21 | 4 | 3 | 13 | 68 |
| 23 | 终极转盘 | 37 | 19 | 4 | 2 | 11 | 69 |
| 24 | 六角大满贯 | 37 | 18 | 5 | 3 | 10 | 75 |
## 10. 来源、复算方法与边界
- 原始布局:[v0.1.json](../levels/versions/v0.1.json),404 枚棋子,24 关;与 `ef2724b` 中的 `levels/campaign.json` 字节一致。
- 归档出处:[provenance.json](../levels/versions/provenance.json),记录完整提交、文件哈希与旧布局回放。
- 本次证据:[v0.1-design-evidence.json](v0.1-design-evidence.json),记录原引擎来源哈希、三版布局哈希、24 关开局状态、参考动作、旋转前后出口、消除批次与实际成功路线。
- 复算脚本:[analyze-v01-design.mjs](../scripts/analyze-v01-design.mjs)。运行 `node scripts/analyze-v01-design.mjs`;需要本地保留初始 Git 提交。脚本在临时目录加载历史引擎,仅输出证据 JSON,不改游戏规则或关卡。
历史源文件均以 `ef2724b` 为准,可通过 `git show ef2724b:文件路径` 查阅:
| 历史路径 | 主要依据 |
| --- | --- |
| `README.md`,21–27 行 | 路径、旋转、碰撞、尝试成本及全部关卡必须旋转 |
| `docs/video-analysis.md`,3–9 行 | 区分视频观察、补充规则与项目实现约定 |
| `docs/level-design.md`,34–72 行 | 旋转、连续碰撞、求解生成、旧评分及未做玩家标定的说明 |
| `scripts/generate-levels.mjs`,6–18 行 | 候选规模、初始旋转、必须旋转筛选、余量、排序与选关 |
| `src/core.js`,136–214 行 | 求解状态、消除批次、评分及逆向生成 |
| `src/app.js`,21–26 行 | 三章与每章八关 |
| `tests/core.test.js`,31–33、99–103 行 | 全 24 关验收,以及首关最后一枚闭环后旋转完成的预期行为 |
本文没有把参考视频中的遮挡轨道当作已完整复原的数据,也没有把生成规则推测成全部来自原视频。参考解答并非所有玩家顺序;统计描述结构,不代表真人体验已经验证。文中关于“让路”“阶段换路”“长路回报”的表达,是依据历史规则和回放所做的设计解释。