Posts

Showing posts with the label optimisation

Texture formats for 2D games, part 4: Overview

Image
In my last three blogposts I've discussed the details of various texture formats. Now that we've seen them, it's time for an overview. Below you'll find a big table that lists the properties of a lot of different formats and shows their results. I'll also discuss some final considerations on performance. The important thing here is to realize that there is no perfect solution: every choice has its own drawbacks, so even with the same art style you might end up with different texture formats depending on the platform. These are the main arguments to consider: Quality Size in video memory Size on disk Download size Loading time Framerate Development time Most of these are pretty obvious and I've already discussed quality and size in video memory extensively in my previous posts. The reason I'm listing them here is that it's important to keep in mind that you can mix and match formats for different goals. There are also more complex things that might m...

Texture formats for 2D games, part 3: DXT and PVRTC

Image
DXT is the most used texture format in games and it is what we use most in Swords & Soldiers II and Awesomenauts . DXT is easy to use but provides some weird compression artefacts, so a good understanding of how it works is very useful for both artists and graphics programmers. Since DXT is not supported on iOS I will also shortly discuss the quite similar PVRTC format. This is part 3 in my short series on texture formats for 2D games. Here are part 1 and part 2 . Note that DXT is often also referred to as DDS because DXT textures are usually saved as .DDS files. DXT is also known as S3 Texture Compression . There are several versions of DXT. The most versatile type is DXT5, which stores an alpha channel that can be used for transparency. DXT5 uses only 8 bits per pixel, making it 75% smaller than full 32bit RGBA. If no alpha is needed or only on/off alpha, DXT1 can be used, which is even smaller: 4 bits per pixel, making it 87.5% smaller than RGBA. That's quite a spectacular...

Texture formats for 2D games, part 2: Palettes

Image
After last week's introduction to texture formats we are going to look at palette textures today. Palette textures are an interesting and underused option for 2D games. Using them is quite a hassle since normal videocards don't support them, but for certain art styles they offer high quality and small texture size. Palette formats are similar to GIF files. The idea is that we have a palette, a list of all the colours in a specific texture. In the actual texture we don't store the colour of each pixel, but rather a reference to the palette. If the texture doesn't have a whole lot of colours we can get away with using only 256 different colours. References to these can be stored in 8 bits per pixel, so this format is 75% smaller than uncompressed RGBA. Palette textures are particularly useful for cartoony styles with flat shading, since those have fewer colours per texture. If your textures have more than 256 colours, you can reduce the number of colours. Depending on th...

Texture formats for 2D games, part 1

Image
When making a large scale 2D game like Swords & Soldiers II or Awesomenauts using the right texture formats can make a big difference for visual quality, video memory, loading times and download size. What format works best varies depending on art style and platform and a good understanding of the options helps a lot in making the right choices. This is a huge topic so I've split it into four posts. Today I'll cover the basics. The other three posts will discuss the more obscure palette textures, DXT and finally a comparison table of all the discussed techniques. This short series will get a bit technical at points but I've tried to make it as readable for artists as possible: knowing how your art will be compressed is important for game artists. While the texture formats available for 2D and 3D games are the same, 2D games have different requirements, so it is interesting to approach this topic from a 2D standpoint. Also, 2D games usually don't have things like n...

Bitcrunching numbers for bandwidth optimisation

An important part of making a complex multiplayer game like Awesomenauts is optimising bandwidth usage. Without optimisations, just sending position updates for one character to one other player already costs 240 bytes per second (30 updates per second at 4 bytes each for both X and Y). And this is just a fraction of what we need to send: Awesomenauts can have up to 35 characters running around the game world, and we need to synchronise much more than just their positions. As you can see, bandwidth usage quickly spirals out of control, so we need to be smarter than just naively sending all the data all the time. In the many months we spent on bandwidth optimisation, we employed lots of different techniques. The one I would like to talk about today can massively decrease bandwidth by crunching numbers on the level of individual bits. This technique not only worked great for the multiplayer implementation of Awesomenauts, but I am now also using this extensively for reducing the size of...

Optimising special effects in Awesomenauts

Image
The latest Awesomenauts patch increased the framerate a lot for players with older videocards, especially during fierce battles. We managed to optimise our special effects without making them look noticeably different. Today I would like to explain how we did that! Before I dive into the details, let me first give some background. In a 2D game like Awesomenauts, most objects are just a square with a texture on it. The texture contains an image, and you only see that image, not the entire square. However, the videocard renders the entire square. So from a performance perspective, it doesn't matter how much of the texture is actually visible . The entire square is rendered and the every pixel uses performance! Our artists know this, so they try to crop the image to have as few transparent pixels as possible (without changing the actual looks of the end result, of course). Since objects in Awesomenauts contain so many (partially) transparent pixels, we cannot easily detect whether an...

Optimisation lessons learned (part 3)

Image
To finish my little series on CPU optimisation (here were part 1 and part 2 , today I bring out the big guns: threading and timing! This is where optimisation really shines as a form of pure entertainment and delight. I can honestly hardly imagine why anyone ever does Sudokus or crosswords. Puzzling to find the best optimisations is so much more fun! Hiccups are horrible without the right tools Framerate hiccups are a special case. This is when the game is running at a high enough framerate, but once in a while a single frame takes a lot longer. Hiccups cause that a game running at 55fps might look a lot less fluent than one running at 30fps, if every second the 55fps consists of 54 smooth frames and one really long one. The difficulty here is that when you gather performance data, the time spent in each function will usually be averaged. This means that if a function runs really fast most of the time and is really slow only once per second, then it will look like a normal function in...

Optimisation lessons learned (part 2)

Last week I talked about some rather general things that I learned about CPU optimisation, when spending a lot of time improving the framerates of Awesomenauts , Swords & Soldiers , and even Proun . Today I would like to discuss some more practical examples of what kind of optimisations are to be expected. Somehow I like talking about optimisation so much that I couldn't fit it all in today's blogpost, so topics around threading and timing will follow next week. Anyway, forward with today's "lessons learned"! Giant improvements are possible (at first) The key point of my previous blogpost was that you should not worry too much about optimisation early in the project. A fun side-effect of not caring about performance during 'normal' development, is that you are bound to waste a lot of framerate in really obvious ways. So once you fire up the profiler for the first time on a big project, there will always be a couple of huge issues that give giant frame...

Optimisation lessons learned (part 1)

Image
Optimisation is a very special art form, with lots of tricks and realisations that give it a place of its own in the programmers toolbox. Until I had to do it for the first time on Swords & Soldiers for the Wii, I had never done any optimisation. At university I had already learned a lot about time complexity (big O notation, like O(n) ), but optimising an actual game with a big codebase is a different beast entirely. I was like a virgin that had never been seduced by a handsome profiler yet. I just started fooling around with optimisations, reading tutorials and articles on Nintendo's dev website and the internet in general, and learning as I went along. Since no pro ever taught me how to optimise, I guess I might still be unaware of some really important tricks. Yet somehow I managed to get Swords & Soldiers from an initial 10fps to 100fps on the Wii (if VSync is turned off), and Awesomenauts from 10fps to 70fps on the Playstation 3. In past five years I spent some six ...

Question: how to synchronise between the game and render thread?

Image
In today's blogpost, I'd like to do something radically different: I'm going to ask you a question . I know that quite a few of the visitors of my blog are hardcore programmers, and since I have a complex situation for which I would like to improve the performance, I figured I could ask for advice here! :) The problem is pretty complex, though, so I figured a short blogpost would be needed to really explain it. In short, this is the question: What is the most efficient way to synchronise renderable objects between the game thread and the render thread? There are a couple of subtleties you need to know to answer this for our situation, though. Let me start with a scheme that shows the approach to threading in the Ronitech (our in-house multiplatform 2D engine), as we use it in Awesomenauts on the Xbox 360 and Playstation 3: This works fine and we managed to get 60fps on console this way. However, the copying phase takes relatively long, so I am still wasting a lot of perfor...