Wednesday 27 October 2010

Quick and dirty scripting with Python

Quick and dirty scripting with Python


I came home from work today and, instead of taking a nap (something that would have come in really handy) or playing Mass Effect 2, I started coding a couple of scripts to help me organising some files that I've got in several Micro SD cards.

Keep in mind that I've omitted the imports, "const-like" vars declarations and the if __name__=="__main__" statement for the sake of brevity.

The first one just lists the files and subdirectories from a given path, and then it saves it to a text file. Python also provides the function os.walk (or the deprecated os.path.walk), but I got it into my head that I wanted to indent the files according to the depth from the root path and the easiest way to accomplish this was using os.listdir, which worked as a charm =)

def extract_dir_files(arg, dirname):

    dir_str= "%s/%s/\n" % (" "*arg[0],os.path.split(dirname)[1])

    arg[1].write(dir_str)

#os.listdir just returns a list containing all files and directories #contained within the path 'dirname'
    for item in os.listdir(dirname):
        new_path = os.path.join(dirname,item)
        args = [arg[0]+1,arg[1]]
        if os.path.isdir(new_path):

#The child directories will make recursive calls
#until the root_path directory has been completely #parsed
            extract_dir_files(args,new_path)
        else:
            name,ext = os.path.splitext(item)
            #do not write out the files having one of the
#extensions specified in IGNORE_EXT
            if ext not in IGNORE_EXT:
                file_str = "%s-%s\n" % (" "*(arg[0]+1),item)
                arg[1].write(file_str)
                print(file_str)    


def main():
    root_path = os.path.join(DRIVE_LETTER,ROOT_PATH)
    with open(OUTPUT_FILE, 'a') as f:
        f.write("*"*PAD_NUM+"\n")
#args[0] will hold the value of the current depth in the dir. #hierarchy; args[1], the file object
        args = [0,f]
        extract_dir_files(args,root_path)
        f.write("*"*PAD_NUM+"\n")




The second one gets the HTML contents of a given URL which are parsed to a DOM-like object. After that, all that it's left is to extract the data of interest and do whatever you want. In my case, I decided to write them to a *.CSV file for future use. I used the library available at http://www.boddie.org.uk/python/libxml2dom.html

It was pretty easy to use, and it allowed for DOM-like processing of HTML pages, which aren't generally well-formed. This causes complaints and exceptions when using better known Python DOM libraries.

def main():
#URL returns a list of links, of which I'll only be
#interested in their text values.
#FROM and TO are the
values I want to pass to the query
#as GET parameters.

    with contextlib.closing(urllib.urlopen(URL%(FROM,TO))) as url:
        encoding = url.headers['Content-type'].split('charset=')[1]
        contents = url.read().decode(encoding).encode('utf-8')
    doc = libxml2dom.parseString(contents,html=1)
    links = doc.getElementsByTagName("a")
    results = []
    for l in links:
        release = l.childNodes[0].nodeValue
        #...then do whatever you want with it :P



Tuesday 12 October 2010

Once upon a night

First, I believe that apologies are in order for the delay in updating. I finally got a job in a Barcelona-based studio, and I've been happily working there as a junior programmer since August :)

The rest of my daytime (and, more often than not, night time as well T_T) up until last Tuesday has been devoted to our master's final project delivery, which was presented that day on Caixaforum. 

First, a Konami exec came and gave a talk about the upcoming release of Castlevania: Lords of Shadow, developed by Mercury Steam, a Madrid-based studio, and then the 5 teams showcased their projects.

  • The creature. A full 2.5d platformer game, featuring 20 levels. Your mission will be to help a creature being complete again by getting back some parts of its body, scattered around several areas.
  • Wyverns Assault. A funny, retro-style beat 'em up game where you're a huge dragon fighting hordes of soldiers and destructing everything :-D
  • Undertown. A graphically amazing action game a la God of War, made by just an artist and a programmer. The main character must fight the Disgusting (Asquerosos, in Spanish: that's their real name) and other monsters so he can have his girlfriend back.
  • Ghosty Town. This game has a truly original concept where you're put in the place of a ghost that must scare the hell out of all the villagers of a small town in order to conquer it.

You should check them all (although some of them still lack a proper downloadable release, ours being one of them -_-U), there's a lot of work put into each and everyone of them, and the results have been really good imho.

And yes...I mentioned there were 5 teams, but only 4 projects are listed above.

So now, enter Once upon a night!



The game puts you in the place of Any, a girl (it wasn't always like that, though ^_^U) that's been trapped in her dreams by a malfunctioning magical clock. To escape and wake up again, she must find a set of gears, springs and other pieces to make it work properly again. These gears are supposed to be similar gameplay-wise to the stars on Mario 64, to name a very obvious example, as it was one of the most important references we took. To retrieve them, she'll have to solve the puzzles scattered throughout the two parallel worlds of dreams and nightmares that shape a level.

I performed tasks as a designer (well, the whole team was, actually, which is something that I now deem a terrible mistake) and, mainly, as a programmer.

Since our work tends to slip unnoticed, I'll compensate by listing the main features I wrote as a programmer. I might talk a bit more about some specific features in the future if I'm in the mood or anyone is interested. I'm sure that lots of stupid errors will be found, but that will allow everybody, specially myself, to learn from those mistakes.

- Base application engine skeleton. It consisted of a main Application class that would contain the remaining subsystems, encapsulated as independent (or that was the goal) modules to handle audio, graphics, AI, etc. After initialization, it just starts the game loop and handles input and state management, the game's subsystems being the ones in charge for updating the world and their attributes.
       
- A stack-based FSM for the game state manager. I had previously used a simpler approach for my previous games, based on IDs and an abstract factory to provide concrete implementations of the states. The stack approach has worked quite well despite an embarrassing error I detected not much time ago concerning state changes -_-U

- Event manager. A template-based approach that allowed any subsystem or the game world itself to subscribe/unsubscribe and react to specific events triggered by the animation engine, the physics subsystem, etc. Events were posted to a priority queue and dispatched at a fixed point of the game update call.

- Game entities management...partially (it was more of a joint task). This is kind of a long story: during preproduction and the earlier parts of the production stage, I had been reading several books and articles on the internet about component-based architectures and data driven design, and thought it could be nice, as it would allow to avoid deeply nested class hierarchies, deadly diamonds, and such. More importantly, we would have a flexible architecture to make it possible to define new entities without changing much code, or modifying their attributes' values without recompiling the whole project.

However, I was unable to communicate the concepts and new philosophy to my fellow programmers, and besides there were conflicts with the level loading module, so we came up with an alternate, middle-of-the-road approach that, honestly, could have been much better.

I still won't desist, though, and sooner or later I'll come up with some tests to compare the implementation, usage and ease to understand that type of architecture as opposed to the classical inheritance-based ones.

- Scripting engine. We used LUA and luabind as an interface between that scripting language and C++ to implement the following features:
* FSM-based AI-controlled entities. I believe we could have made entities a lot more script dependent, allowing them to react to state changes (for instance, playing sounds, changing animations and such) inside LUA code instead of delegating to the main C++ code, but it was
decided to leave it at that.

* Triggers. We had some entities that could act as triggers when another entity (typically, Any, but it wasn't the only one) entered/exit/was at the volume defined by the trigger. Through LUA, we could define a pair of functions condition/action, so that the logic subsystem could check if a set of additional conditions had been fulfilled (besides the enter/exit/presence checks, of course) and, in that case, execute the action function. This provided triggers with some interesting flexibility.

* Cutscenes. The in-game cutscenes in our game were also coded in LUA, taking advantage of the coroutine feature LUA provides (this was a bit difficult to understand at first). We had made available a set of exported functions (move an entity, change an animation, show a message box, etc), and then all we had to do was define the script to launch the different actions sequentially.

- Audio engine. It was based on FMOD and a specialisation of Ogre3D's ResourceManager, that made it possible to define sound resources as scripts that could configure several properties: looping, 3D, intensity thresholds, etc.


- User interface: To tell the truth, the user interface is actually split into three different components:
- The actual GUI subsystem, used for good old buttons, combos, etc., widgets. For these ones I went with CEGUI, an open source GUI library that already came bundled with the Ogre release we used (1.6.5). The more familiar that I got with it, the more powerful I've been finding it, so we could have used it instead of overlays in some other places, but then it was too late ^^U

Skinning a GUI layout, however, has been hell (well, I managed to come with a new skin on two days under a lot of time pressure, but still, it was a nightmare)

- Ogre's overlays. Mainly used for the HUD, and for almost the whole development cycle, the pause and game over screens (they got replaced with the third approach in the end). Ogre provides a specification for overlay scripts, but I find it a bit messy when you want to do some more complex positioning.

- Ogre's Rectangle2D class. Even simpler approach, consisting on creating a quad and applying a material to it. The intro, game over and loading screens are examples of this.


- Several graphical features.
- Animation engine. We adapted some code of an animation blender found on Ogre3D's wiki, adding the possibility to incorporate partial blending using an array of weighted bones. Unfortunately, it wasn't used at it fullest, due to time constraints and bugs.

- Initial approach to incorporating soft shadows, that unfortunately didn't make the cut. They were working, but then, when the change world functionality you've seen on the video was incorporated, it stopped functioning. The world change being a key feature of the game, it took precedence and dynamic shadows were removed until a later stage in the game.

- Some special effects. Nothing fancy, though. Some of them were reused from existing open source code, and then incorporated to the game:
    - The intermittent tint effect shown every time Any gets hit. This one was pretty easy to implement by using a pixel shader that would apply a tint whose intensity would vary according to a sine-like function.
    - The flashlight halo effect, combining texture and node animation  with a projective decal. The particles were incorporated at a later stage by another fellow programmer.
    - A lens flare, but it triggered on very rigid constraints, so it had to be tweaked a bit.

- Gameplay programming. I implemented the behaviours for several entities in our game.
- Any.
- The tripollos in the world of dreams.
- The scared plants (those weird plants that hide when Any gets close).
- The diamond trees. They work like the multiple-coin boxes from the Mario platformers: you may hit them for a set amount of time and obtain diamonds.
- Egg nests: These ones could drop an item -or a tripollo- from a varying choice of weighted.
- The story book item.
- An initial version of the world change item.
- Signposts.


As you can see, there were quite a few things to do @_@. Despite all this,  to be completely honest, I'm not entirely satisfied with the end result, despite the efforts the whole team has put onto it. Maybe it's just that I'm too hard on myself, but I believe that some degree of ambition and self-criticism should be a must for anybody that aims at developing games professionally, and I think that our game still has a long way to go until it can reach the status of 'acceptable'. The experience, however, has been really valuable, either as an example or as a counterexample.

Last, I would like to recommend a book that I found particularly useful during all this time (it's not the only one at all, but it was the one I've enjoyed the most):

Game Engine Programming, by Jason Gregory. I discovered it while I was looking for some algorithms on game loop synchronization, or maybe for entity managers and event handling. This book is amazing: exhaustive (it covers such things as animation engine programming, physics or entity management) and at the time I found it quite easy to read.

Saturday 10 July 2010

Strategy pattern applied

  
Yesterday I started thinking about how to improve the behaviour of one of the enemies on our Master's final project game, Once Upon a Night. At some point, I found myself thinking how the enemy might have to choose among a variety of available attacks once the main character enters the attack range for more than one attack types (obviously, if there is only one kind of attack it may launch, there is no problem). The easiest way would be to stick with a common selection policy (for instance "pick the first one", or "pick randomly"), but it wouldn't be very flexible. Then, almost immediately, one of the GoF patterns sprung to my mind. Of course, I mean the Strategy Pattern. According to their book, the pattern's intent is to define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

To make the concept clearer, I'll show you a simple implementation that I sketched last night applied to the attack selection policy for enemies. It should be correct (save for missing includes, which I've omitted) aside from a few typos.

First, some macros and typedefs...

// Attack selection strategies using the same-name design pattern.

// Let's say we have an enemy currently chasing the player.
// At some point,their distance gets close enough for
// the enemy to launch one or several possible attacks.
// If more than one attack is available, which one would it select?

// This code shows how several selection choices may be
// available at once by using the well-known strategy pattern.

#define SAFEDELETE(x) if (x) {delete x; x=NULL;}
#define SAFEDELETEARRAY(x) if (x) {delete[] x; x=NULL;}

// Struct containing a hypothetic attack type data
struct TAttackData
{
std::string name;
int damage;
int attackRange;
int cooldown;
int energy;
};

// A collection of available attacks, indexed by their name
typedef std::map<std::string, TAttackData*> TAttackCollection;

// Functor-like struct used to fetch the vector of values of a map
struct getValue
{
template <typename T>
typename T::second_type operator()(T keyValuePair) const
{
return keyValuePair.second;
}
};

// Return the vector of attacks from an attacks map.
std::vector<TAttackData*> getValues(const TAttackCollection&

 availableAttacks)
{
//BEWARE! This is inefficient, it'll copy the vector to return it.
//Passing the vector as a parameter might be a better option

std::vector<TAttackData*> attacksVector;
std::transform(availableAttacks.begin(),availableAttacks.end(),
std::back_inserter(attacksVector), getValue());
return attacksVector;
}


And now, let's define our base strategy class, and a couple of concrete implementations.

// Base strategy class.
class AttackSelectionStrategy
{
public:
virtual TAttackData* selectAttack(const TAttackCollection&
availableAttacks)=0;
};

// Concrete strategy: an enemy using this strategy will always choose
// the highest-damage
class HighestDamageStrategy: public AttackSelectionStrategy
{
public:
bool compareHighestDamage(TAttackData* one, TAttackData* other)
{
return one->cooldown>other->cooldown;
}
virtual TAttackData* selectAttack(const TAttackCollection&
     availableAttacks)

{
if (!availableAttacks.empty())
{
std::vector<TAttackData*> attacks = getValues(availableAttacks);
std::sort(attacks.begin(),attacks.end(),
  compareHighestDamage);
return attacks[0];
}
return NULL;
}
};


// Another concrete strategy: this time, an enemy using it
// will choose the available attack that has a lowest cooldown,
// so it may attack again as quickly as possible.
class LowestCooldownStrategy: public AttackSelectionStrategy
{
public:
bool compareCooldown(TAttackData* one, TAttackData* other)
{
return one->cooldown<other->cooldown;
}
virtual TAttackData* selectAttack(const TAttackCollection&
    availableAttacks)

{
if (!availableAttacks.empty())
{
std::vector<TAttackData*> attacks = getValues(availableAttacks);
std::sort(attacks.begin(),attacks.end(),compareCooldown);
return attacks[0];
}
return NULL;
}
};




Next is some sample client code using strategies:


void AnEnemy::selectAvailableAttack()
{
AttackSelectionStrategy* myStrategy = new HighestDamageStrategy();
setCurrentAttack(myStrategy->selectAttack(mAvailableAttacks));
SAFEDELETE(myStrategy);
}


However, this is quite rigid, which defeats the purpose of the pattern. I then thought of a way to select specific strategies. Two different alternatives came to my mind, in both cases using an enumerated type as a discriminant.

//Strategy selector enumerated type
enum TStrategyPolicy
{
HIGHEST_DAMAGE,
RANDOM,
FIRST,
LOWEST_COOLDOWN,
LOWEST_ENERGY,
WEIGHTED
//..etc
};



// Now, to implement the strategy selector I have thought of two
// different alternatives:
// I could use a factory function that had a switch statement
// on a TStrategyPolicy value, instancing one
// or the other strategy on demand.
// The second possibility consists on defining a
// map <TStrategyPolicy, AttackSelectionStrategy*>
// and initializing the map at the beginning.
// When the time comes to select a strategy,
// the selector function/class would just access the map.
// While simpler, it has a bit of overhead since an
// instance of all strategies has to be created regardless of if
// it is used or not. However, if
// a getStrategy() method is used frequently, it may actually turn
// out being more efficient, since
// every strategy will only be instanced once.

//OPTION 1: FACTORY FUNCTION
AttackSelectionStrategy* createStrategy(TStrategyPolicy selector)
{
// Ensure that this function's client frees the
// dynamic memory, or memory leaks are bound to appear.
switch(selector)
{
     case HIGHEST_DAMAGE: return new HighestDamageStrategy();
     case LOWEST_COOLDOWN: return new LowestCooldownStrategy();
     //...remaining cases
       default: return NULL;
}
}

//OPTION 2: USE A MAP OF STRATEGIES AND RETRIEVE AN INSTANCE WHENEVER //YOU WANT

typedef std::map<TStrategyPolicy,AttackSelectionStrategy*> TStrategyCollection;

class StrategySelector
{
private:
TStrategyCollection mStrategies;
public:

// The initialization is hardcoded, which would require to
// recompile 
any time a new strategy was added
// (this will also happen using 
a factory function), but without
// any reflection-like device that'd

// allow us to dynamically load on runtime a particular subclass

// (I'll have to research more on RTTI or some libraries)
// there's little else to do.
// If I'm mistaken, which is really likely, I'm open to
// corrections :)
void initStrategies()
{
cleanupStrategies();
mStrategies[HIGHEST_DAMAGE]= new HighestDamageStrategy();
mStrategies[LOWEST_COOLDOWN]= new LowestCooldownStrategy();
//...
}

// Free memory
void cleanupStrategies()
{
if (!mStrategies.empty())
{
for (TStrategyCollection::iterator it=mStrategies.begin();
     it!=mStrategies.end();++it)
{
     SAFEDELETE(it->second);
}
mStrategies.clear();
}
}

// Retrieve a given strategy.
AttackSelectionStrategy* getStrategy(TStrategyPolicy index)
{
if (!mStrategies.empty() &&
mStrategies.find(index)!=mStrategies.end())
{
return mStrategies[index];
}
return NULL;
}
};


Any of these two alternatives would allow for some interesting results. For instance, you might script behaviours for enemies, such as 'Aggressive', 'Defensive', 'Ranged', etc, and the attack selection policy might be a behaviour-dependent parameter.

The client method I presented before would be rewritten to this (of course, myStrategy can be refactored to an AnEnemy class member, which would require at least a setter method allowing changes on the strategy selection algorithm to apply):


//Using option 1

void AnEnemy::selectAvailableAttack(TStrategyPolicy strategyId)
{
AttackSelectionStrategy* myStrategy = createStrategy(strategyId);
if (myStrategy)
{
setCurrentAttack(myStrategy->selectAttack(mAvailableAttacks));
SAFEDELETE(myStrategy);
}
// else throw exception, or do something to notify the strategyId
// wasn't valid
}

// Using option 2: assume StrategySelector is a Singleton
// (http://en.wikipedia.org/wiki/Singleton_pattern).
void AnEnemy::selectAvailableAttack(TStrategyPolicy strategyId)
{
AttackSelectionStrategy* myStrategy =
StrategySelector::getInstance()->getStrategy(strategyId);
if (myStrategy)
{
setCurrentAttack(myStrategy->selectAttack(availableAttacks));
myStrategy=NULL;

// Don't delete the strategy here: that'll be handled by
// the StrategySelector when it invokes its cleanup method
}
// else throw exception, or do something to notify the strategyId
// wasn't valid
}


Now, we can define as many strategies as we want, and the code for the class AnEnemy won't have to be changed to do that. We may provide the strategy selection policy externally through the value of an int that would be cast to a TStrategyPolicy.

In fact, using LUA and luabind, which allows exposing C++ enums to LUA, we wouldn't even need to care about casting between enums and ints.

Unfortunately, due to tight time constraints, we've been trimming the variety of attacks that enemies can launch on our game, so this code will never see the light beyond this modest blog post.


LARGELY UNRELATED RANT: I've been a happy user of the Opera browser for close to 8 years now. However, after the 10.60 release some Google services, such as Google Calendar, Gmail or Google Docs, are screwed up in varying degrees of severity. My biggest annoyance is at the moment Docs. Besides being close to unusable when using their new version, I've been crashing every time it auto-saves, or when I manually save my work. Restarting the browser and logging back in every two minutes is a real pain in the a#se, so I've ended up switching to Firefox so that I could finish this post without fear of having to restart again.

People in Opera Software, PLEASE, can you fix that???

Thursday 8 July 2010

My first game design challenges

A couple of months or so ago I decided to stop lurking, and then I began submitting my own entries for Game Career Guide’s Game Design Challenges. In case you don’t know, Game Career Guide is one of Gamasutra’s sister sites, specifically oriented to students. It features some interesting articles on game development by prominent people in the industry, and it also holds a game design competition every few weeks. For these challenges, that are quite useful as a way to exercise one’s skills at designing and, mainly, communicating your idea as concisely as you can, they suggest a topic from which to devise a game, and then anyone may submit their own design in 500 words or less, including a maximum of three images. The most relevant ones are listed on the site. When I first learned about it, I instantly got interested and thought that I would take part on it as soon as I came up with a half decent idea. Inspiration, though, is a bit reluctant to assist me half of the time, so I have only participated three times so far. I got an honorable mention and a second place (the results for the third one haven’t been posted yet), so I guess I can’t complain. However, I’m still aiming for the first place. From now on, I’ll devote a whole post to future challenges, which I’ll update when the results are out...or maybe I should create a specific page to list the challenges, whatever. For today’s post, however, I was planning to share my first two entries.

My first time: Romance (No pun intended)

On the challenge’s wording they dealt with the romancing genre (for instance, the Tokimeki Memorial series), which is quite popular in Japan. Attempts to carry over those titles to Europe and the United States have kind of failed though. Our ‘mission’ was to design a game with romance as its main theme that could be more appealing to occidental mindsets.

To provide a bit of context, as the game will be heavily story-driven, I had the main idea while recalling 'Eternal Sunshine of the Spotless Mind', one of my favourite films ever.


The goal consists of gathering the pieces of a perplexing puzzle: the memories of your girlfriend/boyfriend and the relationship you had/have, which apparently you have completely forgotten. Solving the riddle doesn't mean you both get to live happily ever after: as you regain new memories and get closer to your goal, your decisions throughout the game and your interactions with other characters may significantly affect the outcome.

You won't be alone in your journey: Together with a partially controllable NPC who's going through the same, you'll have to cooperate to find out why your respective significant others seem to have been erased from your memories...if they ever existed.

At the beginning, you'll get to choose your gender and sexual orientation: they'll determine your partner's identity. Then you can pick a career (such as a scientist, a painter, a PR or a stripper) with benefits and disadvantages to your skills. There will also be some traits to choose which will set some background story-wise and grant you with further bonuses and handicaps. Your character's appearance will be customizable, for the eye candy.

Your companion will start with some skills of her own. As you progress through the game and get to know her better, you'll be able to 'discover' her own traits (not necessarily the same set you were offered in the beginning) and further refine her skills.

The plot will advance by completing certain sub-goals: - Get some reaction from an NPC, through conversational trees or performing in-game actions. - Reach some particular location. - Cooperative missions. Say, your partner uses her persuasion skill to distract some guy while you sneak past and then use your amazing ability to find information to...find some information. - Mini-game solving, related to whatever you're doing. Oblivion is useful as a bad and a good example: While I found the persuasion wheel totally unimmersive, the lock picking mini-game was, in contrast, reasonably well done.

Solving a sub-goal will trigger some hint about your relationship (which will contribute to get you attached to him/her, lest you might end up always romancing a secondary or even more unimportant character) and may give some clues for the next mission.

If you end up romancing other people (you cheater!), you'll have to talk to them, give them gifts or help them out. Your choices during the game may also modify the approval of one potential lover (where that option makes sense: no clairvoyance!). I'm afraid I won't be spoiling much if I say beforehand your companion will be a love interest, but there'll be more, some of which you might not get to meet on a single playthrough.

Last, there will be a variety of optional areas where you can get some benefits: insight about missions or the game world, shops, secondary quests, workplaces, motels, etcetera.

I enjoyed a lot imagining how the story would unfold. My weak point was, however, that I lacked a bit of focus on the gameplay. As a result, it isn’t totally clear if the game will be more of an RPG, vastly focused on conversations and character development, than a sandbox.
This is something that I have tried to solve for the subsequent entries. I still like the idea very much, and I intend to further develop it as soon as I can think of a set of suitable mechanics.

The results of the challenge, as well as the entries on the following pages, are listed right below, so you can read what other people did. My entry, that you’ve already read, is on page 8. http://www.gamecareerguide.com/features/835/results_from_game_design_.php

Second entry, second place :D: Inappropriate title

The second challenge I participated in asked contestants to take the title of a game that has nothing to do with the game itself and make another one that is better suited to that title. Examples included were Vagrant Story or Guilty Gear.

This time I opted for a more casual approach. I was playing Braid at that time (amazing game, by the way), and I couldn’t see how braids had anything to do with a time-controlling platformer (aside from a really brief mention on the plot introductory texts for one level). I then remembered Ratatouille and suddenly everything made sense: what about a hairdresser louse?

Don’t tell me it isn’t cute

As Louse Sassoon, a hairdresser-wannabe louse (Ratatouille anyone?), your dream is to make your human host wear the best-looking braids in the neighbourhood. To do so, you'll get to tame a set of rebel hair locks, forming the links that will shape the braid(s). However, humans and even your fellow lice will be around, decided to crush your dreams.

At the beginning of the level you'll get explained the type of braid you must do, as well as the possible new features you may encounter in it.

Then the game will star with Louse swinging from one of the locks (There will be some wind, blowing with varying strengths depending on the level). From there, it can jump to another lock either on its own, or carrying around the lock Louse was previously hanging from. If the jump is done while carrying around a lock of hair, one of the "links" of the braid will be made. After that, Louse will keep making links by repeating this process until time runs out. You must decide carefully when to jump so Louse can reach the desired lock avoiding to fall down. In addition to jumping and swinging, Louse can also use some items that may help it defeat its enemies, get some power-ups or score additional points. All the levels have a set duration. The area of interest where Louse will be able to put its skills to use will remain fixed for some seconds, and then the braid will go up (think of Puzzle Bobble, but in reverse order). If no links were done, the braid's appearance will look messy and you'll get less points.

Once the time has run out, Louse will move on to the next level if it managed to achieve a minimum score. There will be more than one scoring levels to provide an additional challenge and reward your skill with some bonuses.

Obstacles/Enemies:
  • Lice shampoo cloud. Be careful and avoid them at all costs, as these clouds may kill you.
  • Enemy lice. They despise Louse because they think it brings shame to the family. To defeat them, throw them some nits and make them fall.
  • Hairspray cloud. This ozone-layer-destroying cloud will also paralyse Louse for a few seconds, leaving it vulnerable against enemies, and making it lose some precious time.
  • Hair drier. Strong wind gusts will blow for a while, making swinging and jumping from lock to lock more complicated.
  • Others.
Items:
  • Hair gel: It stops a lock from swinging around due to the wind.
  • Nits: Keep them to fight the enemy lice.
  • Beads and ribbons: Use them to increase your score, as the braids Louse will make will look prettier <3
  • Blood bubble: It'll cover Louse, making it invulnerable for a few seconds.
  • Extra lives: Well, I bet all of us know these ones already, don't we?
  • End-of-level bonus: After finishing certain levels Louse will have a chance to make some cool hairstyle by combining the braids it has been making during the level. If successful, it'll earn a huge score bonus
A fellow programmer colleague from my Master’s final project, Aniol Alcaraz, ranked in third place. UPC seems to be hitting hard design-wise, doesn’t it? :)

Check the full list of winning entries here: http://www.gamecareerguide.com/features/855/results_from_game_design_.php

Third design: Michael Jackson

For the latest design challenge, our objective was to imagine a game centered about the late singer.

I’ve always thought that his videoclips were really original and elaborated -starting, of course, with Thriller, responsible for my irrational fear of zombies, so when I read about the challenge I thought that I could use that as an obvious theme. I was at a risk of ending up like on my first challenge, where I kind of left the essential gameplay aside, so I began plotting possible interesting mechanics.

Since leaving music and dance out of the picture is a no-no, I came up with a not-too-original rhythm game, borrowing lots from the Osu! Tatakae! Ouendan! and Elite Beat Agents games. To prevent my idea from being a total rip-off, I thought of an issue concerning these two games: The player can forget about the DS’s upper screen when playing. In fact, if she wants to achieve a nice score, she should forget about it, as it may be distracting. Storywise isn’t particularly meaningful either (except for the comic-book-like cutscenes that are played on the level’s play pauses), so iNiS might have done without the upper screen and nobody would have noticed the difference. I decided to solve that by adding an enemy to fight on the upper screen. Square’s The World Ends With You manages to do a two-screen combat system using both the stylus and the buttons that works reasonably well, and I thought it could be applied to my game, hence the 9 Michael Jackson’s evil impersonators he must defeat. (Oh, the number isn’t final...it could be 9, it could be 13,...)

Adding this ‘pay attention to both screens’ feature involves an additional complexity layer, which means the difficulty of the classic rhythm game on the lower screen must be decreased a bit so that the combined challenge is not unbearably difficult.

This is my original entry:
Michael Jackson vs the nine.
Nine die-hard fans who've taken their obsession way too far and now believe to have become him, have got rid of Michael's most famous video clips and replaced the originals with their own, utterly crappy versions. Michael will have to redo the videos performing the same moves that made him famous again while at the same time he defeats his evil impersonators to prevent his legend from being stained with shame.


Mechanics:
This is a rhythm game intended for the Nintendo DS. The main source of inspiration is Elite Beat Agents, but I’ve added a twist inspired on the battle system used in The World Ends with You to make the upper screen a bit more meaningful gameplay-wise than it was on EBA.



During a stage you’ll have to take care of two things:
Performing the dance moves as accurately as possible on the lower screen using the stylus. You’ll have to click and/or follow certain symbols at the right time to make Michael dance, and also increase the power meter (the better he performs, the more energy he’ll gain).
At the same time Michael dances, he’ll have to dodge, counter and attack the evil impersonator for the current stage (remember those fans have lost touch with reality and think the authentic Michael is actually an imitator himself). Michael’s fan will be displayed on the upper screen, and every now and then he’ll throw some spotlights, rocks, etc (dependant on the setting of the stage). The directional pad+L trigger (or ABXY buttons+ R trigger for left-handed people) will allow you to avoid the items, deflect them or attack your foe, pressing the buttons when appropriate. The damage you cause to him will be proportional to the “style meter”.

As the focus is on rhythm, the attack and dance sequences will have to be balanced so that Michael’s attacks blend in nicely with the music. In addition, the dance moves part should be a bit easier than it is on EBA so that when incorporating the upper-screen-focused gameplay the combined challenge level does not get impossibly difficult.

The stage ends either when the whole video has finished, or when the player loses, which will happen when the style level goes below a minimum (either by repeatedly failing at dancing, or by getting hit by the crazy fan). There is a middle-ground situation: if by the end of the stage the style level is above the minimum threshold but the player hasn’t beaten the enemy, the score will be computed and the experience will accumulate to the total experience counter, but the stage will not be considered as cleared till the enemy has been defeated..

Last, the game is structured on several tiers of two or three stages of increasing difficulty. The player may choose between the available stages freely, but all of them will have to be cleared before advancing to the next tier.

The time limit to submit entries ended yesterday, and they’ll be posting the results next week.

If I happen to have a good idea from which to code a simple game on XNA, C++ plus [OpenGL|DirectX] or Pygame for learning purposes (What should I do? A scrolling shooter? A platformer? A tower defense? I’m open to any suggestions), my next post might deal with it; otherwise, I may have to recycle a couple of incomplete designs that I have in mind. For now, I’ll just spoil the titles: Psyche, and The Path is The Goal (this one is probably temporary, though).

Tuesday 6 July 2010

Wall Chaos (II) - Technical stuff (Run for your lives!!)

After the first post, focused on design issues, this second one will show the dirty implementation details behind the 2D version of Wall Chaos.

The language of choice was C++. Firstly, because that way I had the chance to reuse some code from the theory classes, and also because it's the language I feel most comfortable programming in excluding Python. 

If you remember, the assignment included a constraint that restricted the game to be isometric. Getting this done was probably the most challenging part, and I ended up mixing theory concepts learned in class with some ideas I got from Ernest Pazera's Isometric Game Programming with DirectX 7.0.

As you probably know, there are several subtypes of isometric maps. The most widely used ones are probably the staggered map(for example, the one used throughout the Civilization series) or the diamond map (The Age of Empires maps have this kind of layout). I was pretty sure from the beginning that I'd go with the second approach, as it seemed to fit better with the shape of the rooms.  Both types are pretty similar, but they differ in the way the map is traversed. 

This is how the x and y coordinates range in a diamond map:
This setup makes it a bit more difficult to blit a tile, since two consecutive cells aren't blitted in rows as in a typical rectangular 2d map. Besides, the cell sprites (which are rectangular) will overlap, so the traverse order matters.

This is the blitting loop (there is an outer loop for further layers, as the tiles are stackable, but for brevity's sake I will omit it)

for (int y=0;y<SCENE_HEIGHT;y++)
{
for (int x=0;x<SCENE_WIDTH;x++)
{
TTile* tile = &(gameData.scene->map[y][x][z]);
//Read the tiles' sprite sheet to get the clip rectangle
tileRect=gameData.scene->getTileRect(tile);
int tileIndex=tile->index;
if (tileIndex!=NOTILE)
g_pSprite->Draw(textures[TILESET_INDEX],&tileRect,NULL,
&D3DXVECTOR3( float((x-y-1)*(TILE_WIDTH>>1)-baseX), float((x+y)*(TILE_HEIGHT>>1)-baseY-z*TILE_HEIGHT), 0.0f),
 inkColor); 
}
}

The x,y screen coordinates are computed as follows;
x_screen = ((x_map-y_map-1)*TILE_WIDTH/2)-baseX;
y_screen = ((x_map+y_map)*TILE_HEIGHT/2 - baseY-(z_map*TILE_HEIGHT);

baseX, baseY define the offset from the screen position (0,0). This ensures that the map is rendered at the right location (at the beginning of the game, it will typically start next to the top edge and horizontally centered).

Another issue was to retrieve the cell in the map from a set of screen coordinates. One of the main uses for this is to find out which cell the player has clicked on with the mouse. As Wall Chaos was basically controlled through the keyboard -save for the GUI menus-, I used this method to quickly convert between screen and cell coordinates instead.

The algorithm consists of two parts. This time I'll just describe it:

First, get the cell's rectangle (The diamond cell and its surroundings).
To do this, from the screen coordinates we'll first get the world coordinates, taking into account the scene's offset. This means that if the mouse click resolved to position (100,200), and there is a (400,64) scene offset, the world coordinates would be, respectively, (500,264).

Then, the tentative coarse (per-cell) and fine (per-pixel) coordinates are to be retrieved. This is done in the same way as with common 2D tiled maps:

coarse = (worldX/TILE_WIDTH, worldY/TILE_HEIGHT)
fine = (worldX%TILE_WIDTH, worldY%TILE_HEIGHT)

On those maps we'd probably end the whole process here. However, there are still some more steps involved in this case. Due to the scene's offset position, there is a chance than the fine coordinates are negative and we need to adjust them, adding the tile width or height to the modulo operation result.

Then, depending on the value of the coarse coordinates, we need to adjust the pre-final map coordinates. That's achieved like this:

int mapX=0,mapY=0; //Candidate map coordinates
while(coarseY<0)//Move north
{
mapX--;
mapY--;
coarseY++;
}
while(coarseY>0)//Move south
{
mapX++;
mapY++;
coarseY--;
}
while(coarseX<0)//Move west
{
mapX--;
mapY++;
coarseX++;
}
while(coarseX>0)//...and finally, east
{
mapX++;
mapY--;
coarseX--;
}


After iterating through these loops, the first part of the procedure ends. We have a pair of coordinates corresponding to a rectangular cell (x,y). However, depending on the fine coordinates, the actual diamond cell might be one of the 4 depicted adjacent cells.



The second part's objective is, therefore, to retrieve the actual cell. Taking advantage of the fact that  the ratio width:height of the tiles was 2:1 we can use the following property:

if(fineX<(TILE_WIDTH>>1))//32
{
//Left
if(fineY<(TILE_HEIGHT>>1))//16
{
//Up
if( (TILE_HEIGHT-fineX)>>1 > fineY ) { mapX-=1;}
}
else
{
//Down
if( (TILE_HEIGHT+fineX)>>1 < fineY ) {mapY+=1; }
}
}
else
{
fineX-=(TILE_WIDTH>>1);

//Right
if(fineY<(TILE_HEIGHT>>1))
{
//Up
if( (fineX>>1) > fineY ) mapY-=1;
}
else
{
//Down
if( (TILE_WIDTH-fineX)>>1 < fineY ) mapX+=1;
}
}

After this, mapX and mapY will hold the final map coordinates.

Last, this game featured music and sound. One of the assignment requirements asked us to implement an interface to abstract and encapsulate the concrete sound library used. This was relatively simple to do. I used the old API of FMOD, which seemed good enough for my purposes, and abstracted the three kinds of supported sounds (Streams, Sounds and Samples -midis, basically) into three subclasses of a base class CSoundItem. At the resource loading time, the layer parsed the filename and, depending on the extension (*.wav, *.mid, *.mp3,...), it instanced a particular subclass.
The sound layer had an STL map indexed by an ID string containing all the loaded sounds (the load was done on a per-game-state basis), and then the application just had to keep track of the IDs to play any sound of music track. 

I could dwelve a bit more on the game's architecture (For instance, for managing the game states I defined a couple of variables to keep the current and next state IDs and then a factory to resolve and instance the particular GameState subclass to switch to next. For Once Upon a Night, the Master's final project, I opted for using a stack-based game state machine instead, which turned out to be much more flexible), but I guess I've bored you enough already. If you feel like diving a bit more into the code, you may download the sources from here.

Tuesday 15 June 2010

Tools in Python

There's been some time since my last update, so I've decided to write a new post to prove I am still alive and kicking.

However, the second post about Wall Chaos will have to wait a bit more, as I haven't finished writing it yet. Instead, I will show you some tools developed in Python that I have coded to assist me in the development of TINC (the first two scripts), and while I was playing Harvest Moon: Island of Happiness on my DS (the third one). The link to get the source code for the three of them is at the end of this post.

The reasons why I chose Python were that I wanted to get better at it, and mainly because it is a language I feel comfortable programming in. Besides, it is widely used in the games industry for tools or scripting, which is always a plus.
The first one is a simple level editor. If you remember TINC from previous episodes, it is just a clone of the Columns puzzle game. While I was designing test cases for it (yeah, I know...a bit over-engineered for a puzzle game) I got bored of editing text files by hand, so I came up with a GUI application. It may seem a little counter-intuitive at first sight, but it is quite easy to use in fact:
Select the checkboxes under the cell(s) you want to set and then pick a colour on the right combo box(you can choose "EMPTY" to clear the cells). The left-most checkboxes will toggle selection on a full row. Likewise, the top-most checkboxes will select/deselect full columns. Last, the checkbox at the top left corner will toggle selection on the full board.

I used wxPython as the library of choice for the graphical user interface. The main frame consists of two separate panels, the left one displaying the board and a grid of checkboxes to select cells, rows, columns or the entire board, and the second one displaying further functionality, such as colour selection, board clearing and exporting the board to a text file. 

Aside from the usual tasks related to GUI programming (layout, event binding, etc.), the most challenging part of the application, to name any, was the test for valid boards, since the program won't allow the user to export an invalid board.
A board is considered valid when there are no gaps left below a coloured block. For instance, the first screenshot corresponded to a valid state.

...whereas this one does not:
If an attempt is done to export the layout when the board in in an invalid state, the application will complain:
The validity check is quite straightforward. The board, initially assumed empty, is considered valid. After that, we'll start going through the columns as long as the current column is valid. To ensure that, the algorithm will start on the top-most row, and then it'll go down until the first coloured block has been found. If the column is empty, it'll be OK. If we find a coloured block, then every other block located in the rows below it must be coloured as well, otherwise the column, and therefore, the whole board, is considered to be invalid.
On the application, this check is performed when clicking on the "Export" button.
You may find the full code  under the "editor" subdirectory in the linked archive at the end of the post.
The second script that I coded while developing TINC is a bit more complex despite the fact that it does not come with a fancy user interface, as it is a command line tool.
You may find the full code  under the "editor" subdirectory in the linked archive at the end of the post.
Sometimes, when you're using enums in C++ (and other languages) you may need a text translation of the value. For instance, when logging messages, a string is more human-friendly than the enum's integer value, hence the need for this script (again, I didn't feel like browsing through all the enums and then writing the string arrays by hand, so I did some coding to automate the process).
It parses a specific header file where I keep type redefinitions, constants and others, searching for enumerated type definitions. Then, it creates a second header file, now containing several arrays of strings (one array for each enumerated type), and a set of matching inline functions, to translate a value of a certain enum to its matching string value. This screenshot depicts on the left side the source file, and on the right a portion of the generated translations file:



The script source code is now a bit more complex, specially on the parser side, relying on regular expressions to find enum declarations and such. The code relies on two classes: Context, which is actually the class in charge for parsing the source header file, and Generator, responsible for creating the enum translations header file.
Check the code under "enum_names.py".

My last tool is actually a lookup application I did to avoid checking the WWW when I was playing Harvest Moon: Island of Happiness, a game by Natsume and Marvelous for the DS. 
In case you don't know the HM series, these games put you in the place of a boy (or girl, depending on the game: the most recent instalments let you choose) that accepts a position as a farmer on a certain town. You'll get to develop the farm by growing crops, tending cattle, chopping trees, mining, fishing, cooking and flirting among several other tasks (if you've ever played Facebook's Farmville, it is a bit similar, but WAY MORE complex and a lot funnier).
It turns out that there are lots of recipes you can make by using several ingredients: the crops you've grown, the fish you've caught, and many others. At some point during my play-through I decided to fill my 'discovered/delivered recipes' (you can get a grasp of your progression throughout the game by checking the list of delivered crops, animal raw materials, gems, recipes, etc.), and I needed some quick reference about the ingredients I might need. As I said before, I wasn't in the mood for keeping an Opera tab constantly open to check every now and then, so I decided to develop a query application.
The GUI lists the set of recipes matching the criterion filter (you may search by the ingredient you need to deliver to unlock the recipe, or by one of the ingredients the recipe consists of), together with some additional information (name, description, stamina recovery, etcetera). The rows on the grid may be selected, and the text area below will display a list containing all the ingredients the recipe needs.
Again, I used Python and wxPython for the GUI. In addition, the application uses an sqlite embedded database where the recipes, ingredients and related data are stored. One of the python modules of the application contains the SQL code to create and fill the tables. I suggest using sqliteadmin, too, to manage the database. 
I intended to make the application multilingual, hence the initial language selection dialog, but it isn't functional, so at the moment Spanish is the only available language, sorry.
And, finally, here is the Dropbox link to the *.7z file containing the code for the three tools. Feel free to modify them at will. Credit will be nice, of course ;P
http://db.tt/YwdUywWD