Thursday 20 June 2013

Enable Nape debugging with CitrusEngine.

After initializing the engine you need to enable a onEnterFrame listener to constantly refresh it all the debug images:

This is how I have done it:


           var params:Object = new Object();

           nape = new Nape("nape", params);
           nape.touchable = false;
           enableDebug();
           add(nape);
           


        private function enableDebug():void
        {
            debug = new ShapeDebug(GameVars.SCREEN_X,GameVars.SCREEN_Y);
            debug.drawBodies = true;
            debug.drawSensorArbiters = true;
            debug.drawConstraints = true;
            Starling.current.nativeOverlay.addChild(debug.display);
            stage.addEventListener(Event.ENTER_FRAME, loop );
        }

        public function loop( evt:Event ) : void {
            debug.clear();
            debug.draw(nape.space);
            debug.flush();
        }
It should be easy to adapt it to your needs. It's pretty straight forward!

Monday 17 June 2013

Optimizing performance when developing high responsive apps: Pools

Everything needs to be pooled.

This means that you create objects when they don't exist. When an enemy or bullet get destroyed it will only get destroyed visually, not in the logics of the game.

The engine places that enemy or bullet in a place in the screen that is not possible to interact. Then disable it and wait until a new enemy of the same kind comes into the screen , then we recycle the object and reuse it as new by refreshing or resiting all its variables.

Why this? Creating destroying objects can be very heavy on the CPU when done several times in a frame (or loop). So by avoiding the creation of new objects we will have a smoother game play.

When creating objects we enable themt and when we don't need them, we can just disable them. In my particular game I've created this function to be used with CitrusObjects (from CitrusEngine).
       private function enableObject(status:Boolean):void
        {
            view.pauseAnimation(status); //textures will not update.
            view.visible = status; //will hide the object
            updateCallEnabled = status;//will stop updating each frame.
            _inUse = status;
            set_bodyEnabled(status); //disable collisions
        }

I hope it helps!

Thursday 13 June 2013

From Box2D to Nape in CitrusEngine

Due the massive Garbage generated by Box2D creating memory fragmentation. I will be porting my shoot'em up game Beekyr (using CitrusEngine) from Box2D to Nape.


Firstly, I have changed these physics instance from:
var params:Object = new Object();
params.doSleep = false;
var box2D:Box2D = new Box2D("box2D",params);

box2D.gravity = new b2Vec2(0, 0);

box2D.touchable = false;
box2D.world.SetContinuousPhysics(false);
box2D.velocityIterations = 1;
add(box2D);
to Nape:
var params:Object = new Object();
var nape:Nape = new Nape("nape", params);
nape.gravity = new Vec2(0, 0);
nape.touchable = false;
add(nape);

I changed all my objects from extending Box2DPhysicsObject to NapePhysicsObject.
All my custom fixtures has been erased, and collision groups dissapeared.
_body.SetActive(true/false);
to Nape:
_body.space = null; //to disable
_body.space = _nape.space //to enable.

Updating rotation:
before, Box2D:

_body.setRotation(rads)

now, Nape, (I think this same code should work the box2D wrapper?):

_body.rotation = rads;


Updating velocity:
before, Box2D:

_body.SetLinearVelocity(new b2Vec2(_currentSpeed.x, _currentSpeed.y);

now, Nape, (I think this same code should work the box2D wrapper?):

_body.velocity = new Vec2(_currentSpeed.x, _currentSpeed.y);
But since the units change betweens engines, Im using pixels as unit and updating the position with my own engine:
x +=speed.x;
y +=speed.y;
This is uesful for shoot'em ups but I am very unsure what would happen if I was using real physics, with gravity, etc.

Updating collisions... they use now a different override, but the rest is the same:

before, Box2D:

override public function handleBeginContact(contact:b2Contact):void {
var collisionWith:* = Box2DUtils.CollisionGetOther(this, contact);

now, Nape:

override public function handleBeginContact(contact:InteractionCallback):void {
var collisionWith:* = NapeUtils.CollisionGetOther(this, contact);


now fixtures are not present as such so I needed to change the way I set up the filters and physics:

override protected function defineBody():void {
_bodyType = BodyType.KINEMATIC ;
}

override protected function createFilter():void {
super.createFilter();
_shape.sensorEnabled = true;
_shape.filter.sensorGroup = PhysicsCollisionCategories.Get("enemyBullet");
_shape.filter.sensorMask = PhysicsCollisionCategories.Get("player", "playerBullet");
}

I think I didn't have to change anything else...

Performance doubled on my smartphone, I went from 18-30FPS to constant 30FPS for the game.

Monday 10 June 2013

Optimizing performance in CitrusEngine and Box2D

Performance tips.

I will explain my experience when I was building Beekyr game for AIR using CitrusEngine and Box2D....

This might be applied to other game engines.... but the way Box2D is used might be the same.
When I created first Beekyr stage prototype I had about 2000 objects moving smoothly in screen, Stage3D was just amazing. But I needed the sprites to collide between each other. Everyone recommended to use the physics engine Box2D, even it if was just for collisions (later on I replaced it for Nape engine (for AS3), which is at least twice as fast, click here to see how I converted from Box2D to Nape).

After adding the physics engine, I only was able to have about hundred of objects moving smooth and fast (still no code to make them react with each other).

I didn't realize that a physics engine would make things THAT slow, specially in smartphones, so I had to start optimizing everything:
I made everything to be classified as sensor:
_fixtureDef.isSensor = true;
That means that touching objects can overlap without having a bounce effect or something.

Enable only begin handle contact:
beginContactEnabled = true;
Objects will not react until I enabled at least one form of contact in Citurs Engine.
Then I want to create groups, that means groups with the same ID will not react to each other this is very good when you have loads of real bullets or lots of enemies, this will stop most collision functions to be triggered when the bullets or enemies overlap.
The way to do this is to edit the fixture filter, this is how enemy bodies are filtered:
    override protected function defineFixture():void {
           super.defineFixture();
           _fixtureDef.filter.groupIndex = GameVars.ENEMY_GROUP;
           _fixtureDef.isSensor = true;
        }

Don't ever use isBullet() unless is completelly necesary. This will add more calculations to the engine making it slower.



Monday 27 May 2013

Fitting the game to in any screen resolution.

For my Beekyr Android game it all started as 720p as it would be a Flash game,  but then I realized that the game needed to work in 800x480  for my smartphone... After that, I realized I needed to make it work in more resolutions for the rest of all Android phones out there. I had to think a way to scale the game and assets.... Turned out that is wasn't that hard!
 
Basically, I had to work always with 720p in mind.

When the game loads I need to work out a conversion rate for the resolution. So first lines of code executed, even before the engine :

        public static const ORIGINAL_X:int= 1280;
        public static const ORIGINAL_Y:int = 720;
        public static var SCREEN_X:int;
        public static var SCREEN_Y:int;
      
        public static var REDUCTION_RATIO:Number;
    

   private function getReductionRatio():void
        {
           &nbspSCREEN_X = Capabilities.screenResolutionX;
           &nbspSCREEN_Y = Capabilities.screenResolutionY;
            var ratioX:Number = SCREEN_X / ORIGINAL_X;
            var ratioY:Number = SCREEN_Y / ORIGINAL_Y;

            if (ratioX < ratioY) {
                REDUCTION_RATIO = ratioX;
            }else {
                REDUCTION_RATIO = ratioY;  
            }
        }

Then apply this REDUCTION_RATIO variable to every loaded asset, positions,speeds and basically everything that involved pixels.

Examples:
params.height = size.w*REDUCTION_RATIO;
params.width = size.h*REDUCTION_RATIO;
_bulletSpeed = 38*REDUCTION_RATIO;


If using AssetManager, all the stretching will be done for you if you initialize it like this:
assetsManager = new AssetManager (1 / GameVars.REDUCTION_RATIO, false);

But if you are converting textures manually then convert them like this:
Texture.fromBitmap(bitmap,false,true,1/GameVars.REDUCTION_RATIO);
This will still use same amounts of Texture Memory in 720 than 480 or 320. If you have troubles with that , load different assets that are smaller and change the REDUCTION RATIO.

In my case, load / unload assets between stages, works well too.
I never reached 128MB of VRAM (more or less, the minimum memory these days: ipad1).

It takes time and real concentration to make it work well but when is done it works flawlessly.

Enjoy.

Tuesday 21 May 2013

Career Shift : from Flash websites to AIR apps

I have been developing websites since 2004, I immediately jumped into Flash when I knew about it. This plug-in let me do really amazing things when you compared it with the HTML3-4 limits...

I worked for years as Flash developer along with very few PHP jobs. But Flash was becoming stronger. It was a solid OOP language and very tested plug-in without hardly any flaws.... until Steve Jobbs told otherwise and everyone believed him, they didn't realize it was all a war between Apple and Adobe, and everybody lost. Only the apple man won his own personal fight.

With all of this in mind I tried to make a game in Flash 10. I wanted to add many graphics and effects but I couldn't get anything very complex working due the lack of GPU acceleration. So I left the game in a playable state, but it was too simple. I had to discard the idea of making complex flash games.

Meanwhile Adobe didn't know how to handle the fight with Apple. Nevertheless Adobe released the best update ever made for flash: molehill - Stage3D. It was the beginning of triple A games in Flash. But it was all obscured with the war.

I realized about this and knew I was finally able to make complex games in flash... but flash sites were starting to die, all iProducts didn't accept flash so the world had to adapt to this (instead of the other way).

I didn't see the GPU acceleration happening in mobile phones until very late 2012. By then market almost already shifted back to old HTML. I was sure that didn't like this backwards step. In fact it was a waste of time for me, I lost all interest in the web: coding with JavaScript (no OOP) is a total nightmare when you add browsers variety to the equation.
So I had no choice other than leaving the web scene and move into apps/games.

I wanted to make games, I didn't mind what language so I researched into some of them: coronaSDK, Unity3D, phoneGap. But a friend told me about CitrusEngine framework for flash Stage3D. So I started working heavily for a month or two to get a demo that looked and and was responsive in Flash at very high frame rates... I was impressed as that was exactly what I had in mind a year back...
Only then,  I decided to make a real game. I got in touch with two friends that were able to work with me: Diego Gangl (amazing artist) and Mete Burch (modern musician). I ended up leading a team making the awesome game I always wanted and playable in most Android phones:
Beekyr

I made it in adobe AIR to be able to get to android devices. It was a really good decision. In the other hand it was also difficult to make the app perform well in these low powered devices. I was used to powerful PCs but I had to work hard to optimize everything and learn some very interesting techniques to make it run smooth everywhere.

So now, in 2013, the history carries on as Indie Developer.
I hope I can manage it well and live from making good quality games!

Friday 17 May 2013

TouchPad class for AS3 + Starling (Rev.2)

A month ago I shared a touch class that was pretty useful to play games in smart-phones but after some testing I realized that didn't work well when moving (with left thumb) + shooting (with right thumb) and pressing them alternatively.

After a bit of thinking, I have improved the class and now it will use always the left thumb to move and the right to shoot keeping the previous functionality. (But you can invert this easily, it have upgrade my class but it is still not public as I want to add more features before posting about it again!)

There is some tap functionality I need to implement, that will be in an future release: Ver.3....

Here it is, enjoy (for AIR or AS3):
(feel free to contribute to the class commenting here or in Starling Forum).



Class: TouchPad.as

package beekyr.controllers
{
    import flash.geom.Point;
    import starling.display.Quad;
    import starling.events.Touch;
    import starling.events.TouchEvent;
    import starling.events.TouchPhase;
    public class TouchPad extends Quad
    {
    /**
     * ...
     * @author Jaime Dominguez for Beekyr (2013)
     * http://www.jaimedominguez.com
     */
       
        private var _moveVector:Point = new Point();
        private var _tapVector:Point = new Point();
        private var _latestVector:TouchData = new TouchData();
        private var _sensitivity:Number;
        private var _touching:Boolean;
        private var _dualTouching:Boolean;
        private const TAP_SENSITIVITY:Number = 2;
        private var _tap:Boolean;
        private var _justTapped:Boolean;
       
       
        public function TouchPad(width:int, height:int, sensitivity:Number = 1) {
           
            super(width,height,0xff0000);
            _latestVector = new TouchData();
            _moveVector = new Point();
            _sensitivity = sensitivity;
            _touching = false;
            alpha = 0.05;
            addEventListener(TouchEvent.TOUCH , _handleTouch);
        }
       
        public function getLatestMovement():TouchData     {
            _latestVector._vX = _moveVector.x * _sensitivity;
            _latestVector._vY = _moveVector.y * _sensitivity;
            _latestVector.touching = _touching;
            _latestVector.dualTouching = _dualTouching;
            _latestVector.tap = _tap;
            resetValues();
            return _latestVector;
        }
       
        private function resetValues():void
        {
            _moveVector.x = 0 ;
            _moveVector.y = 0 ;
           
            _tap = false;
        }
       
        public function setWidth(w:Number):void {
            width = w;
        }
       
        public function setHeight(h:Number):void {
            height = h;
        }
       
        public function updateSensitivity(s:Number):void {
            _sensitivity = s;
        }
       
        private function _handleTouch(e:TouchEvent):void {
            e.stopImmediatePropagation()
            var touchArray:Vector. = e.getTouches(this);
            //var _wasDualTouch:Boolean = _dualTouching;
           
            _dualTouching = false;
            dispatchEventWith(TouchPhase.BEGAN);
            if (touchArray.length>0){
                var touch:Touch = touchArray[0];
                if (touchArray.length>1){
                    _dualTouching = true;

                   //If you want to move with the right thumb then edit the next line.
                    if (touchArray[0].getLocation(this).x > touchArray[1].getLocation(this).x) {
                        touch = touchArray[1];
                    }
                }
               
                switch (touch.phase){
                    case TouchPhase.BEGAN:
                        _justTapped = true;
                        storeThisPos(touch);
                    break;
                   
                    case TouchPhase.ENDED:
                        //checkForTap();
                        //stopMovement();
                        _tap = _justTapped;
                        _touching = false;
                    break;
                   
                    case TouchPhase.MOVED:
                        _justTapped = false;
                        getMovementVector(touch);
                    break;
                }
           
               
            }
           
        }
   
               
        private function getMovementVector(touch:Touch):void
        {
            _moveVector = touch.getMovement(this);
       
        }
       
        private function storeThisPos(touch:Touch):void
        {
            _touching = true;
            _tapVector = touch.getMovement(this);
        }
   
    }

}

Class:  TouchData.as 
package beekyr.controllers
{
    /**
     * ...
     * @author Jaime Dominguez
     */
    public class TouchData
    {
        public var _vX:Number;
        public var _vY:Number;

        public var touching:Boolean;
        public var dualTouching:Boolean;
        public var tap:Boolean;
           
        public function TouchData()
        {
           
        }
       
    }

}



Used in Beekyr for Android.

Wednesday 17 April 2013

TouchPad class for AS3+Starling.

When I started developing games for Android I had to work pretty hard to invent a good controller, It has been created to meet the needs of my shooter game Beekyr. But Im sure it will work in other kinds of games.

I couldn't find anything that was good enough so I made one that works very well...

UPDATE, VER2: Allows two fingers and works better than this version. VIEW UPDATE HERE!

At the moment only allows one finger, if you want to extend this class feel free to do so!

package beekyr.controllers
{
    import flash.geom.Point;
    import starling.display.Quad;
    import starling.events.Touch;
    import starling.events.TouchEvent;
    import starling.events.TouchPhase;
    public class TouchPad extends Quad
    {
    /**
     * ...
     * @author Jaime Dominguez for Beekyr : 2013
     * http://www.jaimedominguez.com
     */
       
        private var _moveVector:Point = new Point();
        private var _latestVector:Object = new Object();
        private var _sensitivity:Number;
        private var _touching:Boolean;
       
        public function TouchPad(width:int, height:int, sensitivity:Number = 1) {
            super(width,height,0xff0000);

            _moveVector = new Point();
            _sensitivity = sensitivity;
            _touching = false;
            alpha = 0;
            addEventListener(TouchEvent.TOUCH , _handleTouch);
        }
       
        public function getLatestMovement():Object     {
            _latestVector._vX = _moveVector.x * _sensitivity;
            _latestVector._vY = _moveVector.y * _sensitivity;
            _latestVector.touching = _touching;
            _moveVector.x = 0 ;
            _moveVector.y = 0 ;
            return _latestVector;
   
        }
       
        public function setWidth(w:Number):void {
            width = w;
        }
       
        public function setHeight(h:Number):void {
            height = h;
        }
       
        public function updateSensitivity(s:Number):void {
            _sensitivity = s;
        }
       
        private function _handleTouch(e:TouchEvent):void {
            e.stopImmediatePropagation()
            var touchArray:Vector. = e.getTouches(this);
           
            if (touchArray.length>0){
           
                var touch:Touch = touchArray[0];

                    switch (touch.phase)
                    {
                        case TouchPhase.BEGAN:
                            storeThisPos(touch);
                        break;
                       
                        case TouchPhase.ENDED:
                            stopMovement();
                        break;
                       
                        case TouchPhase.MOVED:
                            getMovementVector(touch);
                        break;
                       
                    }
               
            };
           
        }
       
        private function stopMovement():void
        {
             _moveVector = new Point();
             _moveVector.x = 0;
             _moveVector.y = 0;
             _touching = false;
        }
       
        private function stopMovementVector():void {
            _moveVector = new Point(0, 0);
        }
               
        private function getMovementVector(touch:Touch):void
        {
            _moveVector = touch.getMovement(this);
        }
       
        private function storeThisPos(touch:Touch):void
        {
            _touching = true;
        }
   
    }

}

With this class initialized at start of the game. Then you need to collect the values in each loop of the game with:


_speed = _game._touchPad.getLatestMovement();

IT will return a vector of the lastest movement.

You can adjust the sensitivity too with:


public function updateSensitivity(s:Number):void {
            _sensitivity = s;
        }



 

Monday 8 April 2013

PHP security.


I recently discovered a blog post that I had written back in 2008 but it is still relevant today So I have decided to release it now in 2013.

This was the original post:


I have been recently reading a book about security. And I thought it was good to share all this new knowledge with the rest of the world.

There may be lots of practices that I'll miss but this text intends to be tips to be considered while programming any PHP app. :


Filter all the data you manage:

Golden rule:
All data you receive on your PHP scripts is invalid until is filtered and validated.



Use SSL every time you send sensitive data. Such login details or credit card data.


Differentiate your variables between verified and unverified. Create an empty array where you can copy all clean variables. This way will be a good thing to do verify that you are using the correct valid variables:
$cleanVars = array();

//if a variable is validated successfully you copy the value into the new array:

switch ($_POST['colorEyes']){

case 'brown':
case 'blue':
case 'green':

$cleanVar['colorEyes'] = $_POST['colorEyes']

}


Once you have filtered all the data:

Use htmlentities() to escape HTML code and html_entity_decode() to decode it.

To send strings into SQL queries use: mysql_real_escape_string().

Ask for re-login some times for specially delicate movements such password reset or contact details among others.

To check if a string is alphanumeric use: ctype_alnum()

When receiving a file name link as string you don't want the hackers to be using relative or full paths, you want just file names and deal with the directories on the script. Erase all possibility of path edition on the variables using the function basename()



Include files:
Set the includes outside root directory.
They can be anywhere and make sure that only the server and only your internal user is able to access them no one else need them. Use .htacess for this matter.

Credentials such password and username for databases should be stored in a file named db.inc
Make sure that inc is treated like a php file and if u want to deny all access to INC files u can configure Apache htaccess to deny all requests to that file extension by normal users:

<Files ~ "\.inc(.php)?$">
Order allow,deny
Deny from all
Satisfy All
</Files>


Dangerous functions:

Try to avoid using the next functions:
eval , exec, shell exec, passthru, system, popen, preg_replace, proc_open, file_get_contents, readfile, file, ini_restore, symlink, fsockopen, escapeshellcmd

Then disable them on Apache with disable_functions. If some of the functions above has to be used then be very careful how you use them...


Apache security:

Have a look at the php.ini and have a look at these apache directives:

allow_url_fopen
disable_functions
display_errors
enable_dl
error_reporting
file_uploads
log_errors
magic_quotes_gpc
memory_limit
open_basedir
register_globals
safe_mode (not used anymore?)

They are all gathered in this php.net page, (you have to scroll down, it is not very well structured)...

Wednesday 3 April 2013

Some Apache security.

I recently discovered a blog post that I had written back in 2008 but it is still relevant today. So I have decided to release it now in 2013.

Apache Security

I have been receiving attacks from someone using zombie computers and banning IPs on Apache.
That didn't stop the attacker as he was able to use different IPS for the same attack. So I decided to fix the problem from the root problem.

I checked apache.log and I saw that the attacker was trying to erase some internal Windows files using a PHP file he uploaded by him self using some kind of vulnerability of the XAMPP default settings.

The biggest problem was that I didn't have a password set for phpMyAdmin software so it was like a big hole in the security.

Now I know what to do:
Go to myphpadmin folder and in config.ini
find the next line and set it to authenticate using http and not automatic!

$cfg['Servers'][$i]['auth_type'] = 'http';

Another good thing for security is to disable directory listings. So when a user tries to open a folder, Apache doesn't show the files on the folder...

on .htacess add the following line:

Options -Indexes


Monday 1 April 2013

Improving JSFL performance



I'm currently working with JSFL.

What is JSFL? JavaScript for FLash . It's a scripting language that allows to automatize some tasks interacting with Flash GUI to store or edit data.... like here: It stores the keyframe's properties of specific Movieclips.

I have made a levels editor for my game where I can edit the path of enemies too.


I made it using MovieClips where I would detect key frames and store the coordinates in that frame.

I have all Movieclips stored in the library, and the script I generated checks all objects in library to export the relevant data to JSON, but it was taking too long. How long? About 2 mins to process ~10 paths in a 6 core 3.4GHz machine. This is far too long and would make sense the need to optmize code.

I was processing many things but I isolated the problem:  the bottle neck was the keyframes detector function.

function getKeyframes (layer){
   var keyframes = [];
    for(var f in layer.frames){
      if (f==layer.frames[f].startFrame){
            keyframes.push({
            frame:layer.frames[f],
            index:f
         });
      }
   }
    return keyframes;
};

It was taking very long time per MC. I played with code and I finally improved it by changing it to:


function getKeyframes (layer){
   var keyframes = [];
   var layerFrames = layer.frames;
     for(var f in layerFrames){
      if (f==layerFrames[f].startFrame){
            keyframes.push({
           frame:layerFrames[f],
            index:f
         });
      }
   }
    
    return keyframes;
};

After this, the script takes about 2-3 seconds instead of 2 mins.

A note for the reader: I usually optimize all my code but since this JSFL script is only executed every now and then I didn't think it was necessary to optimize it.

I hope it helps to someone!

Thanks for reading!


  

Tuesday 26 March 2013

Ending up with AIR + Citrus Engine [Starling+Box2D]

Today I want to talk about how I ended up using Citrus Engine.

So, I wanted to create my first game for phones, game-hubs, and maybe Facebook.  Flash is not the only thing out there and I had to look for new technologies. I don't want to get rusty....

I looked at CoronaSDK, PhoneGap, AIR and Unity3D:


Kerb guys told me Corona was good. But I wasn't happy to tray a product that costs $349/yr,,, what if I don't like it? Not sure what to do. I decided to put it on hold and look more and if nothing good comes I would try Corona.





The idea of developing anything serious with HTML and JavaScript, makes me ill. Instantly discarded.





Unity3D
I have a bunch of friends that use it, some of them like it and some don't.

I like the work flow and the GUI. I was extremely familiar with the syntax (C#) so I liked the idea of developing with Unity...

I looked at the prices... and it says:

"Unity Pro :$1,500 All the high-end features today's professional developers need."
Whoops that's a bit pricey.
If I want to develop flash + android + iOS is $1500 extra per OS (that means $6000). No thanks!

There is a free version. Yay!
But.... If I want to export to flash that will be $400. There is more, If i want to export to Android... another $400.... and same thing with iOS, (another $400). Just great.

I would end up paying $1200, so: not free!
I friend told me to have a go anyway, there were some discounts at the time...
So, I almost started with unity3D but I thought that for my first own commercial game I would like to use a technology that I am conformable with. Is hard enough to build a whole game so imagine with a new technology... I decided that I will come back to this technology, when I have some code to port. So the process will be a lot simpler.



I knew AIR has improved a lot since 2012 with stage3D. I already know how to program Flash so AIR would be like a piece of cake for me. In fact is was the same, the used language is ActionScript3. Only hard bit is to set-up the Smartphone drivers and the rest of the GoogleSDK.

I didn't have to pay extra for anything, you can even do it all for free with AIR-SDK  and FlashDevelop. Or pay a little bit and use the official Adobe's AIR/ Flash Builder

Choice was easy... I decided to have a go with this, and perhaps try Unity3D later....

So, after many many weeks I made a choice!



Someone suggested to have a look at CitrusEngine and more engines. I wanted to start developing and this was the only one I saw that used Stage3D... So I got my hands on it.


At first, I was not happy about using an framework/ engine. Usually, I develop 99% of the code I use. But turned out that was pretty good as simplifies the process of making games. Apparently CE was designed for platformers but I am making a shooter.

I found it hard to start with because the lack of documentation for CitrusEngine + [Starling/Away3D] + [Box2D/Nape/AwayPhysics] back then.




I told Aymeric (main CE developer) that I was getting stuck all the time in very basic aspects of the game design. They started to improve documentation and start-up examples.

Now,  I think CE has improved lots but still a long way to go. The Engine is constantly evolving and once you understand its mechanics, you will be able to use it to create any kind of game. I'm creating a shooter with complex backgrounds and many enemies in screen and performance is still 50FPS... the performance is good!

I know AIR performance will be improved eventually along with all the frameworks under CE. In fact, it's still very active and it has been improved several times in the 3 months I have been using it.

Have a go, try, Citrus Engine!


Wednesday 9 January 2013

Why flash developers won't go extinct!

I always wanted to work as a games developer. I have created some little games in the past for clients or for myself but always my time has been utterly consumed by my own portfolio websites maker: Electrofolio

In 2010, I made a remake of an old game which was running really well in Flash Player 9 (AS3). 
Later on (late 2010), when I realized that I was the only one excited about my game (playability was amazing),  I decided to add a twist improving graphics adding real animated images instead Tron looking vectorial pictures. Play at the newer version.

Animations were running slower now and FP struggled to move the game at 50FPS plus I couldn't add a parallax scroll effect with bitmaps so I got well disappointed with Flash performance.

In 2011, after Flash beeing totally destroyed by Steve Jobbs, Adobe released a GPU 3D accelerated Flash version called molehill.

I saw several 3D demos and differences with performance were so huge that I decided that I had to go with this new way and stop working with time lines and classic Flash, completely.
I realized that I would take longer to develop apps but this is the way forward.

With the release of Starling 0.8, a friend and I decided to have a go and got involved creating a kaleidoscope game using textures and stage3D. I liked the way it was running. It was pretty fast!

It was a real shame seeing everyday Flash was dieing slowly with so much power on its hands!
Flash was almost dead and Flash-haters where everywhere making so much noise that even myself had really deep thoughts of leaving the technology.
 
I had a go making trying to develop a slide-show with HTML5 that worked everywhere.... Hey! that's what HTML5 is all about, right? Well it's WRONG. It worked in some devices and some didn't execute the JavaScript / CSS combination right....  I was trapped between a dyeing technology and a really over-hyped technology.

In that moment, beginning of 2012, Flash saw its end in phones and tablets. It was one of the worst stages for Flash developers but there was still hope to use our actionscript good skills, an exit, developing AIR apps instead of web apps. That was a great idea! Sadly, my phone (Samsung Galaxy ACE 1) didn't support AIR... I got really down and kept working on Electrofolio (Flash, PHP, mySQL, HTML, JS, CSS, blablabla) for almost a year until I read a very positive post of making money with AIR and iOS+Android.
http://www.esdot.ca/site/2012/journey-of-an-air-developer

Now, I have decided that this has been dragged for too long, This time I'm decided to invest real time in making games. I got a newer phone (Samsung Galaxy S3 mini) which supports AIR and I right away I started developing for Android. I got registered in play.google.com for 25 US$ and adapted an old flash 9 recycling game I made in the past using normal timeline - AS3.

It was very simple drag and drop game and turned out that works pretty well...
Get the game for Android (updated in 2013)

Compare it with the Flash version:
Flash Version (made in 2010)

I think there is big potential being able to release games to several devices with just one click and monetize visits.

I took a look at adMob,  and set up an account, it took me almost a whole day to implement it all:

I got a free AIR native extension that works OK and now I am monetizing my first project. It's hardly any money but if I keep creating games they will all add up making my develop time more monetized.

I see a brighter future, this is is how continues. I will post more about this.