答一下,作为国内第一批职业电子游戏开发者凑个热闹:
放一个自己早期的产品以示证明。我是1990年大学毕业开始职业游戏开发,开发过Gamate(类似GameBoy),FC,SEGA还有A'can。实际在8位机时代,128K已经是非常大的游戏了,因为8位处理器的寻址能力只有64K,实际多数留给游戏开发的空间只有32K,因此我们会使用切Bank获得超过64K(严格说32K的)的访问,即一颗专用解码芯片完成高位译码。因此,那个时候但凡到64K基本已经是巨作了。
1)图形:早期图形使用Pattern+Palette概念,即一个称之为PGT的数据存放色区索引的数据。而实际显示时,是这个索引加色区值构成一个指向调色盘的值,即实际上每个像素只需要2位。而由于复用这些Pattern因此,图形数据并不会太大
2)音乐:纠正楼上网友。实际FC连Midi都没有使用,我们是在SEGA开发时才使用了MIDI ---- MIDI中的鼓音色会很占空间。FC使用的全是FM音色,即都是由若干可程序化的简单频率振荡器按照一定方式连接发出不同的声音,而控制这些连接的控制数据相对很省空间,完全不是现在音轨和PCM可比
//-------------------------------------------------------------------------------------
补充一下:早期FC游戏卡根据译码芯片不同,会有不同卡型:如最早的168卡,这种卡的图形数据即我们所说的PGT是放在RAM中,因此,会有搬移动作。后来更为普遍的是使用C3卡(和其变种),这种卡打开典型的样子是三颗黑豆,两边两个分别是程序ROM和图形ROM,中间是解码芯片。因为全部使用的是ROM,因此,这种卡的显示会更快速,但问题是会有数据浪费 ------ 但成本更低。因此,后期FC使用C3即C3派生的卡更多,尤其国内后来广泛使用Ink Die后更是降低了成本,其成本甚至低于MASKROM ----- 因为Ink Die早期基本是论公斤秤的。对于早期小霸王游戏机在开机时会出现一声小霸王其乐无穷,实际,这个声音并非是FC自己的声音,因为之前我们说过FC的声音只有FM,不可能发出复杂的语音,其实现方式我印象是因为游戏机的Audio线有引入游戏卡,这样就好办了,游戏卡中内置一颗语音芯片就可以了。
后来开始做SEGA MD的开发,初期SEGA的开发仍是多沿用传统的汇编方式,但效率很低,所以,那时我尝试使用C语言开发SEGA MD游戏,实际就是一个商用的M68k编译器,然后主要是自己重写了标准库,包括动画显示、背景显示和音乐显示,早期国内炬力的SM801的Sega开发用的就是我们那套工具,后来日本BANDA也用的是我们那套工具。那套工具实际最大的改进就是音乐可以使用MIDI ---- 因为SEGA虽然仍是YAMAHA的FM芯片,但是他有一个PCM声道,因此,我们可以使用鼓 ----- 因为鼓很难用FM,早期FC中鼓是用Noise通道,那个效果。。。
真正国产游戏机似乎只有A'can,那个是敦煌科技(实际是UMC)开发的,我们初期就参与那个机器的开发,主要是做VD工具(即动画和背景编辑),后来还帮助这个机器设计游戏,我那个时候是《鸟笼院》的主设计,实际那台机器性能上要远强于SEGA,当时我是仿造SFC,在快打中实现无极缩放,只是可惜那台机器,出来不到一年就死了。
后来慢慢转3D引擎的设计,并因此转到芯片设计公司:初期主要是多媒体芯片和图形芯片,偏重算法多些。现在主要是做很底层的算法,和芯片设计即EDA相关,不仅局限于图形。
之所以匿了,作为老一代的游戏开发,看过太多的游戏开发领域的起起落落,也看到太多因为沉溺游戏而荒废学业的。现在只是潜心做些基础的研究,算是离开这个圈子 ----- 只想安安静静做技术,所以匿了。
//--------------------------------------------------------------------------------------
再补一脚:FC实际我开发的游戏不多,记得早先的狮子王III,那个是我写的,当然之后的几代狮子王实际都那个版本改改数据或换换关卡的排列。在街上看见自己的游戏被盗版莫名的兴奋,实际狮子王之后,我基本没有再写实际的游戏,主要是各游戏的开发工具设计,如SEGA等等。Gamate上游戏应该有几个,那个《毒龙谭》(DevilCastle)是我工作后第一个上市的游戏(实际那之前还有一个,失败了),三个程序,美术应该是两个台湾同事,记得一个叫邱小姐,写了快一年,完全汇编,代码整个好像也就32K;后来Gameate上又陆陆续续写了几个,记得最后一个应该是叫《郁卒龙猫》那时和我老婆谈对象,所以最后一关是写给我老婆的,密码是我老婆的小名,可惜那张卡找不到了。实际在后期,尤其到SEGA时,因为工具进步了,加上开发可以使用C语言,实际一个比较大的冒险游戏甚至只需要1.5个月就可以完成:一个游戏新手+2名美术,因为多数都是引擎自动生成,比如在编辑器上只要标出什么地方出小怪,那些地方可以抓,那些地方有机关等等,程序基本什么都不需要写。而动画也有动画编辑器,针对快打有快打的,在动画编辑器上除可以标注运动轨迹,还可以标注那些地方是事件点,那些地方是碰撞点,那些地方有攻击属性。。。程序编写也简单很多,不同类型有不同类型的引擎和工具。也许因为写游戏时间久些,后来一直专注游戏引擎和各种开发工具,之后几年直至离开这个行业,几乎没有实际的游戏了(有个内部版本的SEGA上的C&C,给公司做教学演示用的)
离开游戏后,喜欢上航模了。后来就是摄影,找一个爱好适当沉淀一下自己。虚拟社会很有趣,也许你在某个虚拟社会已经成为万人瞩目的英雄,但终有一天,曲尽人散 ----- 那个服务器关了或是那家公司倒闭了,一切终究会回归现实。所以,多认真考虑一下真实的自己,而不是用游戏去逃避或麻痹自己 ----- 人的一生何尝不是一场游戏?
一个古老的问题,因为某些机构号挖坟,被我看到了。作为那个时代的亲历者,来给新生代程序员讲讲这里面的奥秘吧 。
其实,玩过小霸王学习机的话(不是打游戏,而是编程),应该多少都知道。没玩过的话,那种用文字拼的图,见过吧。网上有很多。那种图,显然比一张图片,容量要小多了吧。
FC时代的游戏,画面就是这个原理。整个画面是由一块一块“马赛克”拼出来的。就好像《我的世界》里面用块块拼各种造型那样。
因为是8bit CPU,int类型(准确来说,是可以直接操作的整数)是8bit。所以,索引范围是0-255。也就是这样的砖块最多能有256种。也就是说,你所看到的任何一关,都是由这最多256种砖块拼出来的。(当然,不同关卡可以使用不同的砖块,就好像《我的世界》里面的皮肤那样)
这个砖块的大小是8x8像素。FC的画面分辨率为256x240,容易计算得出就是32x30个砖块(tile)。
此外,砖块本身也并非是按照今天的图片那样,按照RGB三通道直接存储颜色,而是使用调色板。8bit的调色板虽然理论上最多可以支持256种颜色,但是实际上FC整体上只能输出64色(其中还有重复色):
而且即便是这64色还不能直接使用,而是要从中挑选出要用的颜色,放入到总共4个调色板当中,才可以使用。每个调色板只能有4色,其中0号颜色强制为透明。也就是说,每个调色板其实只能放入3个自选色(还必须从上面64个里面选),4个调色板共12色,+透明,共计13色。
每个砖块可以最多绑定一个调色板。因为一个调色板是4色,所以每个像素只需要2bit就可以索引这4种颜色。这样存储一个砖块的内存容量其实是8x8x2bit=16byte。256个砖块就是4KB。
然后其实画面分两层:背景、前景。背景可以使用单独的256个砖块,4个调色板;前景也有自己的256个砖块,4个调色板。所以这样的话一关最多是512个砖块,8个调色板。调色板数量很少存储大小忽略不计,512个砖块存储需要8KB。
然后就是实际记录游戏场景(背景)以及人物武器装备子弹等的开销。背景前面计算了,一屏幕需要32x30个砖块,砖块之间不能重叠。因为是从256个砖块里面选,所以需要8bit的索引。那么一屏幕(背景)就是32x30x8bit=960字节。
各个关卡的长度不一。下面是所有关卡的背景图:
以最长的第五关为例,该关背景图为5616x240,那么也就是横轴差不多22屏。这样的话存储这个背景所需的索引值的总容量就是960x22=21KB的样子。
前景。前景就是那些人物啊,子弹啊,炮台什么的。FC最多支持64个前景“精灵”(之所以叫这个名字是因为和背景的块块不同,前景的块块可以放在画面任何位置且可以相互重叠,像精灵一样漂浮)。每个8x8(或者8x16)像素。保守起见按全部都是8x16(2个tile)计算(事实上不是),那么总共就是8bit/tile * 2tile/sprit * 64 sprits = 128B。(注意游戏当中的角色等很多是由多个精灵组成的,特别是boss,所以精灵并不是和角色一对一的)
所以,满打满算,前景背景都用足256个砖块,且所有砖块都不同,8KB的砖块存储+前景索引128B+背景索引21KB/关 * 8关,大约176KB的样子。当然此外还有程序(逻辑)的部分,音频的部分(音频的部分其实是MIDI而且音符很少,大概CDEFGAB+cdefgab,也就是2个八度音阶的样子(音高。音色是通过三角波方波等波形控制,也有的游戏卡里加入了额外的波形生成芯片),容量很小),但是显然背景部分是最耗的。其它场景都没有第五关那么长,甚至部分关卡短得多,而且有些关卡之间雷同很高,砖块可以大量复用(比如如果仔细看第五关的背景图,显然不同的砖块远远少于256个)。所以这样看下来大致上128KB是没有问题的。
统一声明:有好几位网友发私信评论告诉我,最近著名公众号“差评”也发布了与这个知乎问题主题一致的文章,核心内容借鉴了本问题下几个答主的主要思想。
我认为红白机时代的资源压缩技术属于网络上公开的知识,并不是某个答主的专利,所以每个人都可以用自己的话总结成科普文章发表。将文章结构分为数据容量、图形、音乐三部分,算是思路上的借鉴。
互联网时代的“原创”文章内容总会出现重叠和交集,如果是某人原创的思想被别人借用,就涉嫌“抄袭或洗稿”;如果是公开的知识则不算。还是要具体问题具体分析。
———————————————————————————
现代程序员A和1980年代游戏程序员B的对话:
A:为什么你用128KB能实现这么多画面、音乐、动画?
B:128KB还不够么?其实为了表现力已经相当奢侈了,加了很多不重要的细节。
A:就说你们的音乐,这个音乐,我压到最低码率的mp3,也得至少1MB吧。
B:你怎么压的?一首背景音乐怎么可能超过1KB。
A:那你实现全屏卷轴,用了多少显存?
B:一共就只有2KB显存,多了也放不下啊。
A:……
除非是专家,一般人根本无法估算到底多大算大,多小算小。
一般人对“数据量”并没什么概念。一篇800字的作文有多少数据量?按照GBK编码,约1.6KB,按照UTF-8编码,则是2.4KB。
只写了1个字的作文,按理来说1字节~3字节就够了。但只写1个字的word文档,有10956字节【汗】。而由于硬盘格式化要求,再多占用1332字节【再汗】。
现实中常见的产品、流行的技术,实际上和时代背景密切相关。
当你抱着15寸笔记本还嫌小的时候,1990年代初的家庭,可是一家人围着14~18寸的球面电视看的。把雪碧拿给古代人喝一口,估计他会齁得要死,必须喝点水压压惊。
当物质基础变得十分丰富的时候,一定会产生无法避免的“浪费”,这种“浪费”会进一步改变人感受的阈值,对度量的估计都变得紊乱了。
由于早期的记忆芯片(ROM)非常贵,而且大容量磁盘的技术也不成熟,所以暂且不论硬件计算能力,仅仅是想增加游戏的总容量也非常困难。所以自然会使用符合当时水平的数据结构。
以红白机FC为例,它的分辨率为256x240。分辨率不算低,但却只有2KB显存,而且还要实现全屏卷轴效果。所以在FC设计之初,从硬件上就提供了充分利用显存的方法——使用Tile(瓦片)。
对每一个场景来说,使用若干数量的瓦片,场景用有限的瓦片拼接即可。这种“二级”表示方法能极大节约存储量。具体一些原理讲解可以看一些科普,比如这个:
现代音乐格式往往直接保存声道的波形,这种做法保真度高、通用性强,但很显然占用空间多,一首曲子的容量以千字节、兆字节计算。
而八位芯片时代的音频解决方案,关键是一颗专用芯片,例如FC用的理光2A03:
音频芯片可以产生合成音效,能提供的音色可以在一定程度上配置,但非常有限。听听FC游戏的音乐可以体会到常用的音色几乎一样。我觉得这个音频芯片最厉害的地方是可以同时播放几个音轨(但不能是和弦那种“同时”),《魂斗罗》、《沙罗曼蛇》、《忍者龙剑传》的殿堂级音乐,主要是靠多个音轨的交替配合实现的。
每个音符只要记录音色、频率和音高就足够了,音频芯片自然会识别出来。把音符按时间排列好就是“乐谱”了,可以简单理解为“简谱”。这种简谱需要的数据量十分有限,而且大部分游戏音乐都是循环播放,数据量更是小的可怜。
代码也是类似的。
FC时代的游戏,没有所谓的“引擎层”,或者说引擎层就是“硬件层”。任天堂的主机完全是为游戏而设计的,瓦片、调色板、音乐、音效等基本功能已经预先考虑到了,这样一来就节约了大量底层代码。
程序员要仔细研究文档,在硬件框架下思考问题,比如如何显示图片、如何卷动屏幕等等;而且还要非常熟悉硬件底层和汇编,不要浪费代码空间。
一来二去,代码也能写的非常小。
总的来说,128KB的游戏大作,在30年前稀松平常,放到现在简直就是黑科技。科技的剧烈变革带来技术指标非线性的变化,让我们的记忆和直觉彻底落伍 :)
一大早是熬粥(尤其是为了保证营养丰富而材料五花八门的粥)省事省时间,还是煮鸡蛋,冲奶粉(或订鲜奶配送),用现成的材料(成品面包片,即食香肠)夹三明治省事省时间?