Journal

Performance Tuning: Speedup

Posted by:

Gamers use the term “lag” to mean a handful of different things. Sometimes, your game engine just runs choppily. In Last Dream, we noticed that the beginning of each turn in battle would freeze for about a second –but only for certain enemies! The last boss of Last Dream 1 had this problem, and it really interfered with the thrill of the fight.

After lots of tracing, we found this line hiding away in the battle engine:

temp_actor = Marshal.load(Marshal.dump(@actor))

Marshal.dump() will save a Ruby object to a string representation, and Marshal.load() will do the reverse. This code essentially makes a copy of @actor, and later uses that copy to predict the effect that different Special Attacks will have on that Actor.

performance-speedup
This enemy only has 6 attacks to simulate. Some bosses have over 20. Multiple enemies per battle compound the problem.

The problem here is that string marshaling is slow. A “deep copy” is both faster and more accurate, and various implementations exist (e.g.,stackoverflow.com/a/8206537). Then, we can do this:

temp_actor = @actor.deep_clone

…which is 10 to 100 times faster.

Looking around, we found a few more places to use this fix. In particular, the Item menu uses a copy of an Actor as a way to show a preview of item predictions. The Synthesis menu had a similar problem; now, it loads about 2 seconds faster.

Moral: Sometimes you actually make things faster!