Skip navigation

Tag Archives: game programming

It’s been a while since the last post.

This post is to announce a new version of Freekick 3, the latest rewrite of my project of writing a soccer game. It doesn’t have fancy graphics (on the contrary, it’s very ugly), but it tries to provide a fun soccer game to play nevertheless.

This is actually the first announcement of Freekick 3. The previous announcement on the Freekick series was the announcement of Freekick 2. Here’s a short overview of the features.

– A few different game modes, including friendly games, knockouts, leagues, seasons and a mockup of a career mode.

– The team, league and player data is not included, but can be imported to Freekick 3 either from Sensible World of Soccer data files or, my favourite, from Wikipedia. By having a script to fetch all the data from Wikipedia it’s ensured that the data is relatively up-to-date and that there’s a fair amount of teams to play against.

– The AI is improved and may provide a nice challenge.

– You can either control the whole team in the match or choose to just control one player.

You can download Freekick 3 (source) from https://github.com/anttisalonen/freekick3. I’ll show a quick tour around Freekick 3.

This is the main menu (quite similar to Freekick 2).

This is the main menu (quite similar to Freekick 2).

After fetching the data from Wikipedia you have lots of teams to choose from.

After fetching the data from Wikipedia you have lots of teams to choose from.

You can tune the line up before the match.

You can tune the line up before the match.

During a match - about to cross.

During a match – about to cross.

Career mode currently includes a league season along with the national cup.

Career mode includes a league season along with the national cup.

Football league two mid-season table.

Football league two mid-season table.

Fighting for the ball mid-field.

Fighting for the ball mid-field.

Behold, Kingdoms 0.1.0 has been released. Kingdoms is a hobby project of mine I’ve been working on for the past couple of months. It’s a strategy game, where you lead a nation from stone age until the bittersweet end – in other words, a Civilization-like game. I’ve been wanting to write one for a long time, and I’m glad to see it’s doable.

It borrows features from all Civilization games I’ve played: graphics from Civ 1 (because I’m no artist), the configuration file type from Civ 2 (back when it was simple), strategic resources and culture from Civ 3 and (part of) the combat system from Civ 4. By the way, that’s also the reason why I wanted something else than FreeCiv: I find it’s too similar to Civ 2, which was never my favorite Civ game.

Here are some screenshots:

Babylonians vs. Aztecs

A map editor is included

You can get Kingdoms from its web page – there’s the source as well as the Windows binary. There are still quite a few features I wanted to implement but haven’t had the time yet, so if something bugs you, let me know.

About a month ago I announced my then-latest programming project, Star Rover 2. It’s a space flying game written in Haskell, and while programming that was fun and I learnt a lot from the project, it was time to find something else to do. So I started another soccer project, again in Haskell (like in September 2008), but with a bit more Haskell experience under my belt.

And now, after almost a month, it’s time for the first release. The new soccer game is called freekick2, and it’s an open source 2D arcade style soccer game.

If you have cabal, you can install it with a simple cabal update && cabal install freekick2. Here’s a screen  shot from a menu:

The freekick2 distribution includes only a few fantasy teams, but you can use the data files from a Sensible Soccer game for some additional realism.

One lesson I learnt when doing Star Rover 2 is that I should avoid over-engineering like plague, as that was probably one reason why I couldn’t get the first Freekick versions in a releaseable state.

Freekick2 now consists of about 3200 lines of Haskell code, around 1000 more than Star Rover 2, and it’s also a bit fancier, graphics-wise. With Star Rover 2 I used monad transformers to handle the main loop and state changes, which worked pretty well, and I’m using the same technique with freekick2. I still haven’t figured out the whole FRP thing, but game programming in Haskell seems to work out pretty well without.

Things I’ve learnt while programming freekick2:

* Texture mapping with OpenGL in Haskell. To load the textures you need to play around with pointers a bit, which are not really that usual in Haskell. But you can do it, and with the help of some great small libraries like pngload it’s relatively simple in the end. Adding dynamic recoloring of the textures after loading them (to support multiple kit colors) was fun as well.

* Parsing binary data in Haskell. Over a year ago, when I was writing Freekick in C++, I wanted to deserialize the SWOS data files (the format’s known; many thanks to the ones who figured the format out) and I thought parsing binary data sounds like a job for C or C++. The result from back then is about 850 lines long and took a few hours to write. Granted, it also generates some XML. Now I wrote a program to do the same task in Haskell; the result has 250 lines and was written in less than two hours. The Haskell version also includes code for writing SWOS data files – a feature I added just because it was so easy to do. Later, for the freekick-internal data structures, I let BinaryDerive derive the serialization/deserialization code for me. Needless to say, I won’t be doing binary data parsing in C anymore if I get to choose.

* Template Haskell. The state in freekick2 changes pretty often, and is managed in a State monad. I needed a lot of functions of type (FieldType -> FieldType) -> State -> State (like already with Star Rover 2), usually one for each field in a record, and so I let TH generate them all for me. Bulat’s tutorials (links to them can be found here) were a life saver.

* Implementing a GUI with colors, textures and dynamic content, with a tree-like hierarchy for screens.

* Use of the existential quantification language extension for heterogeneous collections. I’ve spent some time with object oriented design in the past, which sometimes leads to object-oriented designs in Haskell, so that something like existential types are needed. In this concrete case, I created the class Sprite, with both the player and the ball implementing it. The easiest way to draw all sprites sorted by depth is then to just put all sprites in one list and sort it. Without existential quantification, I would’ve had to write code to sort the players and then call the draw method of the ball somewhere between the draw methods of the players.

So, programming in Haskell is more fun than ever, and the productivity boost given by Haskell is starting to show more and more.

Here’s the announcement of my latest programming project. It’s called Star Rover 2, and it’s a space flying game. You can fly around in space, trade goods, fight against other ships and complete missions for different governments. It features different difficulty levels, a high score list and several ways for the player to play the game. It’s also the first game I wrote in Haskell that’s actually playable.

Flying between planets

The game itself is quite simple: you start on a planet, and you can buy some cargo if you want before launching into the space. In space, you can fly to other planets and see if you can sell your cargo for a better price. There are other ships in space as well, and you’ll get interrupted every once in a while when coming across one, with the possibility of attacking the other ship. If you win, you get their cargo, and the various governments may have their opinions about the attack as well.

(it looks better in motion :)

Combat in Star Rover 2

As the game progresses, you may earn a reputation among the governing bodies, which leads to new dangers and possibilities. The international relationships are complicated, and attacking a ship of one nationality may not only affect the nationality being attacked but their friends and enemies as well. By playing your cards right you can receive missions from governors, and by completing them you may boost your ranking further.

Captured cargo

The game is quite non-linear; it ends when your ship is destroyed often enough and you are too weak to continue, or when you choose to retire. At the end, your achievements are rated and you may make it to the high score list. Until then, you may choose your activities freely.

You can find Star Rover 2 at Hackage, so if you have cabal, you can install it by running cabal update && cabal install starrover2. You can also fetch the sources from github. As for dependencies, you’ll need SDL, OpenGL and FTGL.

In the beginning, Star Rover 2 was more or less a test of whether I can actually concentrate on one project enough to have a playable game in the end, and I’m glad it’s now reached a state where it can be released. Other than that, I was curious to see what programming such a game actually is like in Haskell, and I’m quite pleased with the results. I started working on Star Rover 2 on my spare time pretty much exactly a month ago, and now it amounts to about 2000 lines of Haskell code. I was a bit worried I couldn’t write a larger project in Haskell, but now I can see how well Haskell scales up to complex tasks. This was also my first project where monad transformers actually came in very handy.

Any feedback and bug reports are of course very welcome.

If you’re planning on writing 3D software in Haskell, here are some tips.

A few months ago I was planning on programming a 3D game in Haskell and was browsing the options for a 3D library. In general, there are a couple of low-level APIs (OpenGL and Direct3D) and a few higher-level libraries built on top of those low-level APIs (OGRE, Irrlicht, and more).  Using a low-level API has the known advantages (fine-grained control) and disadvantages (lots of code to write).

It turned out that limiting the programming language to Haskell is quite restrictive; almost all higher-level libraries are intended for using with C++ (Panda3D being an exception with Python as the intended language; the library itself is written in C++, though). So what you need is Haskell bindings for the libraries. There’s a Haskell binding for OpenGL, which is used for (apparently) all 3D games written in Haskell. A few months ago it was the only option and, if you’re doing anything more complicated than rendering a few models in a scene, it still is.

The problem is that binding a C++ library is rather complicated and basically boils down to either writing C code to wrap the C++ interface and then interfacing the C code in Haskell using FFI or automatically generating the C interface (as well as the Haskell FFI code that wraps it). The latter option was chosen for at least the GUI widget libraries wxHaskell and qtHaskell.

However, a few Haskell bindings for 3D libraries have appeared. There’s a very primitive binding to OGRE written by the author of this post (with examples) as well as at least a start of a binding to Irrlicht by Peter Althainz.  So there appears to be a bit of activity regarding the use of higher-level 3D libraries in Haskell, which is good news, I guess.

One more note regarding the Haskell bindings for Ogre: you can do some simple things like adding models and a camera, and moving them around, but that’s about it, since I haven’t really had the motivation or need to provide support for anything else. The bindings are relatively simple to extend, though, so if you use the bindings and miss a feature, go ahead and let me know.

I wanted to start typing down some things as notes I’ve learnt during the development of Freekick until now before I forget all about them. The first article in the series is about one of the most important things that are different between Freekick and my previous hobby projects: modularization in software.

I first started to understand the importance and the benefits of modularity as I read the great book “The Art of Unix Programming” by Eric S. Raymond, a book I can recommend to every software developer, even those who’ve never used or programmed on Unix. Lacking modularity in my programs was the biggest reason why I had to abandon them sooner or later – I’ve ended up in such horrible situations where tweaking the AI creates a bug in the main menu, for example.

As mentioned in the book, managing complexity is one of the most crucial (and difficult) jobs when developing software. Basically, as long as you can simplify the tasks of the software into more and more smaller, simpler sub-tasks, and organize them so that you always know which parts of the software should be talking to each other and how the talking is done (interface design), you have no problem. If you lose the overview half-way to the project but go on writing code, you probably won’t get it finished.

From a developer’s point of view, some programming languages encourage designing the software top-down, always breaking problems into smaller pieces, and then implementing the software bottom-up. I take FORTH as an example, in which it is near to impossible to write even slightly complicated software without designing it thoroughly in a top-down fashion first. Most languages, such as Java or C, don’t really force you to manage complexity in any way, but merely provide you with the tools.

There are a lot of ways to bind all your software components so tightly together that there’s soon no way to take them apart anymore. One way is having a so called “god class“, a class usually aptly called something like “World” that ends up having most of the code in the project. Other popular ways include global variables, static variables or simply functions that are 1000 lines long, with multiple static variables that are conditionally used for different purposes in the beginning, middle and end of the function. Here are some small hints how such misfortunes can be avoided.

One thing to keep in mind is that each class, function and module should have exactly one well defined task to do. When I put it that way it sounds almost trivial, but it’s still sometimes forgotten. Another problem that I often see are confusing interfaces: when designing the interface, don’t have functions InitTaskX(), BeginTaskX() and StartTaskX(), where StartTaskX() internally calls InitTaskX() and BeginTaskX() in sequence. Instead rather decide on one option that the one using the interface will need (even when it’s “future you” – in a few weeks you’ve forgotten what you meant with all the weird functions anyway) and stick to it.

Another thing I wanted to use to increase modularity in Freekick was to split the whole application in multiple processes. There’s one process for doing all the non-soccer-match stuff – menus, league tables, transfers, etc. and other processes for the actual match. When the main menu process starts a match, it creates an XML file for the match server, then starts the server and passes this XML file to it, then starts the other match-related processes (client and AI). This allows me to be 100% sure that I can change anything in the menu part of the application and not break the actual match, as long as I don’t change the XML file which serves as the interface between the two.

The server itself handles the physics, rules and the match state, while the clients display the state received by the server and send user input to the server. As a nice bonus adding multiplayer capability is relatively easy, even though it was something I hadn’t originally planned. Another positive thing about it is that I can use different programming languages for different processes; I’m currently writing the menu part in Python and the actual match part in C++. There are also more sophisticated libraries for accomplishing a similar task, such as D-Bus, but I felt it would’ve been an overkill for this one.

As for the server and the clients, they communicate over a simple, clearly defined Freekick protocol that works over network sockets. This allows me to change the way the client displays the match, for example, without me being able to break the functionality in the server. In Freekick, the AI is a client as well, which allows me to reuse much of the client code while still having clear limits on what code belongs to the client that the player sees, what is only relevant for AI and what code is used by both of them.

Splitting the game into a server and a client is what FreeCiv did as well, by the way. That’s why there exist multiple clients for FreeCiv that do the same thing but look different. Freekick has two clients now as well, one that shows the match  in 3D and another where all the graphics are text based, using Curses. In the end they both same exactly the same soccer match with the same AI, logic, state and rules, only the way of displaying it and receiving input from the user different.

As for the internal structure of the server itself, I’ve also tried to keep things as independent from each other as possible. There’s the Physics class, which is a facade to the whole physics subsystem. Then there’s Rules, a class that is responsible for calculating the changes in the current rules status of the match. Physics can be subscribed to, implementing the visitor pattern, and is subscribed by Rules. Rules receives all updates from Physics (where the ball is at the moment, which player touched the ball, etc.) and updates the rules state correspondingly.

Rules can be subscribed as well, and both of these classes are subscribed by Dispatcher, a class that sends both kinds of updates, rules and physics, to the clients. How does Dispatcher know who the clients are? There is the class ServerManager, which accepts incoming connections and adds them to the list, which the Dispatcher has a pointer to. There are also classes ClientEventListener that receives the input from the clients and InputMonitor, which validates the data before passing it on to Physics.

Freekick is using Bullet for physics simulation. While Bullet is an excellent library, I can’t be sure Freekick will be using it forever (who knows what kind of open source physics libraries we have in five years). To make sure the physics engine can be exchanged in the future as easily as possible, I wrote an interface that should correspond my needs and no more – functions like addStaticObject(form, position) and simulate(timestep) – a wrapper. The interface is then implemented by the BulletPhysicsEngine class using the sometimes not-so-clear Bullet interface.

These are some ways to add modularity in software – of course, there are more and maybe better ways to do it, but these have made it rather easy for me to continue implementing Freekick, even as the code base has gotten bigger with time. For the interested, the Freekick code itself can be browsed here.