lunes, 27 de julio de 2015

Gamepolis 2015: An Overview

Hi all!

As promised, here it is my experience during the 2015 edition of Gamepolis. (To check my course during the previous editions, click here and here). 

The event came this year with some interesting novelties:

1) More national and international projection: not only did the number of attendees increase, but also the variety of their origin, which encompassed many Spanish regions. Long lines, especially during the morning, showed the increasing interest in this event, as shown in Figure 1. Also, the invited speaker Petro Tyschtschenko provided the international flavour with his nostalgic speech about the Amiga in its 30th anniversary. 


Figure 1. Tons of people lined up to access the premises, and more than half of the line 
cannot be seen from this perspective!

2) GameInvest Forum: co-located with Gamepolis, GameInvest provided a forum where developers could show their games to investors. As part of the agenda, there were some interesting talks on game investment and financial aids. Particularly interesting was a roundtable discussion about the aspects that investors often examine when making investment decisions. The main conclusion was that the game developer experience is usually graded with the highest priority. Thus, when an investor is faced with whether to invest in an unexperienced game developer with a brilliant idea, or in an experienced developer with a not so good idea, the odds will mostly be in favour of the latter (in many cases, unfortunately). 


Figure 2. GameInvest Forum

3) Game Jam: MalagaJam is a young association targeted at game developers, which is based in Malaga physically and in Internet digitally. Two weeks ago, they organized their second Game Jam, the awards of which were announced during a Gamepolis session on Sunday afternoon. The list of games and their download links are here. One of the most successful games, Panspermia, achieved The Most Outstanding Visuals and to The Best Audio and Music awards, the latter of which was thanks to my friend Oliver (Figure 4). 


Figure 3. The auditorium was completely crowded during the jam awards ceremony


Figure 4. Panspermia team receiving The Best Audio and Music award.

Contrary to the previous editions, in which I tried to turn up at almost all the conferences, this year I could barely attend any one. The reason is that I participated in GameInvest with a project called GalaxyNumbers (Figures 5 and 6), for which I'm the programmer. The game combines match-3 mechanics (Tetris) with a Candy Crush aesthetics and presents an interesting mathematical twist. According to the people that could play the game during the event, it is fun and addictive, and these people would repeatedly ask us whether the game was already available for download. Unfortunately, we always had to answer "not yet". Precisely the idea of participating in GameInvest was to request investment to polish the last details and to integrate the last features, and also to cover marketing efforts. For now, we are happy to have received very positive feedback from a broad range of users.


Figure 5. The stand of Galaxy Numbers


Figure 6. The presentation of Galaxy Numbers

As a wrap-up, this edition of Gamepolis has provided a bigger focus on developers and has widened its impact by bringing an international, well-known speaker, which were two aspects that remained uncovered in the two previous editions and which I criticized in those posts.


Figure 7. A 3D printer making cool stuff. Actually, the game jam awards were printed!

Something to improve? Well, there are some sources that have complained about the lack of respect of a reduced number of attendees during some conferences, who would not stop their chattering. I would therefore suggest enforcing a bigger control during the presentations, as well as continuing the effort towards a wider internationalization.


Figure 8. A minute of silence was observed in memory of Mr. Iwata, followed by a huge ovation.  RIP.

miércoles, 22 de julio de 2015

Gamepolis 2015 is coming!

Hi all!

Gamepolis 2015, the biggest and most important videogames event in Malaga, is coming back this weekend. 


As I did in the 2013 and 2014 edition, I will cover my experiences along the days of the event. This year, Gamepolis brings along a nice novelty: GameInvest, a forum where investors will evaluate different projects and will finance the best ones. And guess what! A project in which I'm working will be there! So wish me luck! 

In the next post, I'll tell you more about this project and about my course during the event. 

See you,
FM 

miércoles, 3 de junio de 2015

Correct Compositional Design in Cocos2d-x

Hi all!

Today I want to share with you an important caveat about composition in the context of Cocos2d-x. Composition is an object-oriented technique where a class contains (is composed of) another class to which it delegates functionality related to the latter. 

This technique is frequently suggested as an alternative to inheritance in complex hierarchies in order to avoid tangled structures, specially in those languages that do not support multiple inheritance (i.e. a class cannot have more than one parent class), such as Java. More information about the composition-inheritance binomial can be read here. 

In the context of Cocos2d-x, composition could be realized through a class that contains a Sprite object as part of its private members, for example:

 class Ball  
 {  
 public:  
   explicit Ball( const BallType &bt )  
   {  
      switch(bt)  
      {  
         case BallType::Hard:  
            ballSprite = Sprite::create("Balls/Hard.png");  
            break;  
         //more cases...  
      }  
   }  
   ~Ball()
   {
       //Clean-up by removing heap-allocated data
   }
   inline cocos2d::Sprite *getBallSprite() { return ballSprite; } 
 
 private:   
    cocos2d::Sprite *ballSprite;  
    //more data
 };  

In this case, the Ball constructor simply takes a scoped enum value and creates a sprite object depending on the type. We also provide a getter function to retrieve the pointer to the sprite object. The destructor, as always, should clean up the memory allocated by the object.

At this point, you may be tempted to place a delete ballSprite statement, but this would yield a compiler error, because Cocos2d-x uses its own reference counter for managing the memory of its objects. Therefore, when a Cocos2d-x object (such as a Sprite) is no longer referenced by any other object, the former is automatically deleted.

Now, a client class (e.g. a cocos2d::Layer ) could use the Ball class as follows:

 //A method in our layer class  
{  
   //start some loop
  {
    BallType bt = getRandomType();
    //balls is a member variable of type std::vector<std::unique_ptr<Ball>>
    std::unique_ptr newBall = std::make_unique<Ball>(bt); 
    layer -> addChild( newBall -> getSpriteBall() ); 
    balls.pushBack( std::move(newBall) );  
 
    //... process balls    
  }
  //All balls destroyed; all  
  Director::getInstance() -> replaceScene( AnotherScene::create() );
} //end of method


In a loop, this method creates balls of random types, adds the balls sprites to the layer to actually show the sprites on screen, and processes them (maybe it detects touches and so on). Upon termination of the loop, there is a change of Cocos2d-x scene, which means that all the children of the current layer (including the sprites of the balls) are safely deleted. Also, as the vector of balls goes out of scope, the destructor of the std::vector class is called, which in turns calls the destructor of the std::unique_ptr objects, which in turn calls the destructor of each Ball object. Everything perfect so far.

However, consider the following scenario. In this scenario, we want to show only on screen some balls of a specific type, whereas other types of balls should be stored and shown at a later time, for example upon termination of the loop. The code to perform this could be:

 //Method in our layer class  
{  
  //start a loop
  {
    BallType bt = getRandomType();
    std::unique_ptr newBall = std::make_unique<Ball>(bt); 

    if ( bt == BallType::Hard )
    {
      layer -> addChild( newBall -> getSpriteBall() );  
      balls.pushBack( std::move(newBall) );  
    } 
    else 
    {
      ballsToShowLater.pushBack( std::move(newBall) );
    }
    //... process balls      
  }
  //end of the loop
  //show hidden balls
  for (const auto& b : ballsToShowLater)
  { 
      layer -> addChild( b -> getSpriteBall() );  
  }   
  //..some more stuff with the new balls shown
  
  Director::getInstance() -> replaceScene( AnotherScene::create() );

} //end of the method

This code, which seems ok at a first glance, has an important flaw. The problem arises because of the automatic reference counting mechanism of Cocos2d-x, which we are not using properly. When we create a Sprite object in our Ball, the reference counter is still 0, because there is no object pointing at it. This means that if right after creating the Ball object we don't add the associated Sprite object to the layer hierarchy (via addChild() ), the next iteration of the framework will detect that the reference counter is 0 and will remove the Sprite object. However, if we add the Sprite to the layer hierarchy, we increase the reference counter by 1, which prevents the framework from deleting the Sprite.

In the first example, there was no problem because right after the creation of a Ball object, unconditionally, we added the Sprite to the layer hierarchy. However, in the following example, we are creating Ball objects and we are deferring the inclusion of their sprites in the hierarchy of the layer. Therefore, most likely, when we try to retrieve the Sprite object in the for loop, we simply retrieve garbage, because the pointer is dangling.

How to fix this? The solution is easy and fast. We simply need that Ball object reclaims (shared) ownership of its Sprite. Basically, we need that a Ball object is capable of expressing: "hey, I need the Sprite object, so don't remove it even if nobody else is using it". This is where the Cocos2d-x functions retain() and release() come into play, as shown next:

 class Ball  
 {  
 public:  
   explicit Ball( const BallType &bt )  
   {  
      switch(bt)  
      {  
         case BallType::Hard:  
            ballSprite = Sprite::create("Balls/Hard.png");  
            break;  
         //more cases...  
      }  
      ballSprite -> retain(); //This is my sprite, so don't mess up with it!
   }  
   ~Ball()
   {
       //Clean-up by removing heap-allocated data
       ballSprite -> release(); //I don't need this sprite object anymore
   }
   inline cocos2d::Sprite *getBallSprite() { return ballSprite; } 
 
 private:   
    cocos2d::Sprite *ballSprite;  
    //more data
 };  

So this is the main consideration when using composition with Cocos2d-x objects! Easy, right?

Hope you enjoyed it!
FM

Tweet: Don't miss this interesting read on #programming and #gamedev. Correct Compositional Design with #cocos2d-x (http://ctt.ec/hIFi9+)