fixing performance in BTD3
The classic
Bloons Tower Defense 3 is known to lag badly, despite being a rather simple game. Here's how to fix it just in time for a Flash-discontinuation-nostalgia playthrough.
cause
Strangely, Ninja Kiwi decided to add an
ENTER_FRAME
handler to
every single Bloon, unnecessarily causing thousands of event listeners to run concurrently each frame.
solution
Performance can be dramatically improved by using a single
for
loop instead.
prerequisites
decryption
Open the SWF in FFDec and find the
mochicrypt.Preloader
script.
Add
import flash.net.FileReference;
near the top.
Add
new FileReference().save(data);
at the end of the
finish()
function.
Running the game should now prompt you to save a decrypted SWF.
BloonsTD patches
Open the decrypted SWF, navigate to the
BloonsTD
class, find the
EnterFrame()
function, and insert the following code at the start:
for(var i=0;this.bloonholder.numChildren>i;i++)
{
this.bloonholder.getChildAt(i).Update(null);
}
However, FFDec's direct AS3 editor will corrupt this script upon saving. Writing P-code (Flash assembly language) is difficult. The easiest solution is to make the change in AS3, copy the equivalent P-code (everything from
pushbyte 0
to the first
ifgt
), reload the SWF, and then re-insert the P-code.
Rename the
ofsXXXX
labels in the pasted P-code, or they might collide with existing ones.
Bloon patches
Find
Bloon
's constructor and click the
addEventListener()
call. Once again, editing the AS3 will cause corruption, so delete the call via P-code.
It's also necessary to make
Update()
public so
BloonsTD
can call it. Change
PackageInternalNs
to
PackageNamespace
in the function's P-code's first line.
framerate
Optionally, change the framerate in the header from 40 to 60 FPS.
result
On my 2010 MacBook, this allows the game to run smoothly into freeplay mode. Normally, it slows to a crawl by round 30. The game balance should be unchanged, since Bloons don't interact, and towers are updated later.