Dec 30, 2009

Bees in Space, or story of my first freeware game project


It was around five years ago when I decided to try making a small game project on my own and publish it on the internets as freeware.

The reason was that I wanted to experience myself a "full" game development cycle in miniature.

And for fun, of course.

Probably the end result is not such a big deal, but I've certainly enjoyed the process and learned quite a bit from it. Actually doing the things, no matter how small they appear, gives that invaluable insight into their very nature, which can not be gained otherwise. When those small, non-uniform (and often beyond the boundaries of one's present competence) things form a complete whole, a closed loop, then this insight may get even more eyes-opening.

At least that's my feeling about it, in the end.

So now, after five years I've suddenly realized that it was not that bad, after all, and it might be a good idea to reflect on that past thing. Just for fun, again.

Picking a theme
The old-school game called Hexxagon was a primary inspiration for that. It was very tempting, of course, to start something grand, like Diablo or GTAIII clone, but that would obviously defeat the whole purpose of trying to finish the game and see what happens after that.

Being as simple as it is, it still involves quite a bit of work in different areas of programming, gameplay design, user interface, art, "marketing", maintenance and support etc - even though every problem here is a toy one, as comparing to a "real-life" game project.


The Game

Essentially, it's a zero sum, deterministic two-players game, somewhat similar to othello.

In it's simplest form AI for such a game is using minimax algorithm, quite often with alpha-beta pruning optimization, to search the game tree, depth first, to a certain level (or until the time limit is reached).

There is quite a bit of research in this area, with a lot of heuristics proposed to improve the "smartness" of the evaluator and game tree search. They would be certainly interesting to try implementing, but as soon as I've got the basic minimax with alpha-beta pruning working, I decided not to bother with this for the time being.

Again, for the sake of being able to work on other things and finish the game.

The board evaluation procedure was dead simple - it was the difference between the one's and rival's balls, the bigger the better, weighted together with the possibility to move, based on some simple heuristic, details of which I don't remember.

The "board" was represented as a bitmask, wrapped by rows, with bit being set if there is something in the corresponding cell (with "something" having different meaning depending on the context), and the whole board state was represented as a triple of bitmasks: one for black balls, one for white balls, and one for empty cells.

Then the bulk of operations/queries on the board state can be conveniently/efficiently done with the bitwise operations.

This, I believe, is called "bitboards", and is quite common trick when programming similar two-player games.


The Engine
I admit that quite a bit of things here could be done in much simpler way, especially in context of such a simple task at hand.

However, in retrospective it does not look that bad. It was certainly good learning experience, and some of the engine design decisions taken seem to have saved quite a bit of time, which would be otherwise wasted doing boring and repetitive things manually and then fixing all the mistakes done in the process.

Few of the things, in no particular order:
  • Game-specific code was minimal and separated from the rest (an "engine" code)
  • The engine code itself was quite modular and layered, different layers were communicating through the interfaces (for example, widgets are using the sprite manager to display sprites, which is using the renderer interface to draw the textured quads, and the renderer interface can have separate implementations for different graphics APIs - I used to have two of them dx8 and dx9). 
  • Sprites were packed into "packages", using custom format, every sprite was cut into power-of-two chunks in a quadtree, and then those chunks were laid out in runtime on the surfaces in the texture memory cache. There was a custom C# tool which did the packing of the sprites, and generating of the font packages as well.
  • A poor man c++ reflection system (using macro and template tricks) for the classes, derived from the "base game object" class, which made it possible to automatically serialize object hierarchies in text/binary format.
  • Custom text format for representation of the object hierarchies in "scripts". I used XML at first (because I knew that rolling your own is a sin, and XML is the answer), but it turned out to be extremely ugly and hard to edit manually. So I did roll my own (which I called JML), using flex/bison, and it turned out to be not as bad as they said.
  • There is a "data binding" mechanism in scripts, the idea I've borrowed from Qt back then, and then eventually Microsoft has stolen it from me and implemented in WPF :)
  • I've got a set of ad-hoc python scripts which would generate project files (.vcproj/.sln, .dsp/.dsw). Every module had a text file called depends.txt, which used a simple syntax to describe which other internal/external libraries it references. The python script would then walk the source tree, find these files and do the generation. This way I could experiment with different physical source code layouts and manage dependencies explicitly without tinkering for ours in Visual Studio property dialogs.
So, for example, the main menu dialog script would look like this:
dialog "MainMenu"
{
    // ...
    picture "Logo"
    {
        skinpack        = "logo";
        extents         = { 40, 30, 330, 100 };
        stretch         = true;
        skinframe       = 0;
    }

    shortcut "EditorShortcut"
    {
        Key             = "E";
        Action          = >>MenuSystem.OnEditor;
    }
        
    button "ContinueGame"
    {
        text            = L"Continue Game";
        extents         = { 290, 160, 270, 48 };
        font            = "font_menu";
        fontheight      = 48;
        fgcolor         = 0xFF49CD49;
        shadowcolor     = 0xFF11FF11;
        hoverfgcolor    = 0xFF88FF88;
        unpress         = >>MenuSystem.OnContinueGame;
        visible         = <<Core.Game.HasPlayers;
    }
    // ...
}
Design

It was obviously programmer art, from the beginning to end.

I've found a few free sound samples on the internets, painted basic game screen elements myself in gimp (that included the space bee from the main menu screen).

I've used Comic Sans MS in user interface, which is a trademark of amateurish design.The interface itself is not consistent, not intuitive, badly laid out and uses a horrible color palette.

So it's hard to call it a "design", rather an inconsistent pile of placeholders. Which I did realize back then, but again did not overfocus on that, hoping that eventually I might get a help from someone who has a taste and gets interested in this.

The Editor
I've decided to add a certain "non-linear" twist to the original Hexxagon gameplay.

The player would progress through the sequence of "levels", which get more complex in terms of the original board setup (the "smartness" of the computer opponent would still remain the same, as it is essentially the same limited depth/time minimax solution tree search). When certain level is won, it opens one or more new ones, and it's up to player to pick which one to play next.

So, it is not necessary to win all the levels in order to "beat the game". The levels form a kind of a graph with nodes being the particular board setups. And if there is an edge from a source level to destination one, it means that destination is available to play after the source is won.

While all the levels and transitions between them could perfectly be "designed" in Notepad (and probably it would be a better idea to keep it that simple), I've decided to make an "in-game" editor for those.

Which turned out to be pretty rad in the end:



One could pan, zoom the whole graph, select node groups, move them around, double click on nodes and edit them etc.

The whole game, when zoomed away, would look like a big DAG, where the leftmost node here is the starting level, and the rightmost one is the end level, which has to be won to finish the game.

Release
The testing (including the focus testing) was done by myself and my friends. The game was obviously far away from being ready, but at least it was somewhat playable, so I decided not to wait an eternity "til it's done" and publish an early version.

I used NSIS for the installer, and was quite happy with that, as the whole distributable size was below 1Mb, which was pretty good for the downloadable game.

Funny enough, I clearly remember myself not counting the things like making an installer or the game's web page as work, which has to be taken into account.

Turned out, that even with the help of such great tools like NSIS or Inno Setup (which make life much, much easier in this regard), it still took considerable amount of time, especially since I did not have much previous experience in these areas.

So that was another good lesson to learn.

Evaluation
I have submitted "version 0.4" to tucows for evaluation and basically forgot about it, because the evaluation queues are pretty long, and it can take a few months before your software gets there (well, it used to be the case five years ago, but I presume it's not very different today).

So it was quite a surprise for me to finally get my game reviewed and rated... with whooping three cows! Which according to the tucows folks themselves means:
If your application receives a three-, four-, or five-cow rating, congratulations! As you'll see by reading the Ratings Guide, this is no small feat. You are in the company of some of the best programmers in the world. We receive hundreds of requests each week for inclusion in the Tucows software library. The fact that you scored in the three-cow range or higher has earned you a spot on our site. This is a sign that your product is among the best of its kind.
See? My little game is among the best of it's kind!

Seriously, though, I've got an extremely good feedback in an e-mail soon after, where they were giving a detailed explanation about how did they evaluate the game, separately on topics of visuals, sound, fun and longevity, user interface, easiness to grasp etc.

Obviously, graphics, sound and user interface were quite far from being the strongest sides, and that was very expected.

Another weak side was perceived complexity of the game, and most of all that it is very hard for a new person to figure out what are the rules of the game and how to play in general (even though the rules are quite simple).

It was also quite expected, as I was observing it myself during my "focus tests", and was going to "fix" it in later versions by making a tutorial (quite frankly, I had to postpone it to  "later versions" because it also turned out harder than I was originally expecting).  

But still, I've got my three cows and that was quite a revelation.

Aftermath
Well, there is none. Soon after I've decided to change my job and move to live in another country, so it was left where it was, at version 0.4.

I did not finish the game, there were quite a bit of things to do yet, but still managed to experience one iteration of the possible game project life cycle, from beginning to what can be called "end".

It's not on tucows anymore, but still is downloadable on the internets.
I've also made the source code public, and it was available until my hosting period has ended.

But all in all, being a failure it is (i did not really finish the game, and it did not find its players), it still was a success to me personally, in the experience it has brought.

Jul 2, 2009

Kozma Prutkov, one of the brightest minds in the software development

Alright, that's quite a stretch. Not only Kozma Prutkov is by no means a software developer (he was a writer, one and a half centuries ago), it's also not a real person (but rather three people behind a single fictional name).
The reason that he's not that well known is that it appears to be quite hard to translate his aphorisms, which are hugely based on the wordplay. Which reminds of what Douglas Hofstadter said about Gödel, Escher, Bach translation:
There were a million issues to consider in any potential translation, since the book is rife not only with explicit wordplay but also with what Scott Kim dubbed "structural puns" - passages where form and content echo or reinforce each other in some unexpected manner, and very often thanks to happy coincidences involving specific English words.
And I think it's a shame in case of Kozma Prutkov. Those little revelations, hidden in a generally tongue-in-a-cheek perls of wisdom, in some ways defined my own world-view long time ago, and I am even more amused to see how do they manage to take new forms when I return to them today.
Fortunately, some people tried to translate it, anyway.
The good thing about this kind of ambiguous and satirical aphorisms is that one is free to put into them whatever meaning he feels fits better himself.
However, in this particular case I was really impressed to discover so many empirical truisms of the software development, which can be directly mapped upon Kozma Prutkov's aphorisms.
Well, this discovery is quite a pleasant exercise on its own. People tend to get enjoyment in finding familiar patterns observing seemingly unrelated phenomenas ("We experience delight when we recognize patterns, yet we're also surprised by them").
So, I will dare to cite some of them.
To be honest, my original plan was to append my own thoughts/associations (and possibly explanatory links) triggered by these sentences. But then I understood that most of those thoughts are pretty obvious, and besides that would possibly rob some people from having a kind of enjoyment I had while discovering these associations themselves.
So for only the couple of the first ones:
  • Do not cut everything that grows.
  • Buy a painting first, and then frame it.
You are not gonna need it
  • The first step of a baby is the first step to his death.
Most of the software designs are deemed to die much sooner than one would expect. But chances are that they will give a birth to the next generation, and many others after that. One has to consider it when designing the systems.
Now, I challenge you to find your own associations for the rest:
  • Many things are incomprehensible to us not because our comprehension is weak, but because those things are not within the frames of our comprehension.
  • If upon a cage of an elephant you will see a sign reading: "buffalo", do not believe your eyes.
  • When casting pebbles into water, look at the ripples being formed thereby. Otherwise this activity will be an empty amusement.
  • Never run to the extreme: who wants to dine too late today takes chances to instead breakfast tomorrow, early in the morning.
  • What other people can say about you if you can't say anything about yourself?
  • Trace everything back to the beginning and you will understand a lot.
  • New boots always pinch.
  • Nobody will embrace the unembraceable.
  • There is no great thing that would not be surmounted by a still greater thing. There is no thing so small that no smaller thing could fit into it.
  • Look in the root!
  • Better say little, but well.
  • People's memory is like a piece of white paper: sometimes it writes well, and sometimes bad.
  • What is the best? - Having compared the past, link it to the present.
  • If you have a fountain, plug it up. Let the fountain too have a rest.
  • Only reason on what your notions allow you to discuss. Thus, knowing nothing about the laws of the Iroquois language, can you pass a judgement on it that would not be ill-founded and stupid?
  • Having lied once, who will believe you?
  • Looking into the distance, you will see the distance; looking to the sky, you will see the sky; looking in a small mirror, you will only see yourself.
  • Where is the beginning of the end that comes at the end of the beginning?
  • Do not seek for unity in the whole, but rather in the uniformity of distinction.
  • We don't care for what we have, we deplore what we have lost.
  • Every thing is a manifestation of infinite diversity.
  • Who prevents you from inventing waterproof gun-powder?
  • When looking at the sun, squint your eyes - and you'll readily discern the spots upon it.
  • If all the past were present, and the present existed along with the future, who would be able to distinguish, where are the causes and where are the consequences?
  • Virtue is an award for itself. A man excels the virtue, if he serves never receiving an award.
  • The harm or benefit of an act depend on the combination of circumstances.
  • Things can be great or minor not only by fate's will, or contingency, but also by every person's notions.
  • Sometimes, zeal overcomes even the common sense.
  • When it concerns art, every tailor has views of his own.
  • People could not stop living together, even if they walked far away from each other.
  • If you want to be happy, be!
I'd be really happy to hear from you, and compare it with the picture in my own head.

Jul 1, 2009

There will be no substitute for COBOL

I've bought that book quite some time ago, and only recently managed to fetch it from my bookshelf (did I already mention that I am a book junkie)?..
Being a second edition of the classic book, some kind of a new thin wrap around ten years old candy, it still manages to sound insightful in some places.
Well, that candy is not just old, it's ancient (first edition is 1990, second one is 2005)... well, at least from the perspective of everchanging software development world.
Still, I'm done through the bigger half of that, and I am not regretting doing that so far. However, there was one part which has turned out to be mind provoking in a somewhat unexpected way:
But there's something else happening here, too. With all that heavy use of COBOL in the business world, where money is to be made by cutting costs wherever possible, why haven't at least a few companies switched to something better? No, I don't mean 4GLs. I mean 3GLs that provide the same capabilities as COBOL. Why haven't the innovative, advanced firms started using a better COBOL?
Here's where I want to get to the real point of this essay. I want to take the position that people aren't switching away from COBOL because there really isn't anything better to switch to.
Heresy! Ignorance! Stupidity! I can hear the silent cries from my reading audience now. But wait, there is method in my madness, and I would like to explain.
...What other tools have been invented to address [the business] problem domain?.. That better way is still COBOL. That's the gist of my heresy.
Does that mean that I think COBOL is a good language?
Emphatically, my answer is a resounding "No."
...Why? Why is this ancient and clumsy language not replaced by something that does its job more cleanly? Because, I would assert, the research world which might create a better language is so disdainful of business application software in general, and the COBOL language in particular, that it is blind to the thought that a major research challenge lies in defining a better COBOL.
COBOL, eh?
Now, certainly, COBOL is out from the scene, and that's something Robert Glass acknowledges himself (what a surprise!) in that "special 2nd edition chapter". But that's not the point.
"COBOL" is just a label, and if one blurs it away from the picture (together with probably some other vintage things), the pattern extracted seems to be very familiar.
As it usually happens with my poor mind, when it's being provoked by something, I see a reference to several (possibly non-related) things at once:
  • That Deja Vu feeling one gets often when reading discussions about the present state of the technology. So, does C++ looks like COBOL in this context?..
  • And what about that too well known Tim Sweeney talk?..
  • And what is a "programming language", after all? Is it programmers' or users' thing, or maybe both?
  • Is really software development history developed in a spiral (pretty much like the human history)?
  • What is the point in developing the new "programming languages"? It seems that users do not care about languages, they prefer working software.
  • And what about our's today arrogance? Like in, "C++ is going to stay here for a while, because it's the most efficient language, and computer games do demand performance".
  • Could it be, that business value of the software is higher if users have more control over the way this software is applied to their domain?
I mean, yeah, of course. C++ is not COBOL. And Java is not COBOL. And C# is not COBOL. And F# is not COBOL.
Those are bloody modern and mainstream.
Or are they?..
Or maybe they are just an another coil of the Spiral?
What we are, then? Are we the pivot of that spiral, or just a part of a coil?
All our experience, knowledge, mental models - all of it can happen to become nothing in the long term.
So, what do we do to prevent that?
Learn COBOL, of course.

Jun 29, 2009

Programmer's workout

There was another metaphor concerning the programmer's skills development, which I personally feel is quite sound.

We had this discussion with the fellow programmers, about learning new programming languages and technologies, and generally doing the work which is not just something that you are not really get paid for, but also you don't get any visible benefit at all from doing it. You don't produce any measurable value.

As in, for example, writing a throw-away code in some new programming language just for the sake of learning that language itself.

The notion of "throw-away code" turns out to be more painful than it could be expected: quite often people get extremely personally attached to their designs, algorithms, code, and time spent on some certain activity in general. So, how come one can even remotely be attached to the throw-away "garbage"?..

That takes different forms and flavours: one feels sorry that he had spent years in the university studying something which does not seem to help to find a job, others are reluctant to get interested in anything outside their own area of expertise ("we don't have time for that, it's not our job"). In the case of programmers, in particular, it often turns out in discarding any kind of mentioning related to the technologies, programming languages, libraries, development methodologies, practices which appear to be unrelated to their job.

That's not just cognitive biases in action (which I wholeheartedly confess in being affected by myself), but also pure and perfectly reasonable human behavior, which does it's best to optimize the actions taken by the human being.

So, why would one voluntarily do anything, which is deemed to be discarded almost instantly?

Now, here is where comes a programmer's workout metaphor into action.

Consider yourself going to the gym, and spending some hours per week there, doing the exercises. What you do there, that "weight's pumping" is nothing else as taking heavy things at one place and lifting them up many times during some period of time, just to put those weights back to their place in the end.
So, without any doubt, whatever happens there is:
  • boring
  • hard
  • time-consuming
  • does not give any visible outcome in the end (those weights end up in the original position).
What's the point, then?.. What is the point in doing something, which is barely enjoyable, and gives no visible outcome immediately?

The stock answer would be that benefit is invisible, long term, and whatnot.

But I honestly think that there really is no point, unless you can tune yourself into the state, where you can consistently come up with short-term achievable goals, and furthermore have the feeling of the success every time those goals are achieved.

So, you've pumped up that thing 12 times two days ago?.. what about adding a couple of kilos on top today and do the same? What about going an extra mile?.. Can you spend 10 more minutes in the gym today?.. You can't?.. Well, it's fine, who cares, there's always next time to try again.

You make this small game out of seemingly boring endeavor, and then eventually, unnoticeably you get to the point where you get used to the process and you start to like it.

You start to enjoy it.

And then, what happens next? The forementioned long-term success comes, that's what happens. You don't really feel it "suddenly coming". At that point it's already with you, and it's hard to tell a difference. But it's there. You see it when you start looking at your old photos. Or at your old code, for that matter.

And even if it does not do it that soon - who cares, that was just a game, right?

So, you get a positive outcome out from doing those throw-away exercises, producing the value from nothing.
What really happens is building a solid background, be it physical or intellectual.

The only problem is that this building can be very routine and hard.
In this case helping yourself into making it a game can help a lot.

Jun 21, 2009

Pragmatic Thinking&Learning by Andy Hunt

So, the book was on my wish list for a while, and then I've suddenly bought it.

And read.

 Fortunately, it's not too big and not too mind-pressing, so it did not fall a victim to my occasional bibliomania (yes, I've bought a few other interesting books, some of them still not finished, such a shame). It was a good read, overall.

Sometimes very insightful, even though sometimes it was giving impression of the text being added just for the sake of keeping the format of the book (which otherwise could be a good article).

 The style is very accessible (which is pragmatic trademark), there are anecdotes and humorous remarks here and there, which makes for easier reading.
...a controversial study done in the United Kingdom noted that if you constantly interrupt your task to check e-mail or respond to an IM text message, your effective IQ drops ten points. By comparison, smoking a marijuana joint drops your IQ a mere four points. Whatever you do, please don't do both.
However, some things are abused a bit, in my opinion. For example there is too much fuzz around Dreyfus model, or around brain's L-mode/R-mode. To the extent, that sometimes it gives an impression of the marketing speech, rather than revelation, which most of the pragmatic bookshelf books traditionally are. Still, I think the book was a good money investment. Interesting points I've got from it:
  • There is no golden rules to follow in the software development, everything should be considered in the context, i.e. which systems are there, how they interact (in explicit or hidden ways).
  • The role of "subconsciousness" in the problem-solving should not be underestimated (that's w.hat is called "R-mode"), as it tends to see "the big picture", and has generally access to much bigger amounts of knowledge.
  • Experts, the ones which are true masters of their profession, rely deeply upon "intuition" to take decisions. Intuition, as ephemeral as it might sound, is nothing else as the ability to access all the knowledge and experience packed into non-linear way deep inside one's mind.
  • One does not just "switch to R-mode" to solve complex problems. It's proper interaction/switching between L/R modes what is important.
  • One can "train" oneself to operate more efficiently on the knowledge access inside the brain (this includes developing of the R-mode).
  • It's not only that learning constantly is important, also the way learning happens matters a lot. There are ways to make cognition more effective, such as mind maps, collaborative learning, exploration, playing, engaging metaphors and analogies etc.
  • It's important to maintain diversity in the personal skills, trying to learn thing which might seem "irrelevant" to one's profession.
  • Stress kills cognition, positive thinking is important for being able to use the brain effectively.
  • Failure is important and inseparable part of the learning. One has to embrace failure as the opportunity to gain the experience and to stretch the boundaries of the cognition. On the other hand, it should be safe and non-expensive to fail as often as possible (because stress kills cognition).
  • In the 5-tier Dreyfus model (novice, advanced beginner, competent, proficient, expert) applied to the programming skill, most of the people are on the advanced beginner level.
  • Software documentation is not as important, as documenting process.