Monday, July 29, 2013

Haxe 3, OpenFL, Native extensions

It's been a while since I wrote anything and a lot has happened since the last post, to recap, I went from C# to AS3 to Haxe.

Haxe is a cross platform language that allows you to create mobile/desktop/web applications (Games!) from a single code base. The premise of writing once play everywhere has been pushed a lot in the latest years, we have Unity (paid), Xamarin (paid), Stencyl (paid/free), Adobe Air(free but meh), Cocos2dx (free), etc.

They all have their ups and downs, but then we have Haxe. It is completely free and very easy to use if you have experience with Java/AS3/C#.

Haxe is great, just like C# is great but C# wouldn't have been that good to me if it wasn't for the right SDK, back in the day XNA was the most amazing tool for programmers like me that were just getting into game development, it handled all the complicated stuff and left us with the only task to make a game, Haxe has its own XNA and it is called OpenFL (before that there was NME, by the same creator).

OpenFL simulates the Flash API and more. Besides having all the necessary elements to create a game with OpenFL it also allows for extensions to native libraries, this is extremely important when targeting mobile platforms since we need to access to these native libraries to implement things such as in app purchases, ads, social media, etc. Without those elements we could not monetize our works.

The biggest problem I have encountered is the lack of documentation or examples online on how to implement things, there are some but sometimes they tend to be outdated (maybe this will be outdated when you read it) or are overly complicated to follow, in any case you must look for the answers a lot in order to find something (also a lot of trial and error, don't get discouraged!)

I would like to give you an example based on this blog about chartboost

That blog post put me in the right direction to figure out how to add a native extension to android, and this is what I came up with.

First we create a new OpenFL project (I am going to assume you have installed FlashDevelop, the latest Haxe 3, and the latest OpenFL, if you havent take a look at this: FlashDevelop and this Haxe/OpenFL )

To create an openfl project you are going to need to open the command prompt, navigate to a destination folder you want to use (I created my project in the desktop so I went to cd desktop) and finally type openfl create project "project name" hit enter and you created an openFL project. If you open the project in FlashDevelop and hit run you will be greeted with an empty window.

The next step would be to acquire the native library, head over to Here and download the SDK for android, also register for an account to obtain your "App id" and "App signature", save this information somewhere, we are going to use it later on. Now we need to create a folder in your project that will contain all your libraries, you can create it anywhere within the project but for the purpose of clarity we are going to create a new folder in the Assets folder, name it "libs" (lower case) and add the charboost.jar file to it.

so now you should have:

|Test
. . |Assets
. . . . |nme.svg
. . . . |libs
. . . . . . |chartboost.jar
. . |Source
. . . . |Main.hx
. . |project.xml


Great so, the next step would be to tell your project that you have an external jar you want to compile for android. For this you are going to need to open the "project.xml" file, in there you can see some information that defines your project, think of it has the manager that holds the entire thing together.

add the following to it:

<template path="Assets/libs/chartboost.jar" rename="libs/chartboost.jar" if="android"/>

Let me explain what that will do, first it will locate the chartboost.jar file in your project, then when compiling for android only, it will add the charboost.jar file to your libs folder (created by the compiler when building for android), this is all you need in order to successfully add a library to android, next step would be how to use it.

To be able to use the library we first need to modify the MainActivity template that gets created when you build for android. But first in order to be able to build for android you are going to need a device or an emulator, setting this up is not that complicated but that is beyond the scope of this tutorial, after you have your emulator/device ready go ahead and build for android, there are 2 ways of doing this, either by selecting android in FlashDevelop as the target or by using the command prompt, navigate to your project folder where the project.xml is and type openfl test android -debug this will build the project for android.

once this is done building it would have created a bunch of files and folders, you should now have

|Test
. . |Assets
. . . . |nme.svg
. . . . |libs
. . . . . . |chartboost.jar
. . |Export
. . . . |android
. . . . . . |bin
. . . . . . . . |bin +
. . . . . . . . |gen +
. . . . . . . . |libs
. . . . . . . . . . |armeabi +
. . . . . . . . . . |chartboost.jar
. . . . . . . . |res +
. . . . . . . . |src
. . . . . . . . . . |com
. . . . . . . . . . . . |example
. . . . . . . . . . . . . . |test
. . . . . . . . . . . . . . . . |MainActivity.java
. . . . . . . . |AndroidManifest.xml
. . . . . . . . |build.xml
. . . . . . . . |default.properties
. . . . . . |haxe +
. . |Source
. . . . |Main.hx
. . |project.xml

notice that your charboost.jar file was added to the android libs and that's exactly what we wanted. Now we are going to need to create a folder for our java code, do this directly in the main project folder "Test", call it "java" so you will have

|Test
. . |Assets +
. . |Export +
. . |Source +
. . |java
. . |project.xml

go to the Export/android/bin/src/com/example/test and copy the MainActivity.java, paste it into your new java folder so we now have:

|Test
. . |Assets +
. . |Export +
. . |Source +
. . |java
. . . . |MainActivity.java
. . |project.xml

Double click the main activity in your java folder to open it, we are going to edit it now, add the following code (straight from the blog I quoted earlier):

package ::APP_PACKAGE::;

import android.os.Bundle;
import com.chartboost.sdk.*;

public class MainActivity extends org.haxe.nme.GameActivity
{
 private Chartboost cb;
 
 @Override
  protected void onCreate(Bundle state)
 {
        super.onCreate(state);   
  
        // Configure Chartboost
  this.cb = Chartboost.sharedChartboost();
  String appId = "YOUR_APP_ID";
  String appSignature = "YOUR_APP_SIGNATURE";
  this.cb.onCreate(this, appId, appSignature, null);
 
  // Notify the beginning of a user session
  this.cb.startSession();

  // Show an interstitial
  this.cb.showInterstitial();

  }
 
 @Override
 protected void onStart() {
  super.onStart();

  this.cb.onStart(this);
 }

 @Override
 protected void onStop() {
  super.onStop();

  this.cb.onStop(this);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();

  this.cb.onDestroy(this);
 }

 @Override
 public void onBackPressed() {

  // If an interstitial is on screen, close it. Otherwise continue as normal.
  if (this.cb.onBackPressed())
   return;
  else
   super.onBackPressed();
 }
}


Remember to change the APP_ID and the APP_SIGNATURE for the correct information you obtained when creating your charboost account.

Okay so now we have our own MainActivity, but the compiler doesn't know that it has to use this one instead of the one that gets created by default (the template one), so to fix this we need to go to the project.xml once again and tell it to override the template with our own one.

Open project.xml and add the following:

<template path="java/MainActivity.java" rename="src/com/example/test/MainActivity.java" />

So what we doing here is telling the project that it is going to be looking for a file inside the folder "java" and going to replace the file src/com/example/test/MainActivity.java with it (this is the path relative to the android folder in the export, you can always check the folder name by building the android template or by checking your package name in the project.xml description at the top)

If build that and run you will see charboost working in your emulator or device.

I hope this helped you, if you have question don't hesitate in emailing or replying to this post. Best of luck in your development!

Sunday, January 20, 2013

Behavior Tree

I have been experimenting with behavior trees for a bit now, always finding I am over complicating things or that I did not prepare to solve all my needs with them, but the potential exists.

Right now I am working on a flash game along side an artist (I am so glad I don't have to draw) and I implemented an straight forward almost component like behavior system, such as "I give you the draw behavior, therefore you draw".

This was great to start, I didn't put too much thought into it and I ended creating some pretty cool behaviors, like interpolations (much like the tween class in Unity, but not as huge, of course), recycling routines, click events, functions proxy (Delegate like things, but in As3), collision responses, sequences, etc.

The problem was there was no stop at some behavior, once the entity got the behavior there was no way to stop the behavior from happening, since there was no real condition evaluation unless I went out of my way and filled the behavior with possibilities within its routine (which is dirty).

So I created 2 supporting templates that would work together to make my behaviors only fire when the conditions apply.

First, I created a "BaseCondition":


public class BaseCondition implements IBehavior
 {
  static var Head:BaseCondition;
  var Next:BaseCondition;
  var Self:BaseCondition;


The first part explains that this class is the type of IBeahvior (To comply with my Entity IBehavior collection, and to not disturb what was already in place and working properly).

The Head, Next and Self are the elements used to keep this class pooled, if you would like to know more about it please check my previous post here

The IBehavior interface contains 2 functions, Update():void and Recycle():void, pretty simple.

var Condition:ICondition;
  
  public var TrueConditions:Vector.<BaseCondition>
  public var FalseConditions:Vector.<BaseCondition>
  
  public var TrueActions:Vector.<IBehavior>
  public var FalseActions:Vector.<IBehavior>
  
  public function BaseCondition()
  {
   Self = this;
   TrueConditions = new Vector.<BaseCondition>();
   FalseConditions = new Vector.<BaseCondition>();
   TrueActions = new Vector.<IBehavior>();
   FalseActions = new Vector.<IBehavior>();
  }


Then we have a field for the condition, this condition is what makes the base condition unique, depending on this ICondition we will be able to tell what we are looking for, such as "Is this element inside the view frustum?".

Then we have 4 collections, one for the true branch (in case the condition is true, follow up with these conditions), another for the false conditions and 2 more of the true and false actions, meaning that depending on the residing condition in this base condition we will execute either the actions in the true collection or in the false collection, this proves to be very useful as you start evolving your behaviors.

Coming next we have the factory patterns I use, they are essentially the same with one another except for a small difference, this is done for convenience when creating behaviors (to avoid a mess of having to create things, link them and then reuse them).


public static function Create(Condition:ICondition):BaseCondition
  {
   var Vessel:BaseCondition;
   if (Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new BaseCondition();
   }
   
   Vessel.Condition = Condition;
   
   return Vessel;
  }
  
  public static function CreateRoot(Owner:Entity, Condition:ICondition):BaseCondition
  {
   var Vessel:BaseCondition;
   if (Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new BaseCondition();
   }
   
   Vessel.Condition = Condition;
   Owner.BehaviorList.push(Vessel);
   
   return Vessel;
  }
  
  public static function CreateTrueBranch(PreviousBranch:BaseCondition, Condition:ICondition)
  {
   var Vessel:BaseCondition;
   if (Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new BaseCondition();
   }
   
   Vessel.Condition = Condition;
   PreviousBranch.TrueConditions.push(Vessel);
   
   return Vessel;
  }
  
  public static function CreateFalseBranch(PreviousBranch:BaseCondition, Condition:ICondition)
  {
   var Vessel:BaseCondition;
   if (Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new BaseCondition();
   }
   
   Vessel.Condition = Condition;
   PreviousBranch.FalseConditions.push(Vessel);
   
   return Vessel;
  }


There's nothing really special to tell, if the factory pattern is not really clear to you please read my last post, there I explain my pool system and the factory pattern used in it.

public function Update():void
  {
   if (Condition.CheckCondition())
   {
    var count:int = TrueActions.length;
    for (var i:int = 0; i < count; i++)
    {
     TrueActions[i].Update();
    }
    
    count = TrueConditions.length;
    for (var i:int = 0; i < count; i++)
    {
     TrueConditions[i].Update();
    }
   }
   else
   {
    var count:int = FalseActions.length;
    for (var i:int = 0; i < count; i++)
    {
     FalseActions[i].Update();
    }
    
    count = FalseConditions.length;
    for (var i:int = 0; i < count; i++)
    {
     FalseConditions[i].Update();
    }
   }
  }

And here we have the heart of this behavior tree, where we check the condition and depending on the outcome we will either do the true reaction or false reaction, and follow the proper path in the behavior.
public function Recycle():void
  {
   Next = Head;
   Head = Self;
   
   var count:int = TrueActions.length;
   for (var i:int = 0; i < count; i++)
   {
    TrueActions[i].Recycle();
   }
   
   count = TrueConditions.length;
   for (var i:int = 0; i < count; i++)
   {
    TrueConditions[i].Recycle();
   }
   
   count = FalseActions.length;
   for (var i:int = 0; i < count; i++)
   {
    FalseActions[i].Recycle();
   }
   
   count = FalseConditions.length;
   for (var i:int = 0; i < count; i++)
   {
    FalseConditions[i].Recycle();
   }
   
   TrueActions.length = 0;
   FalseActions.length = 0;
   TrueConditions.length = 0;
   FalseConditions.length = 0;
  }
 
 }
Finally we have our recycle method, pretty essential to my system, we have to make sure to recycle absolutely every single behavior and condition, for reuse. And this concludes the BaseCondition, it is not complicated but we haven't really seen it in action, in order to make this work we require a "ICondition" as well as another "IBehavior" to append to one of the action branches, let's start with the condition:
public class Con_CollidedWith implements ICondition
 {
  static var Head:Con_CollidedWith;
  var Next:Con_CollidedWith;
  var Self:Con_CollidedWith;
  
  var Target:PhysicsComponent; //Contains all the physics info.

  
  public function Con_CollidedWith()
  {
   Self = this;
  }
  
  public static function Create(Target:PhysicsComponent):Con_CollidedWith
  {
   var Vessel:Con_CollidedWith;
   if(Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new Con_CollidedWith();
   }
   
   Vessel.Target = Target;

   return Vessel;
  }

This is pretty much the same pattern I follow for almost everything that requires to be pooled, in there you can see an object of type of "PhysicsComponent", in there I store variables that represent the entity in the physical world, such as position, body type (Rectangle, poly, circle, etc), a collision list, etc.
  public function CheckCondition():Boolean
  {
   return Target.CollisionList.length > 0;
  }
  
  
  public function Recycle():void
  {
   Next = Head;
   Head = Self;
  }
  
 }
Finally we have the CheckCondition (which is part of the ICondition interface) where I test the condition at hand, in this case if we have something in our collision collection (meaning we have collided with something in the collision phase) it will return true, otherwise false. That concludes an example of a condition, you can create all sort of conditions, you can test if an enemy has certain amount of HP, or if a button has been clicked, etc. Now we move to the last piece of the puzzle, the Action, for this example I will use a function proxy action:
public class Act_ExecuteFunction implements IBehavior
 {
  static var Head:Act_ExecuteFunction;
  var Next:Act_ExecuteFunction;
  var Self:Act_ExecuteFunction;
  
  var Execute:Function;
  
  public function Act_ExecuteFunction()
  {
   Self = this;
  }
  
  public static function Create(Execute:Function):Act_ExecuteFunction
  {
   var Vessel:Act_ExecuteFunction;
   if(Head != null)
   {
    Vessel = Head;
    Head = Head.Next;
   }
   else
   {
    Vessel = new Act_ExecuteFunction();
   }
   
   Vessel.Execute = Execute;
   
   return Vessel;
  }
  
  public function Update():void
  {
   Execute.call();
  }
  
  
  public function Recycle():void
  {
   Execute = null;
   Next = Head;
   Head = Self;
  }
  
 }
As you can see in our Update function (this will only get called if the condition fell in the action branch where this action resided in) we call the function we appended to this action, much like a delegate. But we still don't know how to put all of this together, so allow me to make an example, in my current game there is "Honey" in the air and you require to collide with it in order to acquire it, here is how I make a honey:
public static function CreateHoneyItem(X:Number, Y:Number):void
  {
   var Honey:Entity = Entity.Create(World.InGameGroup);
   var Graphics:GraphicsComponent = GraphicsComponent.Create(Honey, AnimationLibrary.HONEY_GRAPHICS);
   var Physics:PhysicsComponent = PhysicsComponent.Create(Honey, X, Y, PhysicsComponent.ITEM);
   Physics.TurnIntoCircle(16);
   
   var Drawer:B_Draw = B_Draw.CreateOwnerless(1, Graphics, Physics); //gets recycled upon collision by the honey collision response
   
   var Condition_Collision:BaseCondition = BaseCondition.CreateRoot(Honey,Con_CollidedWith.Create(Physics));
   Condition_Collision.TrueActions.push(Act_ExecuteFunction.Create(HoneyCollisionResponse));

}

public static function HoneyCollisionResponse():void
{
    //Do your response here
}


So in order to make a honey I call the factory method for the honey, this will create a honey, and give it's behavior. The behavior says that it will Draw (B_Draw), Also says that if the honey collides with something then execute the function proxy (HoneyCollisionResponse).

There's more behind the scene, such as the collision system, the render system, etc, but it is not hard to get the idea on how the behavior tree works. Using this you can come up with all sort of complex behaviors, but the main issue with this is that they are inflexible upon creation, there won't be learning of AI, it will just run the routine over and over, but that doesn't have to be that way, there are methods to make this work the way you want to, implementing weight based decisions instead of just conditionals could be a way, there's a lot of things that can be implementing using this Behavior Tree pattern, but that would be another post for another time.

Wednesday, January 16, 2013

Final pool version

Since I went from C# to AS3 in order to complete web games I realized that the lack of generics in AS3 was going to be a huge problem for my pooling system, this forced me to think things once again and the result was something more elegant, secure and completely contained within the pooled class.

Making use of the factory design pattern once again I was able to create a pool system within the same class (which is now a template in my IDE), here is how it goes:

public class PooledItem
{
   private static var PoolHead:PooledItem;
   private var Next:PooledItem;
   private var Self:PooledItem;

   public function PooledItem()
   {
      Self = this;
   }

   public static function Create():PooledItem
   {
      var Vessel:PooledItem;
      if(PooledHead != null)
      {
         Vessel = PoolHead;
         PoolHead = PoolHead.Next;
      }
      else
      {
         Vessel = new PooledItem();
      }
      
      return Vessel;
   }
}


The PoolHead is private and static, making it unique locally and impossible to access from outside this class, then we have the Next and the Self which are unique to each instance of the PooledItem, and finally we have a factory pattern which creates a new instance of a PooledItem if the head is null, but if the head is not null it will return it and set the new head as the next element in the queue.

One thing to have in mind is that AS3 does not allow to have private constructors, thus making it possible to create an instance of the PooledItem without the factory method, if this happens and you don't properly get rid of it by calling its recycle method then you will have an extra element (outside the pool) doing nothing, but even if you create it without the "create" function you can still put it back in the pool by calling recycle, so no real harm done if handled properly, still if this was not AS3 I would make the constructor private.

Going to the recycle function now, the recycle function is where I do all my clean up code (if required depending on the elements of the class) as well as to put elements back into the pool:

public function Recycle():void
{
   //Do clean up code, maybe recycle other pooled items that were created within this
   //class or release references of an element to let GC deal with it, etc.

   Next = PoolHead; //we set the next element as the current head.
   PoolHead = Self; //and finally we set the this element as the new head.
}


And that's it, it is amazing how essential and memory friendly this can be, allocating memory and deallocating memory can be very tasking in the system, specially if you are planning on putting your games in mobile devices, have in mind also that the more memory you use the more battery it might consume, so in order to have some balance make sure to maintain your pools, this can be achieve by an internal reference counter and releasing some of them if the number gets to a certain point, however you want to handle that I will leave to you.


Friday, October 19, 2012

Intrusive linked node

Dealing with large number of objects can be tasking, specially in games, traditionally we have our objects living in some sort of collection, and then we traverse this collection to perform a task (like Update() or Draw()).

Collections work amazingly, traditionally I seen that the generic List is used the most, I use them often, but I stopped using them to managed my objects, simply because of how slow and tasking the "Remove()" function was, let me explain this:

when you have a collection of 10 elements in a List, and you decide to remove element 4, you would have to shift the following 6 elements down a slot to keep the list continuous, since the list is just a glorified "array", this can be very expensive, imagine if you were to remove element 1 in a list that contains 10,000 elements, not fun.

Linked list in the other hand do a much nicer job for removing elements, since they know what's next and what was previously, I would suggest to use linked list when you don't need to access an specific element in a collection, linked list do not work nicely when trying to "find" things inside them, because they are not indexed, you would have to check from start to end for an element using some comparison check on every single element, not fun.

Currently in my game, I use my own "collections" which are very specific, I have an "Actor Node" which takes care of the actors, like this:

public class ActorNode
    {
        public IActor Subject;
        public ActorNode SelfReference;
        public ActorNode NextActor;
        public ActorNode PreviousActor;

        public static ActorNode Head;

        public ActorNode(IActor subject)
        {
            SelfReference = this;
            Subject = subject;
        }

        public void Activate()
        {
            if (Head != null)
            {
                Head.PreviousActor = SelfReference;
                NextActor = Head;
            }
            Head = SelfReference;
        }

        public void Deactivate()
        {
            if (PreviousActor == null) //check for head
            {
                if (NextActor != null)
                {
                    Head = NextActor;
                    NextActor.PreviousActor = null;
                }
                else
                {
                    Head = null;
                }
            }
            else
            {
                if (NextActor != null) //check for tail
                {
                    NextActor.PreviousActor = PreviousActor;
                    PreviousActor.NextActor = NextActor;

                    NextActor = null;
                    PreviousActor = null;
                }
                else
                {
                    PreviousActor.NextActor = null;
                }
            }

            PreviousActor = null;
            NextActor = null;
        }
    }


This Node is a "component" of my actors, meaning that they live inside my actor class, using my factory design pattern (check last post for reference) I easily activate them, and using my Recycle method (also last post) I deactivate them before returning them to the pool, like this:

public class AnActor: PooleanNode<AnActor>, IActor, Irecycle
{
    LinkedPoolean<AnActor> Pool = new LinkedPoolean<AnActor>();
    
    ActorNode ActorLink;    

    public AnActor()
    {
        ActorLink = new ActorNode(this);
    }

    public static void Create()
    {   
        AnActor Vessel;
        Pool.Get(out Vessel);
        Vessel.ActorLink.Activate(); //Activates the node so it is in the collection
    }

    public void Recycle()
    {
        ActorLink.Deactivate(); //deactivates the node so it is taken out.
        Pool.ReturnPoolable(this);
    }
}


Now, let's assume that the "IActor" interface contains a method called "Update()", we can use this collection to update all the currently activated actors like this:

public static void UpdateAll() //function that updates all the actors
{
     ActorNode Current = ActorNode.Head; //gets the current head
     if(Current == null) //make sure there are elements in the collection
     {
         return; //if there's nothing, then get out.
     }
     IActor CurrentActor; //container for the current subject that needs to update

     do
     {
          CurrentActor = Current.Subject; //get the first subject
          
          CurrentActor.Update(); //Update it and then

          Current = Current.NextActor; //check for the next node

     } while (Current != null); //and if that node is not null, then repeat.
}

That function will make sure that all the activated nodes will update.

Thanks for reading.







My Factory Design Pattern

I will talk a bit about how I create my "Game objects".

The first thing you need to know is that I do not use the keyword "New" to instantiate a new object, this is because I need to have control over my game objects (coming from the pools), Let's create a quick example, I am going to assume that you know about my pool system, but if you don't please take a look at the previous post.

We will start with the body of the class.

public class Slime: PooleanNode<Slime> 
{
    static LinkedPoolean<Slime> Pool = new LinkedPoolean<Slime>();

    public Slime()
    {
    }
}

Here we have declared a "Slime class" that can be pooled with my pool class, as you can see the constructor is public so we can instantiate them with the activator class, also there's a static pool of slimes living inside this class, this will mean that in every single slime object you will have access to the same pool, this is important cause all the slimes need to come from the pool, now moving into the "creational" method.

public static Slime Create() //this function must live inside the slime class.
{
    Slime Vessel;
    Pool.Get(out Vessel); //if it doesn't live inside the class, the pool wouldn't be
    return Vessel;        //visible, you would have to make it public and access it
}                         //like "Slime.Pool", I don't recommend that. 

And done, we have create an static method that will take slimes out of the pool and return them, simple as that! now for some logic on why I do this, by making a new slime this way I make sure they come from the pool and that they are not generated outside of the pool, this is handy when we want to manage them and when we want to avoid tasking the garbage collector, since we are not allocating new memory.

Now let's expand on it, to make it useful, you can declare multiple creation methods to obtain different results, let's say that the Slime has some fields like position or maybe current hit points, etc, we can modify these elements like this:

public class Slime: PooleanNode<Slime> 
{
    static LinkedPoolean<Slime> Pool = new LinkedPoolean<Slime>();

    Vector2 Position;
    int HP;

    public Slime()
    {
        Position = Vector2.Zero;
        HP = 1;
    }

    public static Slime Create(Vector2 Position, int HP) 
    {
        Slime Vessel;
        Pool.Get(out Vessel); 
        Vessel.Position = Position;
        Vessel.HP = HP;
        return Vessel;       
    } 
}

By default the slime starts at position 0,0 and with 1 HP, but we can create any slime anywhere we want as well as giving it any amount of HP we want, we can create more methods to define things ever further.

Lastly I define a recycle method that I use when I need to get rid of the object and sent it back to the pool, like this:

public void Recycle()
{
    Pool.ReturnPoolable(this);
}

That makes sure that the object is sent back into the pool to be reused by the factory method, this is an overly simplified version of what I use in my current game, if you would like to check the game out, here:

Game

Thanks for reading!

Monday, October 15, 2012

Taking casting out of the picture

Once again! I have done another revision to the way I am doing pools, it is almost like an obsession, in any case, it has proven to be fantastic, onto the code:

public class LinkedPoolean<T> where T : PooleanNode<T>, new()
    {
        public T Head;

        public LinkedPoolean()
        {
            Head = Activator.CreateInstance<T>();
        }

        public void Get(out T Vessel)
        {
            if (Head != null)
            {
                Vessel = Head;
                Head = Head.Next;
            }
            else
            {
                Vessel = Activator.CreateInstance<T>();
            }
         
        }

        public void ReturnPoolable(T Return)
        {
            Return.Next = Head;
            Head = Return;
        }
    }

The Key change here is the way we access the "Activator", you see, there's a function to create an instance that takes a Generic parameter T, and there's another version of the function that takes an argument "Type" and returns an "Object", the object returned by the second function is sadly not the right type, so in order to use it I used to cast it, this would create a hit on the performance. The function that takes a parameter of type T returns an object of type T, making casting unnecessary.

This improvement was only possible though if the PooleanNode knew which "kind of poolean node" it was, new Poolean node class:

public class PooleanNode<T> where T: PooleanNode<T>
    {
        public T Next;
    }


This in turn makes the poolean node type safe, before hand it was potentially possible to subscribe a poolean node into a pool of another type, it was kind of weird at the beginning to see a class expecting itself to be the template, but it is kind of cool the way it works.

Thanks for reading~

Friday, September 21, 2012

The Pooling Redo

I can't believe that I first attempted to make a proper pool back in April, that's only 6 months ago! I learned so much and looking back I feel dumb, but that's the main purpose of this blog! I like to check out my learning curve.

Anyways, to the pools, not too long ago I read about intrusive lists and how they were awesome for managing your game objects, before that my take on recursions were weird as well, I abandon the method and just made a while loop scanning of the nodes to traverse the tree, so no more recursion because the Xbox hates you using memory!

My last revision on the pool was cool, managed and it served it's purpose pretty well, but then I read about recursive lists and I thought that I could use something like that in the pool, a linked list pretty much but instead of using the built in linked list I wanted to make the nodes of the pool the actual objects and not a sub object attached to a node.

public class LinkedPoolean<t> where T : PooleanNode, new()
    {
       Type TypeOfT;

        T Head;

        public LinkedPoolean()
        {
            TypeOfT = typeof(T);
            Head = (T)Activator.CreateInstance(TypeOfT);
        }

        public void Get(out T Vessel)
        {
            if (Head != null)
            {
                Vessel = Head;
                Head = (T)Head.Next;
            }
            else
            {
                Vessel = (T)Activator.CreateInstance(TypeOfT);
            }
        }

        public void ReturnPoolable(T Return)
        {
            Return.Next = Head;
            Head = Return;
        }
    }

The thing to note here is that it is so ridiculous simple in comparison to my first attempt, and I was thinking that the last attempt was short! now, in this case I made the "PooleanNode" a base class cause it bugs me to know that I would have to use a "Property" to fetch a single field (which is all that class has in it as for now), but if that doesn't bother you then you may as well make the class an interface.

Poolean class:

public class PooleanNode
    {
        public PooleanNode Next;
    }

Well more weird things will result out of this, I am going to be changing quite a bit of things in my engine, because this method it is not just about 10 times faster and more memory friendly but it is also a good design.