28th May 2009 Ė Development on a (Memory) Budget
This diary covers one of the most significant problems involved with building FunOrb games and FunOrb Central: memory consumption.
Click here to see the full sprite sheet.
Memory inside a computer forms a pyramid of sorts. At the top, there is a small amount of very fast memory embedded into the processor (cache). At the bottom, there's a slow, but very large capacity memory (the hard disk/drive). In between these two, there's the type of memory thatís relevant to this diary, which is commonly called core or main memory. Managing the transfer of data between these three types of memory is an important aspect of development, as it heavily affects performance.
When a Java applet (e.g. a FunOrb game) is running, it is stored in this main memory. All of an applet's resources (e.g. graphics, music, sound effects) must be held in memory before they can be used. Unfortunately, the most commonly installed versions of Java limit the amount we can use to around 64MB (referred to as 'the heap'), and it's already very easy for the resources of a FunOrb game to overrun this limit. A background wallpaper the size of the average screen takes about 1MB, and large backgrounds (e.g. an Arcanists map backdrop) or sprite sheets (e.g. Tor Challenge animations) can take more.
FunOrb Central restricts things further, as both the game and FunOrb Central need to run within the 64MB limit. To help alleviate this problem, we're aiming to get FunOrb Central running using no more than 10MB of memory, leaving 54MB for a game. Many FunOrb games require more than this at present, though, so we'll need to go back and amend them, which will require some technical work from the entire FunOrb development team.
Here are a couple of the techniques we'll use:
- Throwing away content that's no longer being used (e.g. an intro sequence, once it has finished)
It sounds simple, but there are complications. We can't predict when data will be needed again, so we'd prefer to keep everything in memory for speed. When that's not possible, we'll sometimes keep hold of a compressed copy instead. It's not quite as fast, but saves us some space.
- Changing the format of data in memory
When we're choosing how content will be stored in memory and for download, it's always a trade-off between performance, quality and size. Generally, to maximise the speed of our games, we'll go for the least compressed version, but memory constraints mean we might have to use other options, such as compressed images*. The trick is to make sure that any loss of quality or performance isn't noticeable to the player.
Click here to see a larger version of this image.
Even using these techniques is not going to be enough for us to get FunOrb Central working within a 10MB limit, so, after discussing this with Andrew, we plan to have FunOrb central do something sneaky... There is a group of technologies that were added to Java a couple of years ago, with the somewhat arcane name of 'NIO' (new input/output or non-blocking input/output). They were primarily intended to let Java applications access files and network devices at high speed, but they have an interesting secondary ability that lets applets allocate a bit of extra memory outside the 64MB limit. Using this technique, we hope to be able to have FunOrb Central store most of its data in this 'ghost spaceí, pulling only the parts we need into main memory and only for the duration they're required.
The other aspect of memory management in FunOrb Central is what to do when more memory is available for us to use. In more recent versions of Java, for those players who've tuned their memory settings to allow it, applets can access more than 64MB. We want to make sure that, where extra memory is available to us, we make good use of it. Some of our existing games already do this using a Java technique called 'soft references'. Itís a way of asking the Java implementation to try to keep data in memory, but allowing it to drop it if space is becoming tight. For example, you should get better performance in Dungeon Assault with more memory allocated to it, as it won't have to keep decompressing the animations. Along these lines, we'd like to have FunOrb Central keep entire games loaded in memory, providing enough memory is available, which should give improved load times for games when using more recent versions of Java.
So what does this mean for you? Essentially, FunOrb Central will have similar requirements to all existing FunOrb games - if you can run those, you should be ready to go - and it will be able to make better use of resources on computers with more recent versions of Java. We'll be more specific about the requirements and recommendations closer to launch, so stay tuned!