How to properly optimize your Starling Flash projects

I am going to release my next game using Starling because it has a lot of interesting features, but to fully take advantage of all this stuff, you have to properly optimize your projects, since even slight differences can lead to very different performance results, as you are about to see.

Let’s see a basic example: I am using Flash CS6 but since I do not use any symbol in the library, you can use your favourite Flash IDE.

This is the main class, the very basic Starling proje3ct:

I just want you to have a look at line 12 where I tell Starling to show stats. It’s a little black box in the upper left corner which will tell us the frames per second, the memory usage, and the number of drawing processes for each frame.

Now look at Game class, which basically embeds a black and a red circle, and randomly places and moves 100 of them on the stage, a bit like in my previous Starling post Circle Chain engine using Starling.

Now look at the result:

It runs at 60FPS, at least on my computer, but we have 100 drawing processes, basically one for each circle. That’s really too much, and will heavily slow down mobile performances.

This is because of the texture creation, which is made at every loop iteration to create a new circle.

Look what happens when we create the texture outside loop creation:

Here is the result:

Now drawing processes should range from 40 to 60. This number is given from the amount of times we switch from the creation of a black circle to the creation of a red circle, or from the creation of a red circle to the creation of a black circle.

Surely, it’s better than before, but that’s not enough.

Let’s try to draw all black circles at first, then all red circles, like I am doing in this script in a very unelegant but clear way:

And the result is…

This time we only have two drawing processes, one for all the black circles, one for all red circles.

The problem is we have all red circles places after all black circles, and this could be a problem in some game concept. Moreover, what if we have 50 different circles?

That’s why we are using a texture atlas, something old school programmers would call sprite sheet. A single image containing all the graphic assets, and an XML file to define images name and coordinates.

This will give us two big advantages: first, we can lower the amount of drawing processes to 1. Second, every image embedded should have width and height as a power of 2, that is 2, 4, 8, 16, 32 and so on. In Starling you can import images of any size, and it will take care about the rest, but you’ll probably pay for it a performance fee. With a texture atlas, it’s easier to satisfy this request since you’ll have a single big image.

Here is the XML:

and this is how we import it:

And finally, the fully optimized result:

It’s very important to keep this in mind when you want to easily develop your projects for mobile devices.

Download the source code, Starling library and graphic assets included.

  • MrPoulet

    nice demo ! and ‘bitmap batching’ is a good pratice with the classic display list too.

  • Pingback: How to handle your Flash Starling animations using the Juggler - Emanuele Feronato()

  • Reminds me of something (some basic tutorial code) I just posted a few days ago at wonderfl , and modified today to use a lookup table.

    It’s the same esthetic; yet, instead of a tutorial on using starling, mine uses the regular drawing api, handles radius based collision, and prevents redrawing if not needed. Although I’m not sure if I should anymore, I might update it again today or tomorrow to use a singleton where drawn assets can be stored bitmaps, allowing their reuse by all objects.

    I might get into starling in the near future thanks to this post.

  • Lovely demo thanks E! Just getting back into as3 after a long hiatus, and it’s a pleasure to see your beautiful illustrated little logo come up again :)

    I’m curious though, as to why your third example is faster than your second example. Does the order of adding the children to the stage make a difference? (i.e. the 2nd example it’s generally black/red/black/red… and the 3rd example it’s 50 x black then 50 x red).

    If the ordering only affects the speed of the creation step and not the enterFrame step, then the overall speed savings would be negligible, no?

  • Nikhil Mahirrao

    I am developing one game in starling, but facing problem of memory leak. In this game frog are generated one by one continually as I am tapping them its destroyed and remove from stage. But still as soon as I tapped first frog memory start increasing and so on. Please tell me how to solve this problem.

  • faisal


    I have a sprite sheet which contains portions of background used to scroll every portion with their own speed. However i m seeing 5 draw calls count in stats panel, can u tell me why its not 1 since i m not using different bitmap for different textures ?

    Here is by background scroll code.

    package com.objects
    import com.classes.GamePlay;
    import com.utils.AssetsUtil;

    import starling.display.Image;
    import starling.display.Sprite;
    import starling.extensions.krecha.ScrollImage;
    import starling.extensions.krecha.ScrollTile;
    import starling.textures.Texture;

    public class GameBackground extends Sprite
    private const SKY_OFFSET_X:Number = 0.2;
    private const MOUNTAIN_OFFSET_X:Number = 0.8;
    private const GRASS_OFFSET_X:Number = 0.8;
    private const ROAD_OFFSET_X:Number = 2;

    private var scrollSky:ScrollImage;
    private var scrollRoad:ScrollImage;
    private var scrollGrass:ScrollImage;
    private var scrollMountain:ScrollImage;
    private var scrollTile:ScrollTile;
    private var myImage:Image;
    private var myTexture:Texture;
    private var gamePlay:GamePlay;

    public function GameBackground(gamePlay:GamePlay)
    this.gamePlay = gamePlay;

    myTexture = AssetsUtil.GetSingleTexture(“sky”);
    scrollSky = new ScrollImage(myTexture.width, myTexture.height);
    scrollSky.x = 0;
    scrollSky.y = 0;
    scrollTile = scrollSky.addLayer(new ScrollTile(myTexture));

    myTexture = AssetsUtil.GetSingleTexture(“mountain”);
    scrollMountain = new ScrollImage(myTexture.width, myTexture.height);
    scrollMountain.x = 0;
    scrollMountain.y = this.gamePlay.stage.stageHeight / 2 – myTexture.height / 3;
    scrollTile = scrollMountain.addLayer(new ScrollTile(myTexture));

    myTexture = AssetsUtil.GetSingleTexture(“grass”);
    scrollGrass = new ScrollImage(myTexture.width, myTexture.height);
    scrollGrass.x = 0;
    scrollGrass.y = this.gamePlay.stage.stageHeight – myTexture.height;
    scrollTile = scrollGrass.addLayer(new ScrollTile(myTexture));

    myTexture = AssetsUtil.GetSingleTexture(“road”);
    scrollRoad = new ScrollImage(myTexture.width, myTexture.height);
    scrollRoad.x = 0;
    scrollRoad.y = this.gamePlay.stage.stageHeight – myTexture.height;
    scrollTile = scrollRoad.addLayer(new ScrollTile(myTexture));

    public function Update():void
    scrollSky.tilesOffsetX -= SKY_OFFSET_X;
    scrollMountain.tilesOffsetX -= MOUNTAIN_OFFSET_X;
    scrollGrass.tilesOffsetX -= GRASS_OFFSET_X;
    scrollRoad.tilesOffsetX -= ROAD_OFFSET_X;

    }//end of class

    }//end of package

  • Gerald
  • Halil

    Hello ,

    Thx for this beatiful tutorial. I wonder is there any way to use external image’s for this ? I want to use starling but this external image thing stop’s me. Thanks again.