Category: Development

  • Migrating to Starling 1: Get it to Compile

    Starlings by onkel_wart

    Welcome to the first of Colin Northway’s “I’m Too Busy Writing Games to Write Technical Blog Posts So I’ll Just Write a Shoddy Technical Blog Post Really Quickly Instead”.

    This Shoddy blog post is the first of two on migrating an existing project to Starling and Falsh’s Stage3d. You can find part 2 here.

    Well Flash is now all jiggy with the graphics card and even though you started your project a year ago you’re definitely going to want to get all jiggy too. Putting graphics on the graphics card is way faster and you get all those extra CPU cycles to do cool things like physics. Plus you can play with neat things like Pixel Shaders which I’ll talk about in a future post.

    This is all based on my experience converting Incredipede and is really just intended to provide a vague roadmap through the experience. This first post will merely be about getting your project swapped over and compiling. The next one will be about making your Stage3d code suck less.

    First thing’s first: go download Starling. Starling is a 2d Stage3d framework being written by Daniel Sperl. It wraps the flexible but verbose Stage3d stuff into a Display-List-like interface. It’s open source, Daniel is constantly working on it, the community is growing and helpful, and it’s quite good so it’s prolly the way to go for 2d Flash games from now on. Also, it closely replicates the way Flash did things before Stage3d existed so it’s going to make it much easier to convert your existing project.

    To get you going, you’ll need to grab the newest versions of the Flex SDK, either the AIR SDK or playerglobal.swc, and the Starling SDK, point your project at them and add “-swf-version=13” to your compiler options. Read the first part of the quite good Starling Introduction by Thibault Imbert, and come back when you call starling.start();

    Now that you have Starling all up and running it’s time to do some mass search and replaces. This would be a really really good time to back up your code. It’s pretty hard to undo the changes we’re going to make so please back it up in case you get half way through and decide I’m an idiot who led you astray.

    Now to work: time to grab the Flash display list, yank out the spine, and then stuff Starling down in the hole left behind.

    Search and replace the following:

    “import flash.display.DisplayObject;” with “import starling.display.DisplayObject;”

    “import flash.display.Sprite;” with “import starling.display.Sprite;”

    “import flash.display.MovieClip;” with “import starling.display.MovieClip;”

    Now everything is going to be broken and you’re going to get a lot of Compile Time errors, mostly where you add graphics to the game. Less’ fix ’em!

    An Error has Occured

    There are three ways you might be getting graphics into your game at the moment. You might be embedding images, you might be embedding MovieClips and you might be using the flash 2d graphics drawing API. Incredipede uses all 3 so I’ve got a system in place to deal with all of them. Let’s deal with embedding images and MovieClips first.

    Most of your compile time errors are going to be where you .addChild(new Graphic()); because starling’s Sprite.addChild method takes a starling.display.DisplayObject not a flash.display.DisplayObject.

    It’s just going to take a little grunt work to make these errors go away. We’re going to do it in a very easy, very bad way and then after you have everything running we’ll go back and make everything suck less (in the next post).

    First let’s make up a very simple, static, texture manager class:

    public class TextureManager
    {
        public static function imageFromSprite(sprite:DisplayObject):Image
        {
            var rect:Rectangle = sprite.getBounds(sprite);
    
            var image:Image = new Image(textureFromSprite(sprite));
            image.x = rect.x;
            image.y = rect.y;
    
            return image;
        }
    
        public static function textureFromSprite(sprite:DisplayObject):Texture
        {
            var rect:Rectangle = sprite.getBounds(sprite);
    
            if ( rect.width > 2048 ) {
                rect.width = 2048;
                trace("Bitmap too big, shrinking");
            }
            if ( rect.height > 2048 ) {
                rect.height = 2048;
                trace("Bitmap too big, shrinking");
            }
    
            //red box means invalid texture
            if ( rect.width <= 2 || rect.height <= 2 ) {
                var tempSprite:flash.display.Sprite = new flash.display.Sprite();
                tempSprite.graphics.beginFill(0xFF0000);
                tempSprite.graphics.drawRect(0, 0, 50, 50);
                sprite = tempSprite;
                rect = sprite.getBounds(sprite);
            }
    
            var bmd:BitmapData = new BitmapData(
                rect.width, rect.height, true, 0x0000000000);
            var matrix:Matrix = new Matrix();
            matrix.translate( -rect.x, -rect.y);
    
            // draw the shape on the bitmap
            bmd.draw(sprite, matrix);
    
            var texture:Texture = Texture.fromBitmapData(bitmapData);
    
            return texture;
        }
    }

    This takes whatever DisplayObject you just passed in, converts it to a bitmap and then uploads it to the graphics card. Now you can go replace all of your:

    addChild(new Graphic())

    with this call:

    addChild(TextureManager.imageFromSprite(new Graphic()));

    That should work for Sprites and MovieClips (alhtough they wont animate) and .PNGs and anything you might embed.

    So that will have killed a lot of errors but there are still a lot left. Among them are all those graphics.beginFill calls which now make no sense.

    To make those errors go away just draw to an intermediate sprite and pass that to imageFromSprite() like this:

    var sp:Sprite = new Sprite();
    sp.graphics.stuff
    sp.graphics.etc...
    addChild(TextureManager.imageFromSprite(sp));

    WARNING: you are now leaking horribly into texture memory. Read part 2 if you are interested in how I stopped this.

    Now all your graphics problems should be gone. You’re close to having things at least running. Well, if all those Event errors weren’t staring at you pretty menacingly you’d be close.

    Starling replaces the Flash event model with its own. I’m not totally in love with this decision but whatever, we can work with it. More search and replace!

    replace “import flash.events.Event;” with “import starling.events.Event;”

    Now all your event classes extend Starling.event.Event so you have to go remove all the clone() methods from them. That’s one upside to Starlings events. One of the down sides is that all your MouseEvents just stopped working.

    That sucks pretty hard right? Well, if you step into this back alley I have some candy you might like. Just don’t tell anyone you got this from me…

    Starling handles mouse events in a totally different way than Flash. Which is too bad because Incredipede was written to use Flash’s mouse events and changing the way everything works is going to kind of suck. But if we put this method in a Utils class:

    public static function addMouseListener(mouseEvent:String,
        target:starling.display.DisplayObject, callback:Function):void
    {
        target.addEventListener( TouchEvent.TOUCH, function( event:TouchEvent ):void {
            var touch:Touch = event.getTouch(target.stage);
            var newEvent:MouseEvent;
            if ( mouseEvent == MouseEvent.MOUSE_DOWN
                && touch.phase == TouchPhase.BEGAN ) {
                newEvent = new MouseEvent(MouseEvent.MOUSE_DOWN, false);
            }else if ( mouseEvent == MouseEvent.MOUSE_MOVE
                && touch.phase == TouchPhase.MOVED ) {
                newEvent = new MouseEvent(MouseEvent.MOUSE_MOVE, false);
            }else if ( (mouseEvent == MouseEvent.MOUSE_UP
                || mouseEvent == MouseEvent.CLICK)
                && touch.phase == TouchPhase.ENDED ) {
                newEvent = new MouseEvent(MouseEvent.MOUSE_UP, false);
            }
            if ( newEvent != null ) {
                callback(newEvent);
            }
        });
    }

    Then we can replace

    button.addEventListener(MouseEvent.MOUSE_DOWN, loadMain);

    with

    Utils.addMouseListener(MouseEvent.MOUSE_DOWN, button, loadMain);

    Of course this is pretty limited. You can’t get the mouse position from the event or anything (although you could make position work) but it’s a quick and dirty way to make your code compile.

    In fact at this point your game should be running! On the graphics card! Really fast! Or actually, you might be uploading a lot of textures to the graphics card every frame depending on how your game works so it might instead be Really slow! Which we’ll fix next time.

    I welcome other suggestions if you’ve found better ways to do some of this stuff. Stay tuned for my next post when I discuss “how to make your Stage3d code suck less”. See you then!

    starlings on wires by Hopefoote
  • Word Up Dog: Game Center with AS3

    Word Up Dog Leaderboard
    This bizness be fresh. Take you from some disconnected punk to BAM! – competin' with all yo homeboys, earnin' achievements and shit.
    In my last post I lamented not having access native iOS features such Game Center and single sign-on Twitter. Well, Milkman Games has come to the rescue with their Game Center Native Extension for Adobe AIR. Took me less than an hour to pop it in to my FlashDevelop project, connect all the events and go. All in AS3, no Mac or Xcode required. Post scores, view achievements, all that good stuff with minimal effort. They also have an Android AdMob extension and more on the way – valuable tools for running AIR on mobile devices.

    I’ve got Word Up Dog now running with Game Center on iPads and iPhone 4+, but I need to test it on the iPhone 3GS and iPod Touch 3+. So this is a call for testers – please sign up to join my Test Flight team if you’ve got any iOS device, and I may recruit you to help me test Word Up Dog, Rebuild, or some future game.

    Word Up Dog Sand Level
    Sandworms, vines, thievin rabbits. Dawg this hood gonna get isself a makeover.
    For anyone who played the old flash version of Word Up Dog, there’s going to be some changes. I’m spicing up the levels with some new terrain and new powerups. I know, it’s no Rebuild, but after writing about zombies for four months I need some cute animals talking in urban slang stereotypes.

    Word Up Dog was always meant to be an iOS game, so here we go!

  • Rebuild iPad is out!

    Rebuild for iPad 2
    Rebuild iPad was born in the jungle

    Rebuild is now available for the iPad 2 on the Apple app store!

    I am happy to report that the game plays great on the iPad 2. Sarah’s done a great job rethinking the interface for the touch screen and this is probably the best version of the game. You can almost feel the zombies clinging to your finger tips.

    Sarah also made some new content for the iPad 2 version. She didn’t really have time to stuff all the features into Rebuild 2 that she wanted to so this was a chance to get that stuff into the game. You could think of the iPad 2 version as the “complete” version of Rebuild 2.

    I don’t want to spoil all the new stuff but there is a new plotline (which I wrote, props to me!) with a new building and a new ending. The new plot is unique because it’s more of a selfish path through the zombie apocalypse.

    Rebuild for the iPad 2!
    Rebuild for the iPad 2 is out!

    There are also Watch Towers that you can use to keep tabs on the zombie hordes. If you research things right you can even use them to mow down troublesome clumps of zed (a great way for advanced players to keep the danger rating down).

    As with Rebuild and Rebuild 2, Rebuild iPad was written entirely while traveling. While Rebuild was mostly written in europe Rebuild 2 was written in Central America. Rebuild iPad was written in Japan and the Philippines!

    It was great fun to test. I’ve played hours and hours of Rebuild and Rebuild 2 but the iPad game really revitaised the fun for me.

    I hope you find playing it as great an adenture as making it was!

  • Rebuild 2: Coming to iPad 2

    Rebuild for iPad 2
    I wrote most of Rebuild for iPad in the Philippines
    I wrote about AIR for iOS earlier in the year, but got caught up with Rebuild 2 before I could actually release any iOS game. By the time I got back to it, Adobe had just released AIR 3.0, and FlashDevelop 4.0 now comes with an AIR Mobile AS3 project that makes building Flash games to run on iPhone/iPad and Android a snap.

    AIR 3.0 is definitely faster than 2.6, but I still ran into some major performance issues when adapting Rebuild 2 for iPad. It came down to dragging the big map around. In its original vector form, the map moved slowly and chunkily as all the buildings were rendered at every frame. As one gigantic bitmap it was quick as can be, but a 2000×2000 bitmap takes up far too much ram. I found an optimum middle ground but including the bulky AIR interpreter I regularly need up to 100mb, and the iPad 1 only has 256mb ram in total. So, what I’m saying is… Rebuild 2 is coming to iPad 2 and only 2. Sorry early adopters, you should have waited a year for the iPad with twice the ram and faster cpu & gpu. And a camera.

    I also had to work around a shocking number of bugs in AIR 3.0 Mobile. Mostly display issues that could be solved by converting things into bitmaps before displaying them, each time increasing the amount of ram the game needs. Then, I was pretty sad I couldn’t add Game Center support without fiddling with Native Extensions in Xcode. I’m looking to pay someone to do this, because of course I’m The Girl Who Wrote An IPad Game Without A Mac.

    Almost. Apple removed their web-based system for uploading binaries around the same time 3rd party compilers made it possible to build from Windows or Linux. Now, you can only upload using Apple software running in Mac OS. Sigh.

    New Buildings in Rebuild iPhone
    What are those new buildings there?
    But enough with the technical. Although the iPad version is a port of Rebuild 2 Flash, I added some new content to the game as a thank you for fans of Rebuild 2 who buy it. There are two new buildings, and one is linked to a new branch of tech. Some fresh events spattered about, and an entirely new story arc and ending written by my husband Colin. You can discover it for yourself (assuming you have an iPad 2) later this month.



    Fun Rebuild fact: in the programming code, survivors are called “Colins”.

  • Tokyo Ate My Work/Life Balance

    Us Not Working

    When people hear that we travel full-time while working on our games the most common question is: “How do you find the time to work while you travel?”

    Mostly the answer is “stay somewhere for two or three months”. By staying somewhere for an extended period you can get past the novelty shock of a new place. The first few weeks is usually a write-off as you explore and lean about the new place you’ve found yourself. But after that you start to find a rhythm, the laptops can come out and you can start pounding out lines of code.

    There are places that are better for working and places that are worse. Tropical paradise is pretty easy. When you’re on a beach in Costa Rica or Thailand or Honduras you don’t really have that much to do. There aren’t many people around so you probably don’t have many local friends and there isn’t that much to do besides go snorkeling or swimming for a couple hours a day. That leaves you with a lot of time to just enjoy a banana smoothie and the sounds of the waves while you get some work done. Plus your Internet is probably pretty bad so you’re not going to be streaming any YouTube (streaming video is a big time-sink for me).

    The harder places to work are big interesting cities. There’s always something to do and something to see. Since there are a lot more people in big cities you’ll probably make more local friends and so you’ll go out more. Friends are a real drag when you’re trying to get work done :) Istanbul was really hard to get any work done. San Francisco is pretty hard even though most of our friends there work 9-5 but for the last month we’ve been in Tokyo. Ack.

    Tokyo is the biggest city in the world and it’s very diverse. Every neighbourhood used to be its own city and they all feel very different. Tokyo feels like a whole country where you can take local trains to get between the cities. Imagine if you could go from Paris to Berlin in half an hour for 2$. Would you get much work done? Worse, we have a bunch of friends here now.

    So I haven’t gotten a lot done this month. I’ve done some PR, given some interviews, worked on the website. All that stuff is important. But if I’m really going to get any work done on Incredipede I’m gonna need a hammock and an ocean. Luckily the Philippines is next on the list and should provide the perfect atmosphere. Unfortunately we’re traveling with friends!