Journal

Performance Tuning: Splitting Things Up

Posted by:

Sometimes, there is no way to speed up the thing you’re trying to do. Take Last Dream’s battle transition, which shatters the screen into ~220 pieces that go flying off in random directions, courtesy of the KGC_SpecialTransition script (ytomy.sakura.ne.jp).

perfomance-splitting-things-up
You get an achievement if you play the entire game this way (just kidding).

Every time the player gets into a random battle, we take a screenshot of the game window and then break it into 220 separate Sprites. We then give these Sprites random velocities and rotation speeds. Then, when the battle starts, we delete all 220 Sprites so that they stop cluttering up the screen.

Needless to say, this causes the screen transition to lag. This is super annoying, because as a player you can sort of feel when you are going to get into a random battle (because the game lags a tiny bit).

We can’t reduce the total amount of work to do, so we rely instead on an old programmer’s trick called “amortization”. Basically, instead of paying the performance penalty all at once, we split it up into a lot of little payments. Like so:

class Scene_Map < Scene_Base alias update_KGC_SpecialTransition update def update update_KGC_SpecialTransition Graphics.make_a_square unless made_all_squares? end end Basically, what this says is "every frame tick, make a new square, unless we have enough". The function made_all_squares? looks like this: cells = (Graphics.width * Graphics.height) / (SPLASH_SIZE ** 2) return @@sp_cached_tiles.length>=cells

The function make_a_square looks like this:

spr = Sprite.new
spr.bitmap = Bitmap.new(SPLASH_SIZE, SPLASH_SIZE)
spr.opacity = 0 #Start invisible
@@sp_cached_tiles.push spr

This code means that by the time we actually run into a battle on the world map, we already have a full set of 220 squares. We still need to take a screenshot and split it between each of the 220 squares, but that is now the only thing we have to pay for. (We do one final optimization: instead of deleting the Sprites when we’re done, we set their opacity to 0 to make them invisible. That way, we only need to make them once per game session.)

Moral: Sometimes you can do enough of the work beforehand, and can shatter it over multiple frames.