为什么有32个关卡的游戏《超级马里奥兄弟》只要40KB?

早期红白机的经典游戏容量出乎意料的小。

这个问题曾经在知乎上引起过热烈的讨论,B站、微信上都有相关的热门视频。相关资料我会整理到答案的末尾,以供参考。

经过一段时间的广泛讨论,这一问题逐渐变得更加清楚了。感谢Anjie的邀请,再将这个问题整理一遍做出回答,对一些有价值的信息做个总结 :)

1、核心压缩方法——Tile(瓦片)

首先,实际上初代《超级马力欧兄弟》只有40KB。

我们先别急着惊讶,先问一个问题:无论40KB还是400KB,它一定有一种基本的压缩方法,这个压缩方法与我们今天保存图片的方式肯定从根本上就有区别。

红白机的基本图像单元为“Tile瓦片”,每个瓦片为8×8像素大小。与现代游戏直接绘制像素的思路不同,红白机上的游戏必须先准备好一系列瓦片,再把瓦片拼在一起形成画面。

为什么要这么做呢?通过简单的数学运算可以知道,先做一些瓦片再拼接瓦片,内存占用量要远远低于直接绘制每一个像素。

例如:一张128*128像素的图片,每个像素可以选2^8=256种颜色,那么每个像素需要记录8bit=1Byte信息,共占用空间16KB。(128*128*1 Byte)

而如果换成8×8的瓦片去铺满图片,则只需要 16 * 16 = 256个瓦片就够了,如果总共只有256种不同样式的瓦片,那么只需要256B 即可表示这张图片。

简单来说:用重复出现的模式拼成一幅画面,可以极大压缩图片占用的空间

但这里留下了一个问题:256种瓦片本身也要占用空间,瓦片本身如何存储?

2、FC如何保存色彩数据

FC虽然画质简陋,但色彩还是相当鲜艳的。在当时的技术条件下,FC理论上可以表示50多种颜色,一个像素的颜色可以用6bit表示。而一个瓦片有8×8 = 256个像素,那么就需要 8x8x6 bit = 48 Byte 来表示一个瓦片。

这么算起来就出问题了~~ 256种瓦片,每个瓦片 48 Byte,瓦片容量等于256*48 B = 16384 B。好家伙,什么都没干,光瓦片就存了16KB,显然太多了。

解决这一矛盾的核心,是另一个问题:FC如何保存颜色数据?

通过 @文礼 大神的回答可以知道(文礼 的回答),每个瓦片只能绑定一个调色板,而每个调色板只有4种颜色,所以每个瓦片的容量占用仅有 8x8x2bit = 16Byte,比上述估算的少4倍

而且,调色板带来另一个有趣的功能,考虑下面几个图片:

外观完全一样有没有?

上图中不同的图片仅仅是颜色不同,并不需要创建新的瓦片,只需要给同一个瓦片替换不同的“调色板”即可。这样可以巧妙利用调色板,创建出不同皮肤的物体,而容量几乎没有增加。

3、FC如何保存音乐数据

现代音乐格式往往直接保存声道的波形,这种做法保真度高、通用性强,但很显然占用空间多,一首曲子的容量以兆字节计算。

而八位芯片时代的音频解决方案,关键是一颗专用芯片,例如FC用的理光2A03:

音频芯片可以产生合成音效,能提供的音色可以在一定程度上配置,但非常有限。听听FC游戏的音乐可以体会到常用的音色几乎一样。我觉得这个音频芯片最厉害的地方是可以同时播放几个音轨(但不能是和弦那种“同时”),《魂斗罗》、《沙罗曼蛇》、《忍者龙剑传》的殿堂级音乐,主要是靠多个音轨的交替配合实现的。

每个音符只要记录音色、频率和音高就足够了,音频芯片会识别出来。把音符按时间排列好就是“乐谱”了,可以简单理解为“简谱”。这种简谱需要的数据量十分有限,而且大部分游戏音乐都是循环播放,数据量更是小的可怜。

当时的芯片擅长产生的波形包括方波、三角波、正弦波等等,其中三角波用来做Bass效果很好。而《超级马力欧兄弟》里面的“鼓”是用“噪波”实现的,也是当年的常用做法。

FC的音频芯片还支持短时间的采样音乐,后期的《忍者龙剑传3》BGM里面的鼓声采用了8Bit采样声音, 效果超棒。

4、FC的程序代码容量

有趣的是,现在绝大多数人都忽略了程序代码本身所占用的空间。但在那个内存容量极其有限的年代,代码的体积不可小觑。

FC时代的游戏虽然逻辑不可谓不丰富,但确实整体代码不大。为什么呢?

因为FC时代的游戏,没有所谓的“引擎层”,FC的硬件本身就是一个非常简陋的游戏引擎。任天堂的主机完全是为游戏而设计的,瓦片、调色板、音乐、音效等基本功能已经预先考虑到了,使用特定的方式就能直接调用,这样一来就节约了大量底层代码。

程序员要仔细研究文档,在硬件框架下思考问题,比如如何显示图片、如何卷动屏幕等等;而且还要非常熟悉硬件底层和汇编,不要浪费代码空间。

一来二去,代码也能写的非常小。

5、其它优化机制

为了极限压榨容量,当年的程序员和美术也动了不少脑筋,比如几个经典案例:

这些细节的优化,也对压缩大小起到了一定作用。但总的来说,并不是让容量变小的主力~~~

总结

以上分5个部分,详细介绍了FC游戏容量小的原因,特别是背后的本质原理。

以上内容参考了很多内容,包括不限于wiki、知乎、B站等渠道。有错误的地方不吝赐教~~

参考资料:

  1. 知乎问题:为什么魂斗罗只有128KB却可以实现那么长的剧情?
  2. B站:【差评君】为什么有32个关卡的超级马里奥兄弟只要40KB?_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
  3. wiki:https://en.wikipedia.org/wiki/Super_Mario_Bros.

还有其它很多参考,不好一一列举,向这些作者表示感谢。

来源:知乎 www.zhihu.com

作者:皮皮关

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。
点击下载

此问题还有 5 个回答,查看全部。
延伸阅读:
你遇到过的最难的游戏关卡是什么?

玩过的最精妙的游戏关卡是什么?