Archive for May, 2008

Metaprogramming in PHP

Tuesday, May 27th, 2008

Not so long ago I wrote about few meta programming tricks in Javascript. These are really powerful programming techniques that let you create elegant frameworks with generic code that adapts to your needs at runtime. But Javascript is not the only language that can accomplish stuff like that. You can use pretty much the same tricks in PHP. Yes, you heard me right – the ugly cousin of Perl, and the most hated and most used server side language can do this stuff.

Let me start this with a real life problem which was very often pointed out as a flaw in PHP 4. As you can remember, in PHP 4 you defined a constructor of a class like this:

class Foo
{
   function Foo()
   {
      // initialize
   }
}

In other words construction was a function with the same name as a class. PHP 5 introduced new constructor semantics:

class Foo
{
   function __construct()
   {
      // initialize
   }
}

This was done to solve a problem that most PHP developers always had issues with – namely how to call the constructor of a parent, if you don’t know it’s name. In PHP 5 it is easy:

class Foo extends Bar
{
   function __construct()
   {
      // do something
      parent::__construct();
   }
}

Easy, peasey! How do we do that in PHP 4? Well, we either hard code it or use a little bit of meta programming:

class Foo extends Bar
{
   function Foo()
   {
      $parent_name = get_parent_class();
      parent::$parent_name();
   }
}

What would be the problem with simply hard-coding parent::Bar() here? Think about what will happen when you create subclass of Foo. SubFoo class will try to call function Bar() which does not exist in Foo. The way we route around this issue is utilization of variable functions. Let me try to make it clearer by using a much simpler example:

function foo() { echo "Hello World!"; }
 
$my_string = "foo";
 
$my_string(); // outputs Hello World!

In other worrds, if you put a set of parenthesis after a variable, PHP will try to evaluate that variable and use it as a function name. It works in similar way to the PHP method call_user_func which lets you pass in a string representation of a function name, and have it called for you. And since you can generate that string on the fly, it makes for some interesting programming techniques. For example you can create a nifty function like this one:

function foobar($my_class_name, $my_method_name)
{
   if(class_exists($my_class_name))
   {
      $my_object = new $my_class_name();
 
      if(method_exists($my_object, $my_method_name))
         $my_object->$my_method();
   }
}

This function takes two strings. One is a name of a class, and one is a name of a method. It then initializes the class if one exists, and then calls an instance method of that class specified by name. You can pass any class and any method name, and if they are correct, the method will be executed.

There is also something called variable variables that may often come in handy. For example consider the following:

$foo = 'bar'; 
$$foo = 'baz'; 
 
echo $bar;   // outputs baz
echo $$foo; // also outputs bas

The contents of $foo are evaluated prior to assignment in $$foo so it dynamically becomes $bar on runtime. Combine that with variable functions and you got yourself a whole arsenal of meta programming weapons. An if that’s not enough for you then there is eval – a function that takes a string and tries to evaluate it as PHP code. Eval has it’s own little quirks though, and may cause somewhat unique issues. For example, code that is built dynamically by concatenating strings is notoriously hard to debug. It also won’t be properly highlighted by the IDE, and it which makes properly formating and escaping it will be difficult. So it probably deserves it’s own post.

I won’t deny it – PHP is not the prettiest language, and the lack of namespaces in it’s function library makes for some colorful naming patterns. But it wouldn’t be so prevalent and so popular if it didn’t have a lot of power underneath the hood.

It’s just a model…

Monday, May 26th, 2008

There is one thing that totally kills my immersion in a video game – it is the Monty Phythonesque realization that “it’s just a model”. In other words, if I see a piece of scenery – such as a house, or a door of some sort I should be able to go and investigate it. I hate entering a long corridor lined with doors on each side only to realize that the only one I can actually open is all the way on the other side. All the other ones are just textures on the wall and can’t even be interacted with. Or for example a village in which houses are used as walls, and obstacles rather than places you can visit and explore.

Camelot!

There are few games out there that do get this right. Morrowind and Oblivion and similar open ended RPG games usually get this particular feature right. In Morrowind for example there are no plot driven doors, or insurmountable waist height fences. If you see a door, you can unlock it. If you see a house, or a hut you can go inside to check whether anything valuable is inside. If there is a chest in the room, you can open it, take stuff out of it or put your stuff inside. If you spot a nice looking cup or a plate on the table somewhere you can pick it up and sell it in a pawn shop for few coins.

Of course Morrowind still contains many static scenery elements. Doors and containers are indestructible (but it’s ok since you can always pick their locks if you have enough skill) and most of furniture like tables, chairs, shelves and etc cannot be moved or damaged in any way. But the fact that each door leads somewhere, that each chest, wicker basket or a box you see is an actual functional container (even if empty) and that each room contains dozen items you can move or loot (even if worthless) more than makes up for this. It gives you such an astonishing degree of freedom that you forget that most NPC’s are painfully static in that game – spending their whole lives in the same room of the same building. I hear that Oblivion changes this by having roaming NPC’s who have regular schedules instead.

Someone will say it is hard and expensive to design game worlds the way Morrowind and Oblivion do it. I won’t argue with that. It is definitely harder to design few dozen of empty rooms that contain nothing specific to the plot of the game than to draw few dozen door textures and attach “this door is locked from the inside” trigger to them. But there is always a cheep alternative and it is called “good level design”.

Fable had this sort of level design too, despite the fact that the game world was smaller than in Morrowind by several orders of magnitude and much more linear. And yet you still could visit most the buildings you saw, loot them, kill their inhabitants and etc.

I wanted to propose something. This might be very radical approach but bear with me. How about – and I’m talking purely theoretically here – we do the following. Whenever you are tempted to add a dummy door that is permanently closed to a wall or a building – don’t. It is really that simple. Don’t line each corridor with row upon row of “decoration only” doors that cannot be open. Use actual wall decorations instead. If you are building a village or a town just design few dummy houses with 1-2 rooms each and throw in some worthless junk in there that the player could loot and perhaps even sell for 1 gold piece/credit each. It is really not that hard – you can have one or two room templates, and then just populate them with appropriate objects and textures based on the in-game location and local decor. If you do not want to put a visitable room somewhere simply do not expose any tempting door or entry way to him. If you will, someone playing the game will surely try to check it out and be disappointed. So no permanently cosed doors, no inaccessible stairwells that cannot be ascended, no fake archways, no man sized windows with impenetrable glass, no insurmountable waist high fences and etc.

And of course if you have to have a closed door, always offer the player more than one way to open it. They could either take an easy quest to get the key, or train for 6 levels to get their lock picking skill up to even attempt the door. Or allow them to bash it in, and let him deal with the fact it will alert the local guards.

It is really such a simple design rule and yet so many games get it completely wrong building impressive environments that cannot be interacted with in any way. Every door that cannot be open, and ever fence that cannot be jumped over abruptly jolts the player out of the game, and ruins the feeling of immersion.

Magic the Gathering Joke Revisited

Friday, May 23rd, 2008

I noticed that some blogs I read routinely close comments on old posts, supposedly to avoid spam. There is even a Wordpress plugin that does this for you. I find that practice silly. I keep spam at bay via filtering, bot detection and captchas – and it seems to be working just fine for me. I’d hate to close old blog posts because a lot of them still get comments today. There are two ways people find interesting blogs – via links on other blogs, and via search engines.

Especially the some of my more technical posts sometimes don’t get much play up until weeks or months after being published. People who comment on them usually found them via Google and either found them useful or want to correct my mistakes or miss-assumptions – which is great. Even silly shit often gets hits long after I forgot about it. Case in point the silly Magic the Gathering joke I posted last year. Someone posted a comment there requesting a pussy version of the card.

Well, your wish is my command:

Get it?

While I was at it I decided to create a PG-13 version of the original card to show that I do think of the children and all that shit. Or perhaps this makes the joke more subtle? Or more stupid? I don’t know, you decide:

PG-13 Version

This is all I have for today. Enjoy your Memorial Day weekend! For those of you who live outside the US of A, this just means we get the Monday off. There will be a Monday post though, unless I’m especially lazy this weekend. :)