I have had to plan many budgets for many games, including memory, polygon and animation budgets.  The first memory budget I ever did, I approached poorly and unsurprisingly it didn’t turn out very well. Luckily, it was only a small game so it fit without too many problems so it could have been much worse.  This was the third or fourth title I had worked on so it wasn’t due to inexperience.  Although looking back it is easy to see why I had such problems, I hadn’t taken into account a large amount of memory.  Many successful budgets later this is the approach I take.

Planning ahead

  1. Make a table of your platforms, listing the memory available.
  2. Break your game into modules.
  3. Read the design document, look at the desired art and read the technical specifications.
  4. Speak to all the major team members about what they are aiming for.
  5. Calculate the budgets.

During early development I go through this list several times because things can change fast.  I also re-evaluate every few months, to make sure we are on track and nothing major has affected the sizes.  Once you drift off budget it is very hard to pull it back, especially if it strays a lot from the original specification.

Make a table of your platforms available memory

Make a list of the platforms and the memory in the system.  This is a list I used recently:

Platform Total(Available) System(Available) VRAM(Available)
PS3 512(462)MB 256(213)MB 256(249)MB
XBox 360 512(480)MB 512(480)MB 0(0)MB
PC 512(512)MB 256(256)MB 256(256)MB

The actual memory available is far lower than the amount installed due to OS requirements.  Don’t forget to factor that in.  Every system has certain alignment requirements as well.  This can make a huge difference to the amount of memory used.  I will talk more about that in a later post.

The reason I break it into System and VRAM (and others if a platform has dedicated memory area) is because it tells me how much memory I have for the actual game.  If the base part of the game needs 400MB it isn’t going to work on the PS3.  VRAM is also not always useful or accessible from the CPU so can’t be used in a generic way.  These memory areas help later on with budgeting as well.

All platforms other than the PC have problems with restricted memory.  To get the actual PC budgets I take the platform with the closest specs and work to that.  The PS3 was the best fit for the game I budgeted for here.  Separate System and VRAM made it an easy match.  In reality you have level of detail texture sets and options for the higher end machines, but it is good to have a minimum spec.

Even if you are not releasing the game on the PC, it is sometimes beneficial to develop on it side by side and it also helps the team catch memory issues earlier.

The Program

You need to factor in the actual code and data required for execution into your memory budget (something I forgot to do in my first memory budget). Every system needs to store this in order to operate and it can be quite large.

A sample MAP file

Generally the program can be broken up into two areas. Both can be monitored from the MAP file or with a tool which process this into a more readable form.  These areas are the code and data.  Code is generally the .text section within a MAP file.  There is also the data section.  These are static and global variables you use in code.  The data area is also split into two, .data and .bss.

The .data section contains the information needed for initialized variables like this:

static int g_CheatModeEnabled = 1;

While the .bss area is the uninitialized statics.

As I mentioned, the MAP file is a good place to get this information.  Most compilers generate GCC compatible formats even if it is not a GCC compiler.  The other major format is output by Microsoft’s Visual Studio.  Both are pretty easy to use and tell you sizes of all sections at the top.

Shows a breakdown of the sizes required by the program. 6.6MB of code in 92k functions and 26MB is static data.

The image to the right shows a breakdown of the functions and data after decoding a MAP file.  The total comes in at around 34MB.  I should mention at this point this that this is a bit misleading.  When I break the game into modules, I normally make animation one of those modules.  The data section in this example contains a 15MB char[] buffer for animation.  Ideally, I would never recommend you to do that. Instead I would recommend allocating dynamically for tracking and gain all the debugging aids that often come with it.

Even so, if you don’t remember to budget for this it can come as a nasty surprise, for example on the 360 that reduces the memory you have available to 446MB.

Debug builds can also adjust these sizes.  I normally factor in about 25MB depending on the platform to leave me with some breathable space.  Another thing to take into account of at this stage is the size of the generated code.  The same code may be significantly larger on another platform.

Therefore taking this into account, the table will look like this:

Platform Total(Available) System(Available) VRAM(Available)
PS3 512(437)MB 256(188)MB 256(249)MB
XBox 360 512(455)MB 512(455)MB 0(0)MB
PC 512(487)MB 256(231)MB 256(256)MB

I will use this as my memory starting point in the next article.

Summary

Next time I will cover splitting the game into modules, working out the budgets in more detail and the other details on the list if I have room.  This post got big pretty quick!