Kirino 的游戏宝藏
← 返回第 022 期
游戏观察

环道上的六只脚与二百五十六分之一像素:Trent Brew 如何把 Genesis《索尼克》手感,从「感觉」还原成可审计的离散仿真

Genesis 索尼克手感不是气氛调参,而是六传感器定点离散仿真(亚像素/hex 角/四模式/2.5 滑落与帧序)。

我的收藏 ↗

如果说当代 2D 平台的默认语法仍是「手感靠调参、动量靠 Rigidbody2D、碰撞交给 CharacterController,再在帖子里写一句我调了很久才像 Sonic」,那么 Trent Brew(u/trentbrew)在 2026 年 9 月 21 日把 Sonic Retro《Sonic Physics Guide》整包编成离线 Markdown 仓库、并丢进 r/gamedev 的那一刻,几乎是在当众把这套默认脚本翻过来:经典 Mega Drive《索尼克》的手感,从来不是艺术方向上的「感觉」,而是一套可逐帧核对的离散仿真。

这句话听起来像怀旧党的宣言。真正有重量的,是仓库里被钉死的规格表——1 像素 = 256 亚像素;角度用 0–255 的十六进制环;六只传感器脚(A/B 地面、C/D 天花板、E/F 墙壁)在四种碰撞模式里随环道旋转;地面速度低于约 2.5 像素/帧就会从陡坡滑脱;每帧执行顺序被写成 Player → Objects → Collision → Camera → V-INT。数字压住修辞之后,「手感」才第一次变成可审计、可复现、可交付给独立团队的系统。

贯穿本稿的意象,是环道上那六只脚。它们不是角色美术的附属物,而是整座动量世界的测量仪:脚踩到哪一块 16×16 固体砖、读到哪个角度字节、在 Floor / Right Wall / Ceiling / Left Wall 哪一档模式里被重新摆放,决定了你是贴着绿丘区的内环冲过去,还是以一种「看起来像、算起来却漂」的方式从墙上掉下来。

六传感器锚点:A/B 地面、C/D 天花板、E/F 墙壁

一、默认逻辑:手感等于气氛,动量等于引擎插值

行业默认逻辑其实很干净,也因此很偷懒。

做 2D 平台时,团队通常会打开一张熟悉的菜单:给刚体一点重力与摩擦,把跳跃冲量调到「感觉舒服」,用胶囊或盒体撞地,再靠引擎的连续碰撞检测挡住穿墙。Unity 的 CharacterController / Rigidbody2D、Godot 的 CharacterBody2D、各类「平台控制器」资源,都在帮你把「站得住、跳得起、不会卡缝」这三件事自动化。玩家也学会了用同一套语汇阅读动量平台——他们会说「手感不错」「有点像 Sonic」「还差点惯性」。这种默契让「手感」变成可被原谅的气氛词:它听起来专业,却几乎无法被复现。

经典 Genesis《索尼克》偏偏是最难被这套语法容纳的作品之一:360° 环道、坡度加速、贴墙贴顶、高速下仍要贴着砖面而不穿模。它最初对准的不是通用物理引擎的时间步长,而是 NTSC 60 Hz 下一帧一次的定点加减。把这样的体验塞进「调一下摩擦参数」的工作流,行业直觉几乎会自动指向「多试几天、凭感觉」。

Trent 的公开仓库却拒绝了这条捷径。README 写得很直白:这是 Sonic Retro 社区维护的《Sonic Physics Guide》的非官方衍生重排——把分散的 wiki 页转成 Markdown,把示意图与交叉链接本地化,好让人离线阅读与实现。注意措辞——被保护的不是某一款粉丝游戏的品牌联想,而是「手感是否仍然可以被准确描述」。描述一旦准确,气氛词就失去藏身之处。

这正是默认逻辑与制作伦理开始分叉的地方。气氛式手感默认问:再拧一点摩擦会不会更像。离散仿真改问:加速度、减速度、摩擦、顶速、跳跃初速、重力、坡度因子分别是多少亚像素;碰撞探针在位置更新前还是更新后执行;模式切换时传感器坐标如何旋转。

二、砸碎脚本:从「调参」走到「六传感器状态机」

仓库与原指南里最刺眼的场面,不是一张怀旧截图,而是那张几乎像劳动纪事的传感器表:玩家比普通物体多出一整套探针——A 与 B 探地面,C 与 D 探天花板,E 与 F 推墙;白点标出相对锚点,第一组传感器的 X 还会按朝向取反。站在平地上时,天花板探针休眠;一旦地面角进入环道,整套脚会按四种模式改写偏移:Floor(约 315°–45°)、Right Wall(46°–134°)、Ceiling(135°–225°)、Left Wall(226°–314°)。只永远使用 Floor 模式,游戏就会退化成普通平台——指南自己用对照 GIF 把这句话钉死了。

场面可以还原得更具体。固体砖带着高度遮罩与角度字节;两只地面脚各自量到砖面距离,取较近者,并列时 A 优先;距离把角色顶出地面,并写入获胜砖的地面角。推墙探针在着地状态下发生在位置更新之前——当前 X/Y 速度被加进探针坐标,撞上则把速度推出墙,并把地面速度清零。悬空时探针不再随地面角旋转,而是按空中速度象限启用四到五只脚。跳跃前还会先问天花板:最近距离小于 6 像素,直接放弃起跳。

关键机制在此显形:这不是「有碰撞」那么笼统,而是一台六探针射线自动机,外加模式滞后与执行顺序上的不对称。实现指南把三条致命陷阱写进同一页——用可变 deltaTime 乘速度会毁掉整张常量表;高速下不做正确探针会穿墙;凹面模式切换若无迟滞会在弯道上抽搐。行业默认把「物理」外包给通用求解器;Genesis《索尼克》把物理焊回同一条决策链——你改的每一帧加法,都要回头核对它是否仍在服务同一次环道冲刺。

四种碰撞模式:地面角决定传感器如何旋转

三、数字压住修辞:亚像素、常量表,以及「低于 2.5 就滑」

如果没有规格表,离散仿真叙事很容易滑向空话。Sonic Retro 指南与 Trent 仓库 README 里的快速参考表,恰好把修辞钉回可核验的地面。

坐标原点在左上;碰撞测试丢弃亚像素,只认整像素;角度 0 朝右、64 朝下、128 朝左、192 朝上(Genesis 十六进制顺时针)。Sonic 1/2/3&K 常用常量写得像零件清单:`acc` 加速度 0x000C(12 亚像素,约 0.046875 像素/帧),`dec` 刹车 0x0080(0.5 像素/帧),`frc` 滑行摩擦与加速度同值,`top` 平地顶速 0x0600(6.0 像素/帧),`jmp` 起跳 0x0680(6.5 像素/帧;Knuckles 为 0x0600),`grv` 重力 0x0038(约 0.21875 像素/帧),`slp` 坡度因子 0x0020(0.125 像素/帧)。水下另有一套减半或更低的对应值。

更尖刻的数字来自坡度物理:当地面角落在滑落区间,且地面速度绝对值低于 2.5(2 像素又 128 亚像素)时,角色会打滑——解除着地、地面速度清零(Sonic 3 起改为有条件滑移),并锁住方向输入约 30 帧。这保证你不能在天花板上慢慢走,也不能永远贴着陡坡往上蹭。主循环的顺序同样不浪漫:玩家控制与自身碰撞交错执行,随后是物体例程、物体与玩家碰撞、相机,再进入 V-INT。高速穿墙之所以难防,往往不是「碰撞盒不够大」,而是探针被放在了错误的半帧。

滑落角区间:速度过低时从陡坡/墙壁脱落

这组数字的叙事力量,不在于它有多复古,而在于它拒绝假装。它没有用「调到手感对了就算」去制造不可复查的权威,也没有把环道场景排除在承诺之外。环道恰恰是最能暴露模式切换、坡度因子与传感器旋转叠加成本的场面——把靶心钉在这里,等于公开承认:真正要保护的体验,发生在最吵闹、最快的那几秒,而不是标题画面的慢跑。

四、回流:离线文档逼出来的可实现性,写回独立管线

故事最有趣的尾声,不是又一份粉丝 wiki,而是反向回流到当代工具链。

Trent 做的事看起来很笨:刮取、重排、本地化图片与交叉链接,附上实现向章节与 AI agent 提示蓝图,并按 GFDL 标明文本来自 Sonic Retro、示意图可能另有条款、精灵图版权仍属 Sega。笨,是因为它不可被「看两眼教程视频」替代;贵,是因为它消耗真正的阅读与对照,而不是只消耗引擎默认组件。仓库创建于 2026-09-21(与 r/gamedev 发帖同日),把原先散落在 info.sonicretro.org 上的权威页,变成可 clone、可离线打开、可按文件顺序实现的文档套件。images 目录里整包落地逾百张技术示意图与 GIF——传感器、高度遮罩、模式切换、滑落区间——让「感觉」第一次站到可以截图核对的位置。

这几乎改写了「手感参考」在独立开发里的位置。过去动量平台常被看作美术与调参的下游工序——先做好关卡,再把摩擦拧到「有点 Sonic」。Trent 把叙事拧转过来:经典手感的边界成了压力测试台,逼你先写出确定性系统,再谈表现层。优化不再是单向加插件,而变成跨引擎的共同语言学习——GameMaker、Godot���自研 C++,读的是同一张常量表。

对独立开发者与小团队,这句回流尤其刺耳,也尤其有用。你未必要做一款合法的索尼克克隆,但你一定有自己的「默认已经够用」清单:某套 Rigidbody 摩擦、某次 `* deltaTime`、某个每帧顺序未写明的碰撞、某张远超目标手感的「手感不错」评论。Steam 上的动量平台、Game Jam 里的环道关,往往是你第一次被迫看见那张清单有多傲慢的地方。公开仓库等于承认:现代引擎上的「够像」,在定点亚像素与六探针面前,常常只是幻觉。

收束:独立与制作,在「可审计的手感」里被重新定义

把这份指南放回 2026 年的制作现场,它真正打击的不是「Unity 不能做 Sonic」这句空话,而是一种更隐蔽的制作惰性——以为平台差异可以用通用刚体抹平,以为手感是发售前两周的专项调参,以为玩家会用「有点像」原谅「不再是同一套动量世界」。

Sonic Retro 贡献者与 Trent 的离线重排给出的反例很笨,也很昂贵:亚像素与十六进制角、六传感器与四模式、2.5 像素/帧的滑落阈值、写明的帧序、GFDL 归属与逾百张原图。笨,是因为它要求你把感觉写成状态机;贵,是因为它消耗真正的实现决策,而不是只消耗插件商店的五星好评。

于是「独立」与「制作」可以在这里被重新定义。独立不必等于拒绝经典,而可以等于在资源更紧时仍坚持问「动量的最小不可破坏集是什么」。制作也不必等于功能堆叠,而可以等于愿意为那份最小集合重写碰撞——哪怕重写看起来像在和 1991 年的汇编对表。

可执行的提示很短,却足够刻薄地诚实:

  • 先写下你的「Sonic 感」清单:哪三条规则一旦变形,环道就死了(例如:固定 60 Hz 步进、着地前/后探针顺序、坡度滑落阈值);实现时它们享有否决权。
  • 对目标引擎做一次「关掉通用刚体、只保留运动学体 + 自写探针」的对照实验——不是为了永远不用物理引擎,而是为了看见插值到底偷走了哪些帧。
  • 改移动实现时,同步回归传感器几何、模式切换与主循环顺序;速度常量表与碰撞必须在同一次提交里一起验收。
  • 把指南里逼出来的更干净写法(定点亚像素、hex 角、显式帧序)标成候选,评估能否回流你的主力平台控制器,而不是当成「复古专属垃圾代码」。

仓库地址就在那里:github.com/trentbrew/sonic-physics-guide;权威原文仍在 info.sonicretro.org/Sonic_Physics_Guide。在你下一次把摩擦滑条拧来拧去之前,制作现场已经把审计标准说死了:不是「像不像」,而是「还是不是那套可逐帧复现的动量」。

小光

来源与延伸阅读

Trent Brew,r/gamedev 发帖(2026-09-21):I compiled the complete Sonic Physics Guide into Markdown & code samples on GitHub

GitHub 仓库:trentbrew/sonic-physics-guide(创建于 2026-09-21;含 README 常量表、docs/ 全套 Markdown、images/ 技术图)

Sonic Retro 原指南:Sonic Physics Guide(GFDL 文本;社区维护)

  • 仓库内关键篇:`docs/06-slope-collision.md`(六传感器与四模式)、`docs/09-slope-physics.md`(2.5 滑落)、`docs/12-main-game-loop.md`(帧序)、`docs/23-implementation-guide.md`(定点 60 Hz、陷阱与实现蓝图)

登录后,留下你的阅读足迹。

在个人页查看自己的点赞和收藏,换设备也能继续。

登录