Skip navigation

Category Archives: programming

New year, new tricks. In this post I’ll explain what Freekick has been doing for the last two months. The main events include rewriting Freekick in C++ so that it finally matches the Haskell version feature-wise, as well as gaining a bit of experience in using the associated tools and libraries. Before I get to that, let me first write down a brief summary of the last year, and of the blog thus far.

In April I wrote the first post announcing the beginning of the project, wondering which language and graphics library to use. The decision was in the end to go for C++ and Ogre. I was also preparing CEGUI as the GUI library. The build system was make, the version control system used was Subversion (if any).

In May I got to physics libraries and decided to look at ODE instead of Bullet. Soon after that I’d let the physics and graphics digest for a while and learn Haskell instead as a tool for AI programming.  Back then, there was no real code written for the project yet.

In June I had learnt the basics of Haskell and was using it to program some of the first things in Freekick.

In July the very basic design of Freekick was slowly getting clear. The plan was (and is) to split the game to different processes and use a server-client model. I went on programming the server and the AI in Haskell and played with the thought of writing the client in Python. I also started getting VCS conscious and mentioned darcs for the first time.

By August I had gotten as far as programming some multithreaded networking in Haskell, as well as doing some nice experiments and tests with neural networks. While the networking part was directly a part of Freekick at the time, I haven’t integrated the concept of neural networks with the project yet.

In September the very basic structure of Freekick, including the server, AI and a client, was finished in Haskell and the version 0.0.1 was released. The client was written using SDL, the primitive physics for the server was done without external libraries and the AI was a simple decision tree.

In October the negative sides of Haskell were starting to become clear, mainly being problems with the performance and problematic use of C++ libraries. The decision was to write a new client in C++ that uses Ogre for graphics. Implementing the data structures (classes) in C++ for the client also makes writing the server in C++ not such a big step.

In November the new client was finished. As it became clear that the performance problems had more to do with the Haskell server than with the client, the decision was to rewrite the server in C++.

In December I didn’t have the time to write about it, but I was busy rewriting the server in C++. This included updating the protocol between the server and the client as well as learning object oriented design.

And now, in January, it’s time for a post again. The C++ server is running, and the preliminary AI is finished too. As there were some updates to the Freekick protocol that broke the backwards compatibility; the old Haskell programs (server, SDL client, AI client) would have to be updated to match the new protocol in order to be able to work with the newer software (maybe I’ll get to it on some rainy day).

As there are some difficulties finding a public code hosting site for darcs repositories (and darcs seems to have some other problems too), I went for another RCS, namely git. I too am one of those who don’t want to go back to centralized SCM after seeing the other side, and git seems to fit my needs perfectly. The Freekick code can be found at GitHub by the way, at http://github.com/anttisalonen/freekick/tree/master. If you want to compile and run it though, there are some external dependencies (notably Bullet and Ogre) and the build script probably isn’t portable yet. If you run into problems, drop me a note.

As a side note, I also wondered which build tool to use for the C++ version of Freekick (for Haskell, Cabal is the excellent build tool, while C++ has a lot more options). The two strongest candidates were CMake and SCons, and in the end I went for the latter. The build tool for Freekick has the seemingly complicated task of compiling and managing a few libraries and applications, preferably comfortably configured in one configuration file. By now, my SCons build script (SConstruct) has become about 150 lines, but it does everything I want it to and how I want it to. The level of documentation for SCons is also excellent.

Now, a few words about implementing Freekick. First of all, even though C++ is more comfortable than I previously thought, it’s still far away from Haskell. My impression is that, thanks to the Boost libraries, you can use most of the nice things that Haskell has (e.g. tuples, lambdas), and everything will run slightly more efficiently than in Haskell, but there’s a lot more code to write and the code is a lot less elegant and a lot more verbose than in Haskell. I guess the better control of CPU cycles and bytes of RAM is worth it.

An interesting thing to note is that it took for both Haskell and C++ about three months to implement the basic functionality of Freekick. The comparison is unfair; I had just learnt Haskell when I started programming Freekick with it, while I’ve had previous (albeit now rather obsolete) experience with C++. Also, when I programmed Freekick the first time, the basic structure and design was only barely clear to me. With Haskell I had to program my own primitive physics engine, with C++ I used Bullet (which was about just as troublesome). The Haskell graphical client was easily done in SDL, while the Ogre client was a bit more work (though using Ogre is actually quite fast, easy and fun – signs of an excellent library). However, in the end the difference in development times wasn’t drastic, which shows to me that C++ really seems to do the job of evolving to a higher level language with time pretty well.

This was also the first time that I’ve actually done some object oriented design. It’s actually quite fun. The constant shuffling around with the header and cpp-files and the verbosity of it all is something I wouldn’t miss with Haskell, and the generic programming and code reuse that OOP offers is still light years away from the level you can find in a functional programming language. Still, C++ is on any account usable and I really need those cycles and bytes. Hopefully in a few years I can use a language that is as elegant as Haskell, while still maintaining the perceived efficiency of C++.

The next things to do with Freekick include relatively small improvements to the server (better compliance with the rules of the game), to the AI (it’s really quite primitive at the moment) as well as to the client (controlling a player and some small graphical enchancements). After that the next task is to go and implement the bigger plan, i.e. the game around the match – organizing the matches into cups and leagues.

It’s time for a small post again. I haven’t updated my blog for a while, but for a reason: there hasn’t really been anything interesting to write about lately. Don’t worry, I’ve been working on my project, but rather implementing it than designing it. The last time I wrote about AI and mentioned it’d be the next thing to implement for Freekick. Well, the basics of AI are there, as well as the basics of everything else (server + client + the organizatory part). I’ve spent the last month writing the AI, writing a client (i.e. a window to the soccer pitch) and making sure the thing doesn’t crash by itself. Sounds like a 0.0.1 release, doesn’t it? Yeah, we’re that far already.

To the disappointment of neural network fans I haven’t implemented them at all in Freekick AI, not yet. The basic structure of the AI is slowly coming together, and when I can concentrate on the details, I’ll try and make some use of neural networks. At the moment, however, the AI follows simple logic for decision making that will be refined later. Having a simplified AI at this stage is helpful because it lets me concentrate on figuring out the bigger picture of the AI functionality.

The current AI is roughly split into two parts, one that defines the possible actions and another that compares these actions with each other and chooses between them. Here, defining the possible actions also includes a set of helper functions such as for finding the best spots on the pitch for scoring or the chances of a successful pass to a teammate.

Splitting the AI code like this makes maintaining it easier than if it was one bloated, monolithic monster. Improving the code should also be simpler in the long run, because if the two parts only communicate via clearly defined interfaces, one part could be swapped or reworked without interfering with the other part. This way I can first make things run with simple logic and when the AI starts to seem too stupid replacing parts of it with, say, neural networks shouldn’t be a big problem. At the moment, though, the AI code is rather transparent (with 10 files and 400 lines of Haskell code), but when the code grows, it will be necessary to make this division even clearer.

I then went on to write an SDL client for Freekick. It’s actually a bit early to call it a client, since there is no single player (nor multi player) mode and the client doesn’t control a player but merely spectates the match, but for now it’s enough to see what the AI is doing. A simple single player mode with some awkward controls will be added later. The client is very ugly, though, and thereby reflects my artistic skills rather perfectly. Here’s a screen shot.

Soccer in all its beauty.

Soccer in all its beauty.

Here it probably starts to become clear for everyone why I wanted Freekick to be so modular. The client is just a client, its duties are merely receiving the match status from the server and displaying it as it sees fit, as well as taking input from the player. It can be exchanged or rewritten in another language without the need to touch the rest of the game logic. I’m also planning on writing an ncurses client for use in non-graphical environments (as if the SDL client wasn’t ugly enough).

As for the server (i.e. the code that handles the network, communication, enforces soccer rules and world physics), it’s running with no major problems. Minor problems include network code that has problems handling disconnecting clients and relatively inaccurate physics, but for now it’s adequate. Probably the biggest thing that differentiates Freekick from a real alpha version of a very ugly spectator only soccer game is (along with the fact that the match actually never ends) that there is actually no connection between the “organizatory part” (i.e. choosing two clubs that play a friendly game against each other, or starting a knockout tournament) and the actual, viewable match.

This all means there is still some more work to do before Freekick could be considered usable. But in the spirit of “Release early, release often” I’m giving you the code (written in Haskell as usual) already anyways. If you have darcs, the easiest way to the code is “darcs get http://code.haskell.org/freekick/”, but there are also tarballs of the code as well of a binary version (x86, Linux) at http://finder.homelinux.org/freekick/files/. With enough playing around one might be able to start the thing, but I’ll write here the way it’s supposed to work anyway. First you start the server (“physics”) with a matchdata file (“matchdata.md”) as parameter. Then you start both the client and the AI, which both connect to the server. AI interprets the information from the server and sends the desired player actions to it. The client displays the players in all its SDL glory. And voila, you’re witnessing a soccer AI experiment.

From the issues mentioned above, the ones I’ll be concentrating on in the near future will be the ability to actually play the game and control a player, finishing up the match flow (i.e. ending the match at some point), and tying the organizatory part together with the match part. After these steps, it’s probably time for some polish, like a main menu, configuration options and a prettier client. As for the 0.0.2 release, it’ll be available, soon. I’ll keep you posted.

It’s been quite a while (a month, actually) since my last post. That is not a sign of laziness, however, on the contrary; I’ve been busy playing around with Haskell and Python lately. In the last post I wrote about taking a break from Ogre to see what this thing called functional programming actually means. I think I’ve come closer to figuring that out in the past month.

Haskell really is quite an interesting language. (There’s a little tutorial showing some very nice aspects about Haskell here.) I started learning it by going through the tutorials available at haskell.org, and especially walking through Yet Another Haskell Tutorial, a mighty PDF book that explains all the major aspects of the language. I really had problems figuring out how to simulate state within Haskell, and the State monad didn’t really make it seem much easier. After going through the source code of some Haskell projects such as Frag (a 3D shooter) and LambdaHack (a roguelike), I finally started to slowly understand how a bigger project in Haskell could look like. So, to start from the bottom and work my way up, I made a blackjack and a video poker game. They’re text based but helped me figure out how to program some simple things in Haskell. (If you’re interested, you can find the sources + binaries here, MIT licensed.)

After finishing those two little cute things, I wanted to tackle the real prob– project, my soccer game wannabe. So I figured out how to read XML files in Haskell to serialize some data. As can be seen from my card games code above, I didn’t quite understand all of the monad concept (and still don’t), which turns out to be a pretty serious drawback when using Haskell to program in a bigger project. As Haskell is a purely functional programming language (one cannot emphasize that enough, I guess), doing something like file I/O without monads is impossible, and without advanced use of monads very tricky once things start to go wrong. The result is that if there is an error somewhere in the XML file to be parsed (my program doesn’t do any validation at the moment) or a bug in a function parsing the XML file, the bughunt may prove to be a very wiery task. So the next thing to do before I go on programming with Haskell is to learn more about monads. Luckily there are a lot of tutorials to the subject on Haskell.org. After that, the smartest thing for me to do would be a rewrite of my XML serializer.

My XML serializer could handle some data, but as I wrote the few XML files manually to test with I realized there is still a lot to design regarding the structure of my soccer game. And in order to see if my design would work, I needed some test scripts to create some XML files that should be able to work with each other. Since creating XML files by parsing text files and adding more or less random data to them is quite an I/O intensive thing to do and since I just wanted to quickly have some scripts that would do the job for me, I decided to do the job in Python instead.

Now, I wasn’t very experienced in Python (to be precise, I had programmed about 20 minutes in Python before this), but I still had somehow had the idea that programming in Python would be extremely fast and easy, especially for such not-very-large programs. After a few days of fooling around with Python and working with the excellent Python lxml library my scripts were finished and it seems I have proved myself correct. Even though my creations look quite terrible (if a Python fan saw my code he’d probably get his eyes hurt) and are written in a procedural fashion reminding me of my BASIC times (maybe Djikstra had a point after all) they do get the job done in the end and I think I can even understand the code.

There are some things I don’t like about Python (mainly the dynamic typing and the fact that is interpreted) and it surely doesn’t fit well for CPU intensive code, but for my XML creation scripts it’s perfect. Python also seems to be very easy to learn (just like Guido wanted it), and my scripts are a living (working) proof for that. I still keep learning Haskell (of course) since it seems even more elegant, faster and is purely functional, but the small Python excursion showed me I should keep clinging to the “right tool for the job” paradigm.

So, what now? Well, there’s the topic of monads to look at. After that I should do a rewrite of my XML serializer. (As boring as it may sound.) Then, well, I should be able to go on with my soccer game project, but with monads this time… We’ll see how it goes.

Yup, I’m still here. I’ve been going through some more of the Ogre tutorials and have reached the first intermediate ones. Things have been going well and I’ve understood the material, but the problems started when compiling the examples making use of CEGUI.

I mentioned before that using Ogre is designed to be highly modular with Ogre itself providing only the graphics engine. The Ogre tutorials also show how to implement a GUI functionality, which is basically required not only for the menus, but also for any kinds of 2D things you want to show as well as the mouse cursor. The tutorials use one of the few available GUI libraries, CEGUI (Crazy Eddie’s GUI), which is apparently also one of the most popular GUIs used with Ogre.

Using autotools, my first quest was finding out how to update my configure.ac file in order to be able to include the CEGUI libraries as well as the Ogre interface for CEGUI. In the end, these lines were necessary to add:

PKG_CHECK_MODULES(CEGUI, [CEGUI >= 0.4])
AC_SUBST(CEGUI_CFLAGS)
AC_SUBST(CEGUI_LIBS)

PKG_CHECK_MODULES(CEGUI_OGRE, [CEGUI-OGRE >= 1.2])
AC_SUBST(CEGUI-OGRE_CFLAGS)
AC_SUBST(CEGUI-OGRE_LIBS)

Notice the name of the interface is CEGUI_OGRE (with an underscore), while the name of the actual library package is CEGUI-OGRE (with a minus). Using a minus instead of an underscore or vice versa made either my configure script or make to return error. I’m not sure if I did everything as I’m supposed to, but to me that was the only way to make progress. To me it sounds like a pretty bad naming convention, but if I see it wrong, feel free to correct me.

The first problem with the actual compilation I had was due to the fact that I had first compiled Ogre, and CEGUI afterwards. Big mistake, since Ogre has built-in interface for working with CEGUI, which is only compiled in if the Ogre configure script finds CEGUI, which of course was not the case for me. Browsing through the Ogre forums to figure out what went wrong, recompiling and reinstalling Ogre fixed that eventually.

The next problem was that while compiling Ogre code using CEGUI I kept getting the following error message:

/usr/local/lib/libCEGUIOgreRenderer.so: undefined reference to `CEGUI::Exception
::Exception(CEGUI::String const&)’

Now, libCEGUIOgreRenderer is actually a part of Ogre, which apparently doesn’t play well with CEGUI. Huh? Sounds like a version mismatch, and after a lot of reconfiguring, recompiling and playing around I could finally make my code compile using not the newest stable CEGUI 0.6.0, but the older 0.5.0.

Note to self: when programming a library, especially when it will be used by other libraries, make sure the class interfaces stay the same from one version to the next. If I really need to redesign the classes, make it a jump from 1.0 to 2.0 (or 0.5.0 to 1.0) or a whole new library.

One might think it works now, but no, that would be a tad too optimistic. I could compile and run my program, but it would crash before actually showing the scene with the following message (delived by Ogre instead of make this time):

Texture: TaharezLook.tga: Loading 1 faces(PF_A8R8G8B8,256x256x1) with hardware
generated mipmaps from Image. Internal format is PF_A8R8G8B8,256x256x1.
terminate called after throwing an instance of ‘CEGUI::FileIOException’:

The error basically means CEGUI wanted to load some content (in this case, an image) but crashed while trying. Looking through the Ogre forums once again, I found a thread (http://www.ogre3d.org/phpBB2/viewtopic.php?t=33103&start=0&postdays=0&postorder=
asc&highlight=ceguiconfig+xsd) advicing to compile in the use of TinyXML library instead of Xerces XML library when building CEGUI. Xerces is the standard XML library for CEGUI, but doesn’t seem to handle all resources that well. It’s actually pretty obvious when you think about it. You almost could’ve come up with that yourself. Lo and behold, after recompiling and reinstalling the code finally worked.

Conclusion: I didn’t really think getting Ogre and CEGUI (or anything, for that matter) up and running would be such a fight, but hey, it’s software, so it has to work somehow, right? And now that CEGUI actually works for me, it doesn’t actually seem that bad. I just make a mental note not to update it, at least not just yet. The building troubles seem to indicate CEGUI or the interface with Ogre is not all stable yet, but it does look promising to me. Luckily the user base for CEGUI with Ogre is large enough that a lot of the problems that do arise have already been discussed in the forums.

PS. In one of my moments of despair I also tried out another GUI library for Ogre, namely QuickGUI, hoping that this one would work better. In a nutshell, the guide for setting the library up told the programmer to make an instance of a class using a constructor that didn’t exist. Looking up the header files, the only constructor that did exist was protected. It was written in the comments that the class is actually a simpleton, although the means of accessing this simpleton was not documented anywhere as far as I could see (the standard getSimpleton() function was not there). Apparently the guide I was reading was for an older version, and the whole class design had been changed since then. I see that as another example showing the importance of design: design your library/application once, and design it well, so that you don’t need to change it afterwards.