Tuesday, February 28, 2012

Create a Top-Down RPG in Flixel: Your First Room

In this tutorial we will go from asking “What is Flixel?” to having an indoor room and a keyboard-controlled character in the top-down role playing game style (think Zelda).


Final Result Preview

Let’s take a look at the final result we will be working towards:


Step 1: Understanding the Project Structure

For the visual people among us, let’s see how everything will be organized so the rest will make sense.

list of all the source files and folders used in the project

Basically, we have all of our artwork stored in the assets folder and all of our ActionScript files stored in the src folder. If you want to use this tutorial as the basis for your own game engine, the topdown folder contains the generic stuff (a.k.a. the engine) and the tutorial folder shows how to use it.

You’ll probably notice rather quickly that the art files have really long names. Rather than showing you a tutorial filled with compelling red boxes (the apex of my artistic ability), we will use some open source artwork from OpenGameArt. Each file is named to show the source, the artist, and the license. So, for example, armor (opengameart - Redshrike - ccby30).png means it’s an image of armor, downloaded from OpenGameArt, created by the artist known as Redshrike, and it uses the CC-BY-30 license (Creative Commons Attribution).

Long story short – these art files can be used for any purpose as long as we link back to the site and give credit to the artist.

Here’s a description of each source file in the project:

  • topdown/TopDownEntity.as – base class for any moveable sprites in our top-down RPG
  • topdown/TopDownLevel.as – base class for a top-down RPG level
  • tutorial/Assets.as – imports any images that we need to use in this tutorial
  • tutorial/IndoorHouseLevel.as – defines an indoor room with some objects lying around
  • tutorial/Player.as – a keyboard-controlled, animated Ranger
  • tutorial/PlayState.as – Flixel state that controls our game
  • Default.css – an empty file needed to prevent the Flex compiler from giving us a warning
  • Main.as – entry point for the application
  • Preloader.as – Flixel preloader

Now let’s get down to business!


Step 2: Firing Up Flixel

Flixel is a 2D game engine for ActionScript 3. To quote the home page:

Flixel is an open source game-making library that is completely free for personal or commercial use.

The most important thing to know about Flixel is that it is designed to use bitmap images (raster graphics) instead of Flash-style vector graphics. You can use Flash movie clips, but it takes a little massaging. Since I don’t feel like giving a massage today, we will be using images for all our art.

Flixel comes with a tool that creates a dummy project for you. This tool creates the three files that are in the root of our project: Default.css, Main.as, and Preloader.as. These three files form the basis for almost any project in Flixel. Since Default.css is just there to avoid a compiler warning, let’s take a look at Main.as.

package
{
 import org.flixel.*;
 import tutorial.*;

 [SWF(width="480", height="480", backgroundColor="#ffffff")]
 [Frame(factoryClass="Preloader")]
 public class Main extends FlxGame
 {
  /**
   * Constructor
   */
  public function Main() {
   super(240, 240, PlayState, 2);
  }
 }
}

There are only three lines of importance here. First off, we tell Flash to use a 480×480 window with a white background. Then we tell Flash to use our Preloader class while loading. Finally, we tell Flixel to use a 240×240 window (zooming in by a factor of 2 to make things look bigger) and to use PlayState once everything is ready to go.

Let me share a quick word about Flixel’s states. In Flixel, states are kind of like a window, but you can only have one at a time. So, for example, you could have a state for your game’s main menu (MainMenu), and when a user clicks the Start Game button you switch to PlayState. Since we want our game to just get going immediately, we just need one state (PlayState).

Next up is Preloader.as.

package
{
 import org.flixel.system.FlxPreloader;

 public class Preloader extends FlxPreloader
 {
  /**
   * Constructor
   */
  public function Preloader():void {
   className = "Main";
   super();
  }
 }
}

Not much to see here. Since we extend from FlxPreloader, Flixel really just takes care of it. The only thing to note is that if you changed Main to some other name, you would have to change className here on the highlighted line.

We’re almost up to seeing something on the screen now. All we need is a Flixel state to get the ball rolling, so here’s PlayState.as.

package tutorial
{
 import org.flixel.*;

 /**
  * State for actually playing the game
  * @author Cody Sandahl
  */
 public class PlayState extends FlxState
 {
  /**
   * Create state
   */
  override public function create():void {
   FlxG.mouse.show();
  }
 }
}

If you compiled this code, you’d get a marvelous black screen with a mouse cursor. Never fear, it gets better from here.


Step 3: Creating a Basic Level

[...]

Read more: Create a Top-Down RPG in Flixel: Your First Room

Sunday, February 26, 2012

Epic Flash memory leak track down

Have you ever had a memory instantiation problem that was impossible to track down? Here is a post that might help you with that kind of thing!

Beware! This post is very long… but VERY instructive! If you want to learn some internal mechanism of Flash, I strongly suggest you read it from top to bottom without skipping parts!:)

The Context

Yesterday I was helping Luca (creator of Nape physic engine, made with haXe) to find what seemed to be a big memory leak. There was a couple framework used so it could be directly from Nape… or from Starling… or from debug tool running… or from a port error from haXe…

Memory profiling

So I though it was going to be simple


I got TheMiner running and started profiling. It was pretty easy to find a LOT of memory allocation coming from Starling. The SWC version available is over 4 months old and back then there was a lot of useless instantiation coming from TouchProcessor.as
If you use Starling, I suggest you build from sources as these instantiation are gone now.
There are a couple left but no big deal.

We also saw that Nape was using a LOT of anonymous function call and some try catch. This create what’s called activation-object. And there was a lot of these. So by removing anon-calls and try catch we were able to remove a lot of instanciation.

And After removing the debugging tools, It was clear it was coming from haXe or Nape.

But even when recording all samples allocated by the VM I could not find the damn allocation. (we are talking of more than 1Mo per sec)

Then I wrote a Scala script to try to identify samples that could have been missed, but that didn’t help me much since that was only an override of constructor and constructorProp avm opcodes.

Simplifying the context

So I decided to look a bit further into the bytecode and found something very interesting.

After simplifying the problem multiple time, I got this very simple code to demonstrate the bug.
Because Nape has that very nice abstraction layer, it can support both standard DisplayObject as well as Starling 3D DisplayObject.

The leak happens when Nape try to set the DisplayObject properties like .x, .y, .rotation, etc.
Let’s create a fake DisplayObject class and name it DO [...]

Read more: Epic Flash memory leak track down

Thursday, February 23, 2012

Building An Elevator in Box2D

Introduction

It took me 4 days to build an Elevator via Box2D in Corona SDK. I wrote the actual code and API for it in about 30 minutes. Getting the physics to work proved way more challenging than I anticipated. I’m still learning the ins and outs of Box2D as it relates to game development, so wanted to report on how I went about it and what I learned.

The following article talks about how I’m using Box2D in my game, the 4 approaches I took to building an elevator, and what I eventually decided upon.

Please keep in mind some of the things below are related to Corona SDK’s implementation of Box2D. Thus, some of the issues and compensation measures I took may not need to be done, nor happen, in other implementations and platforms.

Why An Elevator?

Elevators provide an interesting transition in both games and movies. They also provide easier ways for game developers to unload and load a level, provide a rest for the player, and/or make it easy to provide cut scene dialogue to prepare for the player for an upcoming part. In a lot of horror movies, they actually are the focal point of a lot of scary scenes such as Resident Evil, and also provide a perfect setting for comedic relief such as such as Spiderman 2 and Deep Rising (good ole Ipanema).

One of my favorite easter eggs was from Max Payne was in an elevator. You walk into a shoddy NYC apartment building elevator alone, with the notorious off-kilter 3rd person camera. Combined with the absurd brightness in the elevator’s interior amongst a very noir game, the tell tale “elevator muzak” is playing. If you shoot the overhead speaker, Max utters a smirk filled, 2nd word annunciated “Thank you!“.

Romance, fear, death. In such a confined space clearly only meant for short periods of stay, elevators can force us to view the human condition ever more clearly. Many writers play up the claustrophobia aspect, the lack of control as a metaphor for life taking us where it wills to, or preying on our fear of the unknown when you hear bad things just outside the lift walls.

It also helps players in games get from one floor to another in a controlled manner. Kind of like they do in the real world.

How Does Mine Need to Work?

A game I’m building requires that a character inside a building go up a floor in the building he is in. It’s based on a Brooklyn apartment building that has 13 floors with 12 ft ceilings. The character is on the 12th floor and needs to use the standard elevator. It has a call switch on the outside. You press a button and the elevator will arrive at the floor the button was pressed. You can optionally walk into the elevator and press the up or down buttons for the same effect. The elevator does not move on it’s own, only when a button is pressed. It currently only operates on 2 floors.

Simple, right? Code wise, it was. Here’s the Lua class on Github. The only thing to really note is the goUp, goDown, and tick functions. The goUp and goDown simply set flags so the elevator knows where to go. The tick function handles the actual movement via the game loop. Distance joints, which I’ll cover in a minute, are not powered by motors, so I just increment or decrement the length to move it up or down.

Brief On Box2D

Read more: Building An Elevator in Box2D

Tuesday, February 21, 2012

Keep Your Flash Project’s Memory Usage Stable With Object Pooling

Memory usage is an aspect of development that you really have to be careful about, or it might end up slowing down your app, taking up a lot of memory or even crashing everything. This tutorial will help you to avoid those bad potential outcomes!


Final Result Preview

Let’s take a look at the final result we will be working towards:

Click anywhere on the stage to create a firework effect, and keep an eye on the memory profiler in the top-left corner.


Step 1: Introduction

If you have ever profiled your application using any profiling tool or used any code or library that tells you the current memory usage of your application, you may have noticed that many times the memory usage goes up, and then goes down again (if you haven’t, your code is superb!). Well, although these spikes caused by big memory usage look kinda cool, it’s not good news for either your application or (consequently) your users. Keep reading to understand why this happens and how to avoid it.


Step 2: Good and Bad Usage

The image below is a really great example of poor memory management. It’s from a prototype of a game. You must notice two important things: the big spikes on memory usage and the memory usage peak. The peak is almost at 540Mb! That means this prototype alone reached the point of using 540Mb of the user’s computer RAM – and that is something you definitely want to avoid.

Bad memory usage

This problem begins when you start creating a lot of object instances in your application. Unused instances will keep using your application’s memory until the garbage collector runs, when they get deallocated – causing the big spikes. An even worse situation happens when the instances simply won’t get deallocated, causing your application’s memory usage to keep growing until something crashes or breaks. If you want to know more about the latter problem and how to avoid it, read this Quick Tip about garbage collection.

In this tutorial we will not address any garbage collector issues. We’ll instead work on building structures that efficiently keep objects in the memory, making its usage completely stable and thus keeping the garbage collector from cleaning up memory, making the application faster. Take a look at the memory usage of the same prototype above, but this time optimized with the techniques shown here:

Good memory usage

All this improvement can be achieved using object pooling. Read on to understand what it is and how it works.


Step 3: Types of Pools

Object pooling is a technique wherein a pre-defined number of objects are created when the application is initialized, and kept in the memory during the entire application lifetime. The object pool gives objects when the application requests them, and resets the objects back to the initial state when the application is finished using them. There are many types of object pools, but we will only take a look at two of them: the static and the dynamic object pools [...]

Read more: Keep Your Flash Project’s Memory Usage Stable With Object Pooling

Friday, February 3, 2012

HOWTO: Join multiple SWF files into one with AIR for iOS

A while back, I promised to write some of the backstage tips that made it possible for Machinarium (1 GB sources!, 28 SWFs!) to run on an iPad with AIR, which requires only a single SWF.

One of the issues you run into is how to join/concatenate 28 SWFs into single SWF. I wrote an article about using SWC libraries for that here Compiling big Flash/AIR projects with lot of SWFs for iOS. This sometimes works, but very often the workflow is more complex and you want to keep the same SWF files for Android and iOS and use them at least in a bit similar way. On Android you can however load SWF files at the runtime and this is very effective for the memory usage. On iOS you have to watch this, especially when you have everything in a single SWF. So, ideally you place all assets into separate files and load them and dispose them on-demand. But that’s more of a general problem you should keep in mind – every asset that doesn’t contain AS3 (pictures, videos, music), put aside. But back to the topic.

Now comes the magic by David ‘Oldes’ Oliva (the lead developer of Machinarium) from Amanita Design, who made it all possible and wrote a script which can be used for joining SWFs together.

Note: This solution allows you to use multiple SWF files containing AS3 script and logic in each of them, not only for assets. That’s why it’s so powerful.

*prerequisite: you’ll need to understand how to work with the command-line on Mac or Windows.

Steps:

1) Prepare SWFs like you were using them the standard way, but instead of loading them dynamically via the Loader class, SWFLoader or a similar mechanism, each SWF has to be Class (or contain at least one, can contain more), which you can instantiate. That’s because once you join all SWFs together, you will be instantiating it’s contents, not loading.

2) Download the samples package rswf-join-example.7z (for unzipping use 7-zip compatible tool)

3) Download the REBOL script view environment http://www.rebol.com/download-view.html

Using the tool:

4) Navigate to the samples folder. There are three scripts that you might want adjust to fit your workflow:

compile-and-run.r
- this is the rebol script that does part of the job and runs Game.bat

Game.bat
- here you want to adjust the path to your Flex/AIR SDK so it points to the adl command

Red more: HOWTO: Join multiple SWF files into one with AIR for iOS