游戏邦在:
杂志专栏:
gamerboom.com订阅到鲜果订阅到抓虾google reader订阅到有道订阅到QQ邮箱订阅到帮看

阐述优化游戏运行效果的7个基本原则

发布时间:2011-10-18 10:53:44 Tags:,,

作者:Cliff Harris

制作运行更为快速的游戏是我所关注的话题之一。提供特别的代码范例只能帮助到某些人,下文我将公布某些普遍使用的原则。

1、避开使用代码的设计。

这听起来确实让人感到害怕,但是人们还是会这么做。诸如肩膀和膝盖之类的“皮肤化”动画对CPU而言较难以处理。你在游戏中看不到多少有着较大肩垫的角色。这种做法会让设计工作更为简单。GSB是款2D游戏,主要原因在于我偏好2D游戏玩法,但是我不能忽略一个事实,那就是游戏不适宜在支持3D的CPU/GPUG的环境中运行。

GSB(from cpugamer.com)

GSB(from cpugamer.com)

2、离线运行代码。

如果你的代码输出是一次性的,那么这种做法只能够使用一次,而且要在你传输游戏之前。GSB战役游戏代码在计算行星移动距离时显得尤为低效和缓慢。代码的运行是一次性的,然后在运行期间装载进结果即可。如果游戏在运行时间内进行的计算是基于永不改变的数据,可以预先对这些数据进行计算而后装载成表格。

3、运行一次代码,然后进行缓冲。

这是最后的重大胜利。在之前的年代里,人们使用正余弦表格来查找结果,而不是真正进行计算。GSB在某些方面也采用这种做法(游戏邦注:对游戏可玩性不是很重要的部分)。如果你可以在计算一次后直接引用结果,那么就不要在相同的功能中进行第二次运算。如此做法能够产生的差异性令人震惊。即便是像STL列表end()调用等简单的事项也能堆积成大型存储器。

4、无需每帧都运行代码。

没有那么多代码需要每帧都去运行。GSB中的小地图并没有每帧都更新。你会注意到这点吗?我不会注意到,因为在多数帧中,船只的移动是“次像素”的。如果需要运行代码的话,那么就要在某帧中更新半个代码,然后在下帧中再更新另一半代码。帧率应当设定为1/60秒。没有人会注意到代码没有随帧更新。

5、看不到的东西无需进展。

GSB中有某些用于各种装饰物品的代码,只会在屏幕上有活动性发生时才会调用。从理论上来说,你可以暂停游戏,或许会发现周围有些微小的矛盾(游戏邦注:假设玩家运气够好的话)。在战略游戏中,多数时间下,多数动作并没有被查看到,所以你可以舍去所有这些东西。比如,我就不更新运行离屏光线的计时器。

6、对内容进行重新排序和分组。

显卡喜欢集中分组处理事情。比如,提供单一纹理和50个精灵,它们会很乐意接受。但是,如果提供的是有着不同纹理的50个精灵,情况可能就有所不同了。这就是所有GSB残骸都使用相同纹理的原因。我也在游戏代码中对船只重新进行排序,这样相似的船只就可以在同个批次绘制出来,即便绘制的只是图标。这使得纹理交换达到最小化。因为GSB不使用z缓冲器,这使得代码有些混乱,但这是值得的。我找到的最简单的系统是保持不同纹理的精灵列表。你仍然会像往常那样绘制精灵,但是当绘制完成后这些精灵会被归类到相关列表中,随后整个列表中的精灵都可以绘制完成。

7、在不繁忙的时候保存内容。

GSB采用了这种方法。这确实非常棘手,但是你可以使用那些只会在CPU空闲时运行的代码。如果激光束集中GSB中的某些残骸,那么残骸就会爆炸。这只会在CPU空闲的时候发生。人们偶尔会注意到这点,认为这是l33t。但是他们并没有发现这种情况并非总会发生。

注意:优化UI

人们获得了运行快速的引擎,却发现其中UI运行格外缓慢。这足以让人发疯!大量的文字、图标、对话框背景和多部分按键,这些都有可能使得界面过载、纹理交换过度并大幅降低效率。你应当注意到这一点。

不要忘记,你同样可以对纹理进行优化。某些纹理已经足够成熟,可以进行压缩,但是有些纹理还做不到,但是你可以对其采取措施,比如将某个循环纹理分离成4部分,将其当成4个抛射和反射精灵来处理(游戏邦注:作者经常采用这种方法)。并非每个人都拥有512MB的视频卡,装载较小纹理的速度总是比较大纹理要快得多。

多数程序员可能都已经知道了这点,但是重新说下总不是什么错事。开发者很容易就会遗忘优化而只关注功能,但是如果你注意到这点,玩家会对你表示感谢。我发现许多人对GSB在其机器上的运行情况表示非常惊讶。这便是我努力的成果。

游戏邦注:本文发稿于2010年8月20日,所涉时间、事件和数据均以此为准。(本文为游戏邦/gamerboom.com编译,拒绝任何不保留版权的转载,如需转载请联系:游戏邦

Basic principles of game optimization

Cliff Harris

Making games run faster is a pet topic of mine. Code samples are too specific to help many people, so here are some general principles I’ve learned.

1) Design to avoid the code.

Sounds horrid doesn’t it, but people do it all the time. ‘Skinned’ animation at points like shoulders and knees is CPU intensive and tricky. Ever noticed how many characters in games have big shoulder-pads? Makes life much easier. GSB is a 2D game, mainly because I prefer 2D gameplay, but I can’t ignore the fact that it would be horrendously more draining on the CPU/GPU to be in 3D.

2) Run the code offline.

If the output of your code is a one-off, only ever do it once, and before you ship the game. The GSB campaign game code has some really inefficient slow brute force stuff for calculating planet-travel distances. It’s done as a one-off, and the results loaded in at run time. If there are calculations your game makes at run time that are based on data that never changes, just pre-calc them and load in a table, assuming the table is small enough.

3) Run the code once, and cache it.

This is the ultimate big win. In the old days, people used tables of cosine/sine lookups, rather than calculating them. Hold on! GSB does that for some stuff too (nothing gameplay critical). Never make a calculation twice in a function if you can do it once and reference it later. It’s amazing what a difference this makes. Even simple stuff like STL list end() calls can mount up with really large containers.

4) Don’t run the code every frame.

Not much code has to be run every frame. The minimap in GSB isn’t updated every frame. Can you notice? I can’t, because most frames a ships movement would be ‘sub-pixel’ anyway. If stuff like this seems to jitter, update half the code one frame, the other half the next frame. A frame should be 1/60th of a second. Nobody will notice.

5) Don’t process what isn’t seen.

GSB does some cunning code for all kinds of cosmetic things that only applies if that activity happens onscreen. In theory you can pause the game, scroll around and spot very minor inconsistencies (good luck). With strategy games, most of the time, most of the action isn’t being viewed, so you can skip allsorts of stuff. I don’t update timers for running lights offscreen, for example.

6) Re-order and group stuff.

Graphics cards like to do things in big clumps. Give them a single texture, and 50 sprites to draw and they are happy. Give them 50 sprites with different textures and they are not. This is why all the GSB debris is clumped into a single texture, ditto the laser bolts. I also re-order ships in the game code so that similar ones are drawn one after the other, even when drawn as icons. This minimizes texture swaps. Because GSB doesn’t use a z-buffer(for blending reasons), that makes for some spaghetti like code, but it’s worth it. The easiest system I’ve found is to maintain spritelists for different textures. You still draw sprites as normal, but when they draw they just get thrown into the relevant list, and the list gets drawn later.

7) Save stuff for when you are not busy.

GSB does this. It’s very tricky, but you can have code that only runs when the CPU is idle. If a laser bolt hits some debris in GSB, the debris explodes. This ONLY happens if the CPU is idling. People spot it occasionally and think it’s l33t. They never spot that it doesn’t happen all the time.

Optimize the UI

People get a fast engine then slap some super-slow UI on top. Madness! With a lot of text, icons, dialog box backgrounds and multi-part buttons, you can have crazy overdraw, crazy texture-swaps and huge inefficiency. Keep an eye on it.

Don’t forget that you can also optimize textures too. Some textures are ripe for compression, others not, but you can also do crazy tricks with some stuff, like chop a circle texture into one quarter, and raw it as 4 flipped and mirrored sprites (I do that a lot). Not everyone has 512 MB video cards, and its quicker to load a small texture than a big one anyway.

Most coders probably know all this already, but it doesn’t hurt to recap. It’s easy to forget about optimising and just worry about features, but gamers will thank you for it. I get a lot of people remarking how surprised they are at how well GSB runs on their machine. This is no accident. (Source: Cliffski.com)


上一篇:

下一篇: