Blog posts


  • Can't save changes in SQL Server 2008 Management Studio table design?

    March 27, 2013 | Tags: Troubleshooting, SQL

    Made changes in the table designer but SQL Server 2008 Management Studio won't let you save?

    Problem

    This is a kind of annoying new feature in SQL Server 2008 Management Studio. In previous versions you could make changes in the design view of a table and if it wasn't possible to save these changes without dropping the table first you would be noticed about it and have the choice to do so. In the 2008 version you will just get a dialog that says it's not possible to save as it would require a drop:


    "Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can't be re-created or enabled the option Prevent saving changes that require the table to be re-created."

    Your only option is to cancel. Surprisingly this is actually by design.

    Solution

    To turn off this feature, go into the menu Tools / Options and under Designers uncheck the box for "Prevent saving changes that require table re-creation" and save. You will now be able to save your changes and the table will be dropped (loosing current data) to be re-created with your changes.


    Remember to turn back on!It's pretty scary because with this off your table is dropped without any notice. In order to prevent future accidentally drops you should turn this feature back on before you shut down the studio.


  • Must have tools for Flash developers

    March 24, 2013 | Tags: Game development, AIR, Tools, Open source, AS3, Flex, Flash
    There are plenty of good tools to use when developing Flash games and applications. Here I list some of my favourite ones.

    FlashDevelop

    This is the open-source develop environment to use for Flash development. Boosted with code generation and some refactoring options. Use together with Flex/AIR to add compilation right into FlashDevelop reducing the need to have Adobe Flash Professional. You'll find instructions on how to install FlashDevelop with Flex/AIR here. Plenty of 3rd party plugins also available.
    Get FlashDevelopUse together with Flex/AIR as a stand alone IDE.

    Citrus Engine

    This open-source framework brings some of the most powerful  frameworks on the market together. Combining frameworks such as Starling and Away3D with physics engines such as Box2D, Nape and AwayPhysics. Use this framework to really get a kick start in your project. Common platformer game objects are available right out of the box.
    Get Citrus EngineWith Starling, Away3D, DragonBones, Box2D, Nape and AwayPhysics.

    Adobe Scout

    As part of the Adobe Gaming SDK - Adobe Scout is a very powerful profiling tool that even adds the possibility to profile on your mobile devices. Currently available for free on Creative Cloud. To use this profiler fully you need to enable advanced telemetry in your swf-file, something that hasn't been available out-of-the-box with FlashDevelop. To solve this you can use a 3rd party AT-plugin in FlashDevelop or this Python script.
    Get Adobe ScoutRequires free Creative Cloud account.

    TexturePacker

    If you aim to use Starling for development you'll need to use sprite sheets/texture atlases in order to effectively utilize the graphics processor required to get good performance on mobile devices. TexturePacker is your choice for this. Compile your sprite sheet by adding images, swf-files or Photoshop files (.psd) and select the export format. Plenty of output formats available to cater for most game engines out there, also supporting advanced image formats like PVR.
    Get TexturePackerPowerful sprite sheet creator. Try it for free.

    DragonBones

    This is currently my primary choice of 2d skeletal animation tools. I'm really looking forward to start using Spine, but since it not yet have an AS3 runtime DragonBones will be my choice in the meantime. There's also Spriter to consider if you don't have Flash CS 5.5 or later (required by DragonBones as the animator is a plugin panel). Find further information about the three different tools here.
    Get DragonBonesRequires Adobe Flash Professional CS5.5 or later.

    PhysicsEditor

    Defining advanced shapes manually to use with physics engines can be a real hassle. Thankfully there exists tools like PhysicsEditor that will allow you to define even the most complex shapes with ease and export as code (both Box2D and Nape supported). Start by auto tracing your sprites and - if necessary - tweak the shapes manually, set the parameters for your physics object (based on your choice of physics engine) and export the code. Supports most major game engines out there (not limited to Flash).
    Get PhysicsEditorCreate physics objects with ease. Try it for free.

    Feathers

    Feathers is an open-source project that works on top of Starling to add highly responsive UI components that will work from mobile devices to desktops. Great for building nice looking user interfaces.
    Get FeathersUse together with Starling.

    Tiled

    Versatile map editor that beside tiles (both normal and isometric) support creation of vectors such as polygons, rectangles and ellipses which makes it ideal to use for defining static physics objects such as platforms, sensors (coins, signs, etc). Citrus Engine (mentioned above) has a loader for the Tiled map-format.
    Get TiledPowerful and free map editor.

  • Multi resolution development with Flash

    March 08, 2013 | Tags: Game development, Actionscript, AS3, Flex, Flash

    This is the second post aimed at app development using Flash. The previous post showed how to create a simple app with Flash.This post will explain how to develop for multiple resolutions, something that is necessary on the mobile market where the screen resolution may vary from 426x320 pixels up to full HD. Not only does the screen resolution vary, the screen ratio does also vary ranging from 16:9 to 4:3.


    The theory

    So, how does one cater for all these resolutions? Simply put, you develop based on the lowest resolution and then scale upwards. This way you only have one code base and instead trust the graphics engine to get it right.

    But wouldn't scaling low-res graphics onto a full HD screen look extremely fuzzy? Yes, it would. And that's why you need to provide multiple sets of graphics. Although we are going to develop for the smallest resolution up scaling graphics hundreds of percentage is not a good idea. Instead we will provide graphics in multiples of the smallest resolution and use the ones that best matches the display. For instance, if we need to display an image twice the size compared to the smallest resolution that we develop for we will use graphics that is twice the size.

    The difference is displayed below:

    One of the decisions that we need to make is how we want to handle different ratios. Let say that we choose to develop for a 3:2 format (let say basing our project on the original iPhone size 320x480). How do we wish it to scale onto a 4:3 or 16:9 display? We have two choices; either we'll scale to fit all or we'll scale so that there's no borders:

    Decision time

    We decide to develop for 320x480, a 3:2 aspect ratio. We will provide graphics in 1x, 2x and 3x. That means that we will have pixel perfect graphics for 320x480, 640x960, 960x1440. Any resolution in between will display scaled graphics.

    All code we write will assume that we're on a 320x480 screen, and the graphics engine will handle all scaling for us. If we for instance place an image sized 32x32 at position 10, 20 - it will appear on a 640x960 screen as a 64x64 image at 20, 40, as the scale factor between 320x480 and 640x960 is 2.

    As we're more interested in that all our content is displayed properly than that the complete screen is used all the time we will select the scale-to-fit mode. This ensures that everything is visible even if it means adding borders to the left and right or above and beneath.

    Let's write some code!

    It's time to test this out. We'll do the development in FlashDevelop using Starling as the framework of choice. We'll be using our last project - which you find here to download (or this complete project already done here to save some time).

    Let´s start by writing the main class. Compared to the last project we'll add a little bit more code in the Starling setup. We'll set a viewport - which is the largest work area that matches our requested ratio against the screen size - and stage size to a predefined value, in this case 320x480.

    Main.as:
    package {
    import flash.desktop.NativeApplication;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import starling.core.Starling;
    import starling.utils.RectangleUtil;
    import starling.utils.ScaleMode;

    public class Main extends Sprite {
    private static const STAGE_WIDTH:int = 320;
    private static const STAGE_HEIGHT:int = 480;

    private var _starling:Starling;

    public function Main():void {
    // Tell Flash not to scale, that will be done by Starling instead
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;

    // Trigger an event handler when application looses focus (see note in handler).
    stage.addEventListener(Event.DEACTIVATE, deactivate);

    setupStarling();
    }

    private function setupStarling():void {
    // Get the preferred stage size based on our smallest target resolution
    var stageArea:Rectangle = new Rectangle(0, 0, STAGE_WIDTH, STAGE_HEIGHT);

    // Get the fullscreen size available
    var fullscreenArea:Rectangle = new Rectangle(0, 0, stage.fullScreenWidth, stage.fullScreenHeight);

    // Fit the stage to the full screen. ScaleMode.SHOW_ALL ensures that everything will be visible (not croping will occur).
    var viewport:Rectangle = RectangleUtil.fit(stageArea, fullscreenArea, ScaleMode.SHOW_ALL);

    // Create a new instance and pass our class, the stage and the wished viewport
    _starling = new Starling(MyStarlingApp, stage, viewport);

    // Show debug stats
    _starling.showStats = true;

    // Define level of antialiasing,
    _starling.antiAliasing = 1;

    // Set to our preferred stage size
    _starling.stage.stageWidth = STAGE_WIDTH;
    _starling.stage.stageHeight = STAGE_HEIGHT;

    _starling.start();
    }

    private function deactivate(e:Event):void {
    // Auto-close the application when it looses focus. This is what you want
    // to do if you don't want that your application continues to run in the
    // background if the user switch program, answer a call or anything else
    // that would cause your application to lose focus.
    //
    // If you want to keep it running you should at least pause it until the
    // user returns. That's achieved by calling _starling.stop(). You should
    // also add an event listener for the Event.ACTIVATE event that will
    // trigger _starling.start() once the application get's focus again.
    //
    NativeApplication.nativeApplication.exit();
    }
    }
    }

    As we selected to work from the 320x480 resolution and scale it to fit - the top left corner is always at 0, 0 and the bottom right at 320, 480.

    We go over to MyStarlingApp.as and add three images to use for 1x (320x480), 2x (640x960) and 3x (960x1440). We will read the value in Starling.contentScaleFactor to get the scale factor and chose the appropriate image. Up to scale factor 1.5 we'll use 1x, 1.5 to 2.5 we'll use 2x and for anything above 3x.

    We'll also add a TextField to display some text.

    MyStarlingApp.as:
    package {
    import flash.display.Bitmap;
    import starling.core.Starling;
    import starling.display.Image;
    import starling.display.Quad;
    import starling.display.Sprite;
    import starling.events.Event;
    import starling.text.TextField;
    import starling.textures.Texture;

    public class MyStarlingApp extends Sprite {

    [Embed(source="/../assets/1x/Happy.png")]
    private static const MyImage1x:Class

    [Embed(source="/../assets/2x/Happy.png")]
    private static const MyImage2x:Class

    [Embed(source="/../assets/3x/Happy.png")]
    private static const MyImage3x:Class

    private var _image:Image;

    public function MyStarlingApp() {
    super();

    addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

    private function onAddedToStage(e:Event):void {
    removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    addEventListener(Event.ENTER_FRAME, onEnterFrame);

    createAndShowImage();
    addTextField();
    }

    private function addTextField():void {
    // Add a textfield containing some text
    var textContent:String = "Our scale factor is " + Math.round(Starling.contentScaleFactor);
    var textfield:TextField = new TextField(300, 120, textContent, "Arial", 32);
    textfield.autoScale = true;
    textfield.x = 10;
    textfield.y = 360;
    textfield.hAlign = "center";
    textfield.vAlign = "center";
    addChild(textfield);
    }

    private function createAndShowImage():void {
    // Create bitmap instance and use it to create an image
    _image = getCorrectImageForThisDisplay();

    // Change images origin to it's center
    // (Otherwise by default it's top left)
    _image.pivotX = _image.width / 2;
    _image.pivotY = _image.height / 2;

    // Where to place the image on screen
    _image.x = stage.stageWidth / 2;
    _image.y = stage.stageHeight / 2;

    // Add image to display in order to show it
    addChild(_image);
    }

    private function getCorrectImageForThisDisplay():Image {
    // Get the scaling factor (1, 2, 3 etc)
    var scalingFactor:int = Math.round(Starling.contentScaleFactor);

    if (scalingFactor == 1) {
    return Image.fromBitmap(new MyImage1x(), false, 1);
    }
    else if (scalingFactor == 2) {
    return Image.fromBitmap(new MyImage2x(), false, 2);
    }
    else {
    return Image.fromBitmap(new MyImage3x(), false, 3);
    }
    // If you have a 4x version of the graphics, here is the place to add some code..
    }

    private function onEnterFrame(e:Event):void {
    // Rotate slightly each frame
    _image.rotation -= 0.01;

    // Side-note: The value for rotation is in radians not degrees.
    // If you want to use degrees you convert them to radians like this:
    //
    // radians = degrees * Math.PI / 180
    }
    }
    }
    Don't use EmbedWe're using Embed to add images to our project but in a real project you should use a loader instead. By using Embed all the content is read into memory when the application loads, this will occupy valuable memory which could be better used. Especially phones have limited memory, so best practice is to only load the things you need.

    Set debugger size

    We'll start out running this on a smaller screen that will use our 1x version of the image. Open Run.bat in the project root and set SCREEN_SIZE to iPhone. This will run the application in a 320x480 sized window.


    Hit F5 to run the application. The text should say that we're using the 1x version of the image.

    Exit the application and edit Run.bat again. This time change SCREEN_SIZE to iPhoneRetina. This will run the application in a 640x960 sized window.

    Once again hit F5 to run the application. The text should now have changed to say 2x.

    Test out your project with a couple other screen sizes, you find a comprehensive list of available SCREEN_SIZE variables here.

    Epilogue

    We've now updated our project to work on all kinds of resolutions. We can now develop without worrying over what screen resolution our application will run under and place images and other objects at static pixel positions and let Starling handle the scaling.

    In this example we chose to scale to fit so that none of our content would be out of view regardless of which ratio the screen resolution have. The downside of this is that we might get borders on some screens. For games you might want to use the complete screen and scale to fill instead. Important to remember in that case is to define a safe zone on the screen that you know always will be visible regardless if the screen is 4:3, 16:9 or any other ratio.

    Next tutorial will be aimed at gaming and introducing the use of a physics engine. Until then, happy coding!

    Download source codeThe complete FlashDevelop project. You'll need to change the paths in bat\SetupSDK.bat to match your development environment.

  • 2D skeletal animation tools

    February 24, 2013 | Tags: Game development, Tools, Actionscript, AS3, Flash
    The transition from powerful computers towards mobile devices requires optimization when it comes to memory and CPU usage. Pre-rendered animations using sprite sheets will reduce CPU usage alot, but will instead consume memory. A more balanced approach would be to use sprite sheets for body parts and then animate them using skeletal animation tools.

    As a bonus this will also allow blending animations to create a much smoother and lifelike feel as well as introduce access to change animation during runtime.

    This article introduces three different 2d skeletal animation tools. Although I'm writing this from a Flash/AS3/Starling point-of-view most of these tools will work with other platforms as well.



    DragonBones

    DragonBones works as a panel inside of Flash, therefor Flash Professional CS 5.5 or later is needed. The animations are rigged in the usual Flash timeline and then tweaked and exported through the DragonBones panel.

    The official runtimes are really easy to work with, supporting smooth transformation between animations (something you never get using traditional sprite animations) as well as a programmatic API in order to change rotation etc through code.

    Exports both animation definition in XML format as well as a sprite sheet.

    Pros: Free. Good supported runtime. Easy to get started.
    Cons: Requires Flash Professional CS 5.5 or later.

    Price: Free
    Homepage: DragonBones homepage
    Download: Download DragonBones
    Demos: DragonBones demos
    Tutorial: Getting started with DragonBones




    Spriter

    Spriter was funded through Kickstarter last year and is a stand alone tool available for Windows, Mac and Linux.

    Spriter does not provide own runtimes for AS3, instead they've opted to provide developers with information about the file format. This has led to two different AS3 runtimes: SpriterMC and SpriterAS.

    Offered as both a free version with a good set of basic features and an upcoming Pro version which will offer a wider set of features (a comparison of the free and pro version). The Pro version is currently under development.

    Pros: Allows both bone and free animation. Support inverse kinematics. Free version works well.
    Cons: The UI could be easier to work with. Not separate keyframes per bone.

    Price: Free / $25 for Pro version pre-order
    Homepage: Spriter homepage
    Download: Sprite free version
    Videos: Spriter tutorial videos




    Spine

    This tool just got funded on Kickstarter and reached most of the stretched goals, promising a lot of official developed runtimes as well as event timeline, bounding boxes and more.

    An impressively designed user interface makes this a very easy yet powerful tool to use. Providing two views; one for rigging and one for animation. Supports keyframing and tweaking of separate bones and transitions.

    The demo version allows saving but not exporting. Available for Windows, Mac and Linux.

    Pros: Powerful standalone tool. Easy to work with. Support skinning.
    Cons: AS3 runtime is on it's way but not yet available. Official AS3 runtime now exists! :)

    Price: $60
    Homepage: Spine homepage
    Download demo: Download Spine demo
    Tutorial: Spine overview
    Videos: Spine overview


  • Create an Android-app with Flash

    February 13, 2013 | Tags: Game development, AIR, Actionscript, Open source, AS3, Flex, Flash
     


    This post will show you how to get down with Android-app development using Flash/Actionscript. All tools used are free, so no licenses are needed.

    What's neat with using Flash to develop your apps is that it's pretty much platform independent. The same project can be built for web, desktop, Android and iOS. When your app is built for desktop or mobile devices it utilizes something called Adobe AIR (Adobe Integrated Runtime) which is - to simplify it - an alternative way to present Flash content rather than the common Flash player (which usually resides as a plugin of web browsers). On mobile devices AIR is embedded in your application so - to the user - it will work as any other app.

    Rather than using the traditional Flash technology using MovieClips, Sprites etc in a graphical timeline of layers we'll be using the Starling framework which is a very competent game engine (although not limited to game development). This framework uses Flash´s Stage3D technology which - by using the computers GPU (Graphics Processing Unit) - delivers high performance, something that is most important to mobile development since those devices not measure the same computing performance as compared to computers. Starling is also officially embraced by Adobe and is included in the Adobe Gaming SDK.

    Prerequisites

    In order to follow this tutorial, you need the following installed:


    You can the source for this project here.

    Follow this guide on how to install FlashDevelop with Flex and make sure that you also follow these steps in order to patch the Flex SDK with the latest AIR SDK (when written 4.6.0/3.5). If you don't patch the SDK you most likely will end up with errors.

    Download the Android SDK and install. If you don't plan to actually test your project on an Android device you can skip this step.

    Download Starling and extract.

    Let´s start developing!

    Start FlashDevelop and create a "AIR Mobile As3 App" project.
     



    Copy \starling\bin\starling.swc to the project lib-folder.
    (The SWC is the latest stable version and might therefor not be the same as the source included in the archive. But unless you really require a new fix or feature, the stable version is the one to use.)

    In order to use access the content of starling.swc, you need to add it to the class library. This is done by right clicking on the swc in question and select "Add to library".



    Goto the project properties and ensure that the used SDK matches the one under output (when this was written the latest version was Flex 4.6.0 and AIR 3.5, if you need help with installing you'll find information here).


    Under the bat-folder of your new project there is a file called SetupSDK.bat, which most likely need some editing. Open it up and ensure that FLEX_SDK and ANDROID_SDK points toward the two paths where you have the SDKs installed.



    Another file that is good to know is the Run.bat file in the root of your project. This file is responsible for what will happen when you decide to run the project. As default it will run in desktop-mode and with the screen size of a Nexus One (which is 480x762). The last line in the bat file contains a pause-command that will require a key press to close down the command console. Althoug this is good for detecting build errors, it's also a bit unneeded when the build runs fine. You might want to change the pause into a timeout that instead will wait for the specified amount of seconds (or key press) before closing the console.



    The third file to learn before we get down to the actually coding is application.xml in the project´s root. This is where the information about your application is specified. You should start by entering a unique id and name. Preferably this should not be changed later during development. On the other hand, the version number in this file should, in order to keep builds apart.



    Add a new folder to your project called "assets" and place an image into this folder, preferably in the same league size-wise as our project.

    Open src\Main.as and edit accordingly:

    package {
    import flash.desktop.NativeApplication;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import starling.core.Starling;

    public class Main extends Sprite {
    private var _starling:Starling;

    public function Main():void {
    // This time we won't scale our application (check next post for that :).
    stage.scaleMode = StageScaleMode.NO_SCALE;
    stage.align = StageAlign.TOP_LEFT;

    // Trigger an event handler when application looses focus (see note in handler).
    stage.addEventListener(Event.DEACTIVATE, deactivate);

    SetupStarling();
    }

    private function SetupStarling():void {
    // Create a new instance and pass our class and the stage
    _starling = new Starling(MyStarlingApp, stage);

    // Show debug stats
    _starling.showStats = true;

    // Define level of antialiasing,
    _starling.antiAliasing = 1;

    _starling.start();
    }

    private function deactivate(e:Event):void {
    // Auto-close the application when it looses focus. This is what you want
    // to do if you don't want that your application continues to run in the
    // background if the user switch program, answer a call or anything else
    // that would cause your application to lose focus.
    //
    // If you want to keep it running you should at least pause it until the
    // user returns. That's achieved by calling _starling.stop(). You should
    // also add an event listener for the Event.ACTIVATE event that will
    // trigger _starling.start() once the application get's focus again.
    //
    NativeApplication.nativeApplication.exit();
    }
    }
    }

    How to speed up your coding

    FlashDevelop has some neat features to speed up development, one of which is the code generator represented by Ctrl+Shift+1. It allows you to generate reoccurring code such as variables, methods and classes. To use this powerful feature, place the text cursor at the currently not existing class MyStarlingApp, press Ctrl+Shift+1 and select "Create new class".



    Click "Browse" to specify the base class and locate "starling.display.Sprite". Notice that there might be a couple of other classes called Sprite, but it's the Starling one you want.



    Select "Generate constructor matching base class" and hit "Ok" (for sprites it doesn't really matter, but it's good to make this a practice when creating subclasses).



    You are now in your new class!

    Add an event listener (because we want to wait until we're actually on stage before starting to do the magic).

    If classes you want to access in your code aren't already imported you can do this by - yet again - place the cursor at the class name (in this case it will be Event) and then press Ctrl+Shift+1. If only one class exists by the name written it will be autoselected. In case of Event there will be more. Yet again you want the one
    from Starling.

    src\MyStarlingApp.as:

    package {
    import flash.display.Bitmap;
    import starling.display.Image;
    import starling.display.Quad;
    import starling.display.Sprite;
    import starling.events.Event;
    import starling.textures.Texture;

    public class MyStarlingApp extends Sprite {

    [Embed(source="/../assets/Happy.png")]
    private static const MyImage:Class

    private var _image:Image;

    public function MyStarlingApp() {
    super();

    addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    private function onAddedToStage(e:Event):void {
    removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

    createAndShowImage();
    }

    private function createAndShowImage():void {
    // Create bitmap instance and use it to create an image
    var myBitmap:Bitmap = new MyImage();
    _image = Image.fromBitmap(myBitmap);

    // Change images origin to it's center
    // (Otherwise by default it's top left)
    _image.pivotX = _image.width / 2;
    _image.pivotY = _image.height / 2;

    // Where to place the image on screen
    _image.x = stage.stageWidth / 2;
    _image.y = stage.stageHeight / 2;

    // Add image to display in order to show it
    addChild(_image);
    }

    private function onEnterFrame(e:Event):void {
    // Rotate slightly each frame
    _image.rotation -= 0.01;
    }
    }
    }
    Degrees vs RadiansThe value for rotation in Starling is in radians and not degrees.
    If you want to use degrees you convert them to radians like this:

        radians = degrees * Math.PI / 180

    Code clean-up

    Another feature in FlashDevelop that may become useful is the code cleanup. You can perform it either by selecting the area that you wish to format or with nothing selected in order to perform the cleanup on the whole file, and proceed to press Ctrl+Shift+2. If you find that the formatting isn't pleasing you can change a lot of options in the program´s settings to match your preferred style.

    Let's run the app

    Hit F5 to start your application, you should be seeing your image rotating on the screen.

    Pretty neat for such few lines of code? Well now comes the really cool stuff. Let´s build this for Android!

    Build for Android

    First of all, you need a certificate for your app. In the case of Android you can create this by yourself (in opposite to iOS where you need to obtain it from Apple). First, edit bat\SetupApplication.bat and change the password for the Android certificate (AND_CERT_PASS).


    Now it's time to run bat\CreateCertificate.bat, when it's done the new certificate will be present in the cert-folder.

    In the root of your project there's a file called PackageApp.bat, run it. You will be prompted to select your build target. I will make a future post about iOS (or you can go through the generated readme-file called AIR_iOS_readme.txt) so lets pick Android for now. You're opted with three alternatives:
    Normal, debug or captive.

    If you want your app to embed the AIR runtime (so that it doesn't require an additional download and installation of AIR besides your app) you should choose captive. This will also ensure you that your app will be running using that exact build of AIR.

    When finished the dist-folder will contain a new .apk-package for you to install and test on your Android device.

    You'll most likely need to enable your device to allow installation of apps from "unknown sources" (i.e. non-market apps). You'll find a tutorial about how to install non-market apps here.

    Epilogue

    There are plenty of steps yet to take before being a full fledged app-developer - such as handling the many screen resolutions on different devices etc - but I hope this was a quick start to show that app-development is possible using only free tools. And that the reports of Flash´s death are greatly exaggerated.

    Where to go from here? You should definitely get the free book "Introducing Starling" from O´Reilly. This is also a great place to start when learning more about Starling.

    If you're new to Flash and Actionscript you might want to find a good book or two and tutorials about Actionscript 3.

    Good luck with your coding!

    Download source codeThe complete FlashDevelop project. You'll need to change the paths in bat\SetupSDK.bat to match your development environment.