Wednesday, 7 August 2013

Pigment & The Droid, Part 3

As foreshadowed at the end of Part 2, the optimisations described therein were not enough to get Pigment to run on the Motorola Droid. Pigment was still using too much memory for the Droid to handle.

So: to get Pigment to run on a Droid it needed to use less heap.  How to accomplish this?  It needed to hold less graphical data.  I'd already reduced image memory size as much as possible regarding format and storage options (such as removing the alpha channel);  I either had to load less of the assets, or generate less content as the game ran.  In the end I did both!

The first saving relies on how the user experiences the game; as they play and complete levels the game will send messages to them: the Win! message, the tip about pressing Back to undo, the Bonus Unlocked messages, the Congratulations on completing worlds / the game.  Of these: the Science  Unlocked message and the final Congratulations message on completing the game made a useful pair.
The Science Unlocked message always (and only) displays after you complete your 4th level.  The End Game message only displays once you have completed every single level in the game.  Clearly it is very unlikely that a user will see both these messages in one play session.
Thus we save a screen-load of heap: when Pigment is loading its assets it checks whether the user has already seen the Science Unlocked message.  If they haven't it loads that image into heap, but if they have seen it then they will never see it again, and so it loads the End Game message instead.
This does introduce a bug into the game: if you sit down with a fresh copy of Pigment and complete it in one session, without switching to a different app (or taking a phone call, or reading a text message, or putting the phone on standby) then, come the end of the game, it will display the Science Unlocked message again, instead of the Congratulations you might expect.  This is a bug I can live with!

The second was really a simple aesthetic change, but requires some understanding of how Pigment works to describe.  The Pigment game board is (in the default Art style anyway) a representation of a canvas.  As you apply colours to the different tiles they will change to reflect what you've done; you draw a red line and the canvas will be drawn with a red tint.  For each tile on the board the game has to draw the canvas bitmap tinted the colour it has been painted.
Now, there are two ways that the game could render this:  The first would be to draw the tile in its default, white state, and then apply a graphical tint to it based on the paint colour.  This tint operation is very slow, however, and doing it for every tile across the screen would significantly damage the framerate.
The second way, the way Pigment uses, is to pre-tint a separate canvas for each colour, and then simply copy the tile from the relevant canvas onto the game screen.  When Pigment first loads it's assets, it loads in the canvas bitmap.  It then creates a pile of other bitmaps the same size, and copies the canvas bitmap into each of them, and then tints them different colours.  There's a canvas bitmap for each different colour: red, yellow, blue, green, orange, purple.  During play, if the game wants to draw the tile at coordinate 2,2 as red, it simply copies that section from the red canvas and pastes it in the correct place.  This copy-paste operation is a lot faster than the tint operation described above, and so the framerate is kept at a playable level.  The cost for this added speed is that it uses a lot more heap.
Clearly, we can't do away with any of the paint canvases - Pigment sort of relies on those six colours for gameplay.  However, it also generates a few other canvases on top of those.  For example, there's the null colour, used when you mix all three primaries together.  For our purposes we have these two: one is the light grey used to draw the grid lines on the play board, and the other is the darker grey used to display locked levels, and locked items on the Bonus screen...
As it turns out, using the grid-line light grey for the locked levels and items actually looks better, and by doing so we need to generate one less screen-worth of image data.

After implementing both these optimisations, Pigment finally ran A-OK on the Droid. Whew!

No comments:

Post a comment