About Me

My Photo
I'm a colonist who has declared war on machines and intends to conquer them some day. You'll often find me deep in the trenches fighting off bugs and ugly defects in code. When I'm not tappity-tapping at my WMD (also, known as keyboard), you'll find me chatting with friends, reading comics or zoning out on my PSP.

Monday, February 13, 2012

Game Review - Shank 2 for PC

The original Shank was a 2D side scrolling beat-em-up released back in 2010. The game was well received by gamers and even grabbed an IGF Game Finalist award. With Shank 2, independent developers Klei Entertainment, had to deliver on the promise of making a better sequel. It was clear that some of the elements reminiscent of the first game had to stay. It was also apparent that many of the quirks and missing features pointed out by the gaming community had to be taken into consideration. Having finished the campaign (on Easy of course), I must say that Klei have indeed managed to make a game worthy of being a successor to Shank.

Controls:
The controls in Shank 2 have been refined and made more PC friendly. Shank (the protagonist) can interact with the environment to a certain degree allowing him to flip switches that set off traps as well as pick up weapons dropped by fallen enemies. Ranged attacks are now much easier to perform and direct with a simple right-mouse click. Standard platforming elements like running, jumping, swinging and throwing have all been brought over from the first Shank. Gameplay is well paced in Shank 2, allowing the player to learn the basics of combat and environment traversal before being pit against anything serious.

Combat:
Combat is part of the core gameplay in Shank. The player has three weapons to use at any given time. A heavy weapon, a ranged weapon and explosives. Apart from these three weapons, Shank also has a normal attack (called his Shank attack). Unlike the first Shank, swapping between weapons is not allowed. This is one tiny feature that I miss because it really does make a difference in a fight. Also, there is no way for the player to guard against attacks, although dodging is possible. Dodging attacks is pretty hard as there is only a split second within which to dodge enemy attacks and god-forbid if there are multiple enemies trying to whack you all at once. I suspect that fewer players will use dodge and will mostly rely on jumping over or away from enemies to avoid incoming attacks.

One of the new moves that I really like in Shank 2 is the counter attack. This move is similar to God of War style moves where the player can quickly do something spectacular when presented with an on-screen notification. In Shank 2, if an enemy is about to attack and has an exclamation mark over his head, the player can perform an insta-kill by pressing a single key. It is also possible to counter-attack some of the boss moves, although this doesn't let you insta-kill them (that would make things too easy, I guess). The good ol' pounce and grab attacks have been carried over from the original Shank. The grab attack does exactly what it says. Shank can grab an enemy standing next to him and then do whatever he feels is fun. Those fun things include slamming the enemy against the ground, firing a shotgun at point-blank range or simply throwing the enemy onto oncoming hostiles. Unlike the first Shank, the player can now also grab bigger enemies and pound the hell out of them! The pounce attack allows Shank to leap over to an enemy some distance away and grab him. This move is especially useful when dealing with enemies that do some sort of ranged attack.

Graphics:
Like the original Shank, violence plays a major role in Shank 2. There are a plethora of ways in which to rain doom upon your enemies like shoving baseball bats down their throats, ripping them apart with a chainsaw or pistol-whipping them. This is definitely a nod to the genre and whole-heartedly embraces every adolescent fantasy that you might have. Gore and explosions are omni-present throughout the game. The original Shank was lauded for its art style and Shank 2 is no slouch either. Shank 2 follows the same 'El Mariachi' look but unlike its predecessor, it certainly plays the part too! Animations are fluid and the visual feedback from performing actions is exquisite. A lot of effort has also gone into the game environment with intriguing detail, weather effects and ‘Desperado’-styled silhouettes. Cutscene animations are interesting, to say the least.

Music:
The music in Shank 2 is simply wonderful. Jason Garner and Vince de Vera have outdone themselves using the nostalgic Shank theme as a set-piece. The music enhances the player’s experience with appropriate tension and action. Voice overs and environmental sound effects are also very effective. With the soundtrack for the first Shank already released, it’s only a matter of time before that of Shank 2 gets out.

Plot:
The original Shank didn’t have much of a story to it and Shank 2 does not attempt to improve things in this area. While the story-telling aspect of Shank 2 is certainly not bad, I felt that a few more questions about Shank’s past could have been answered. The cast of new characters like Corina (the female counter-part to Shank) could have also been fleshed out. The game features Rebel Intel. These are basically pamphlets that describe some of the game characters and their motivations but finding this information is somewhat akin to unlocking secret content by scouring levels. Another tiny peeve of mine is that I felt that the game could have been longer. The first Shank had an equally long campaign and an extra co-op campaign to go with it. The campaign in Shank 2 took a little over 3 hours to complete and left me lingering for more!

Multiplayer:
If the campaign is short, the game certainly makes up for that with an entertaining multiplayer survival mode. Klei Entertainment listened to their fans and went all out in implementing a great co-op aspect to the game which allows you to team up with another player and survive against waves of enemies. The survival mode can be played online or locally (the first Shank had a local only co-op campaign). Rather than bore you with incessant text about how Shank 2’s survival mode works, I’ll just point to this excellent tutorial video after the jump.



Unlockables:
Shank 2 has 16 different costumes to be unlocked by completing various single player and multiplayer objectives. The costumes are not simple re-skins. Each costume has a particular stat bonus associated with it making it crucial to your style of gameplay. For example, if you are more of a ranged attacker rather than an up-close melee brawler, then there’s a costume that will help you do more ranged damage. Shank 2’s Steam achievements also make for great gameplay. Ah, nothing like getting 60 pistol counter-kills, eh?

Verdict:
Shank 2 is high on thrills and will satisfy your thirst for gore. The single player campaign offers an entertaining but short experience. If you have a friend to play with online, then there’s loads more fun to be had in the survival mode! The game is currently priced at 9.99 USD (approx. 500 Indian Rupees) on Steam. Shank 2 is also available on Origin for PC, XBox and PS3. Grab the game from it's Steam page here!

Do you think this game review was fair? Please let me know in the comments!

Thursday, February 2, 2012

Lazy Programming

I am a slightly lazy programmer. There I said it! This doesn't necessarily mean that it's a bad thing to be lazy... Lazy programmers try to avoid doing grunt work. They are the ones who will write that tiny tool or that simple script just so they can get out of having to do a repetitive task. Those same utilities will end up being used by others and will in the long run boost productivity!

"So, is it good to be lazy?" - one might ask. The answer is - "It entirely depends...". You see, a lazy programmer can also be that fellow most people find uncooperative in a team. He might want to spend two whole days (at crunch time!) writing a script that would save him a few hours of continuous grunt work. If a lazy programmer is forced into a position where automating a task is quite infeasible, then BEWARE! The programmer will now unleash the beast within - moaning, groaning and cursing all the way through to task completion. Another area where lazy programmers don't fit in, is when they are called upon to debug someone else's code. Most programmers hate this part of the job but lazy programmers hate it even more! They will naturally point out flaws in the code architecture (ritually quoting design patterns that should have been used).

However, there is one very important thing that lazy programmers love to do! Lazy programmers love to design code. Give them a chance to do so and they will build you a very flexible and generic system (covering lots and lots of use-cases). The same system could be taken and simply "plugged" into other projects with similar requirements! Lazy programmers also tend to write very elegant code with fewer bugs by virtue of the fact that they encourage re-usability.

At the end of the day, Lazy programmers are bad soldiers but good Generals. Are you a lazy programmer? Let me know what you think constitutes a lazy programmer in the comments.

Happy (lazy) coding!

(Above comic, courtesy of http://xkcd.com)

Thursday, January 5, 2012

Create an icy glass silhouette with Gimp.

Hey folks!

I came up with a nice effect which I thought was really worth sharing. Refer to the following image for a clear picture (pun intended) of what we are trying to achieve.
Note that I am using Gimp 2.6.1 on Windows. Gimp is free software and can be downloaded from www.gimp.org. Since I don't want to end up with an extremely long-winded post, I'll just assume that you can find your way around Gimp. If you do find yourself stuck at some point, feel free to comment on this post and I will gladly help you along.

Step 1: Begin with an empty canvas size of 640 x 480.

Step 2: Set the foreground color palette to the following shade of Blue - 80c0ff and bucket fill the background layer.

Step 3: Create a new background layer and name it 'Noise'. Bucket fill this layer with the following shade of Blue: 386597.

Step 4: Go to Filters->Noise->Hurl and use the settings in the image below.












Step 5: Go to Filters->Blur->Gaussian Blur and apply horizontal and vertical blur radius of 25.

Step 6: Set the opacity of the Noise layer to 70 and the blend mode to Value. Your image at this point should look similar to this.









Step 7. Now, create a new layer with a white background. Go to Filters->Noise->RGB Noise and use settings of 0.2 for Red, 0.2 for Green, 0.2 for Blue and 0.0 for Alpha.

Step 8: Set the opacity of the White layer to 30 and the blend mode to Grain Extract.

Step 9: Create a new transparent layer on top. Name it 'Silhouette'.

Step 10: Set the foreground color to full white and paint haphazardly inside this layer. See the picture below for the kind of painting you should do.









A real piece of art, huh? You don't need to precisely follow this painting but try to concentrate on the center of the picture since that is where we will ultimately end up placing our silhouette.

Step 11: Gaussian blur the layer with horizontal and vertical blur radius of 100. Change the blend mode of the layer to Value. Your image should now look similar to this.









Step 12: Now, its time for us to put in our silhouette! Make a heart shaped cut-out in the center of the 'Silhouette' layer. You can easily make the top part of the heart with two circles and then use the free select tool for the bottom portion of the heart. Then just delete the area within the selection. Alternatively, you can use the eraser tool and erase in the shape of a heart. No need to be totally meticulous about the shape of the silhouette since we will be blurring it anyway. I've chosen to go with the selection method and if you did the same, you should end up with an image similar to the one below.









Step 13: Select the entire 'Silhouette' layer (Ctrl + A) and Gaussian Blur it with horizontal and vertical radius of 30.

Step 14: There is no Step 15!

Here is another variant of the effect. I just played with the colors, opacities and of course did a completely new silhouette.

Enjoy!

Saturday, December 31, 2011

Create a simple vintage photo effect with Gimp

Hey folks!

Sometimes you might want to take a recent photo and make it look like it was taken with a vintage camera. Here's one easy way to do this. Note that the image processing software that I am using here is Gimp 2.6.1. Gimp is free software and can be downloaded from http://www.gimp.org/

Alright, just to give you guys a feel of what we're trying to accomplish, here are before and after shots of a photo that I took when visiting the Chinese Gardens in Singapore.

Before:












After:












Step 1: Open the image of your choice in Gimp.

Step 2: Duplicate the image layer one time. You can duplicate a layer by clicking on the duplicate button at the bottom of the layers panel window or pressing Shift + Ctrl + D (in Windows).

Step 3: With the new layer selected, go to Colors->Desaturate. Pick 'Luminosity' among the options presented and then click OK. Your image should now look Black and White.

Step 4: Change the blend mode of the Black and White Layer to 'Overlay'. The blend mode can be changed from the drop-down menu at the top of the Layers panel.


Step 5: Change the foreground color to the following shade of Yellow: fbf2a3

Step 6: Go to Layer->New Layer (or press Shift + Ctrl + N). Among the Layer Fill type options, select 'Foreground color'. Leave everything else as is and click OK.

Step 7: Change the blend mode of the new layer to 'Multiply' and set its Opacity to 60. Your image should now have a yellowish tinge.

Step 8: Change the foreground color to the following shade of Magenta: e865b3. Once again, add a new layer with Layer Fill type as 'Foreground color'. Change the blend mode of the new layer to 'Screen' and set its Opacity to 20.

Step 9: Change the foreground color to the following shade of Blue: 0949e9. Again, add a new layer with Layer Fill type as 'Foreground color'. Change the blend mode of the new layer to 'Screen' and set its Opacity to 17.

Step 10: That's it! We're done. You may tweak the opacities of the Yellow, Magenta and Blue layers to make your particular image seem more authentic.

Enjoy!

Friday, December 30, 2011

Light Snake for HTML5!


I have had the good fortune to explore a bit of HTML5, an emerging web standard that is poised to take the online world by storm. The technology isn't quite there yet. Current browser vendors offer differing or incomplete implementations of the standard and it's a bit of a pain to ensure that whatever you write works generically. Still, this is one of those lemons that bears watching...

The first thing that crossed my mind was to port LightSnake. Its a simple and fun game of snake and requires very minimal player input. And so, I did manage to port the game from C++ to Javascript and get it running acceptably well on most of the major browsers. One notable exception is that dinosaur of all browsers, the one that exists simply to torment all web-developers. Yes, Internet Explorer!

The project has been hosted on Google App Engine and can be accessed from the following URL: lightsnakegame.appspot.com (I wanted to get the app name 'lightsnake', but someone seems to be squatting on it).

Enjoy!

Wednesday, November 9, 2011

Light Snake

While listening to some really cool music on soundcloud, an image of the old-school Snake game popped up in my head. A game of Snake with neon lights. So, I thought to myself - "Heck, I should make this!" And so I did...


Needless to say, I didn't sleep that night.

Want to play? Get it from:

Thursday, October 27, 2011

How to erase specific elements from an STL container - the C++ way.

STL iterators are tricky little fellows. One moment they act clean and the very next, they throw their hands up and say something cryptic. Consider this snippet that erases all elements whose values are 20 from a vector of integers.

typedef std::vector<int> IntVectorType;
IntVectorType vInt;

for(IntVectorType::const_iterator iter = vInt.begin();
iter != vInt.end(); ++iter)
{
if( *iter == 20 )
{
vInt.erase(iter);
}
}

Lo and behold! The program crashes! This is because when you erase an element from a container all iterators to its position are invalidated. This just happens to be our loop iterator. So, what is an innocent programmer to do?

Well, there are two ways to erase individual elements in an STL container.

Method 1: The crude way ( recommended for cavemen/barbarians/C -programmers ;) )

IntVectorType::iterator iter = vInt.begin();
while(iter != vInt.end())
{
if( *iter == 20 )
{
iter = vInt.erase(iter); // Get iterator to next element.
}
else
{
++iter; // Increment if not erased.
}
}

The method vector::erase() returns an iterator to the element that subsequently follows the last element that was erased. So, we just use that iterator to continue looping. Good! Problem solved! Is there a better way?

Method 2: The modern C++ way (recommended for rockstars/you/me)

struct EraseFromVector
{
// Functor
bool operator ()(const int value) const
{
return (value == 20);
}
};

vInt.erase(std::remove_if(vInt.begin(), vInt.end(), EraseFromVector()), vInt.end());


Looks like g(r)eek, you say? Alright then, let me explain. Basically, std::remove_if() is a magical chap. He takes two iterators as a range within which to work. For each element within that range, he then checks the unary predicate(our third argument) to see whether the element should be removed or not. If the predicate returns true, the element is removed.

I did say "removed" but in actuality, remove_if() sends the doomed elements to the back of the container. He doesn't actually remove them. How could he? He doesn't know what kind of container he's working with. Only the container can remove elements.

The nice thing about remove_if() is that he is guaranteed by the standard to preserve the order of the elements that were not removed. So, if our vector contained the elements 10, 20, 30, 20, 40 in that order, it will now contain the elements 10, 30, 40, 20, 20.

Finally, remove_if() returns an iterator to the start of the sequence containing all those miserable elements just sitting there at the back waiting for the axe to fall. We pass this iterator as the first argument to vector::erase() and an iterator to the end of the vector as the second argument. In one full swoop, all elements in the range are erased.

Now, doesn't this seem a lot more fun than a boring old while loop? :)