As a fun programming exercise and just to see if I could, I decided to try making a PC version of an established boardgame. I picked Caylus: Magna Carta because 1) I own a copy of it (actually a gift from Han a couple of years ago now 2) its main components are cards that I can easily scan and yet the cards are played onto a virtual board, so it’s more like a boardgame than a cardgame and 3) I thought that it should not be too difficult to write an AI for it, as opposed to something like Glory to Rome which has way more combinatorial possibilities.
I’m aware that the standard practice in such cases is to adopt a different name and to avoid using the original art. But I’m doing this just as a learning exercise so I don’t plan to distribute it. Besides, seeing the actual game in action is a key part of my personal motivation for doing this and I can always switch out the art for placeholders later. Anyway, the project is far from done but after nearly a month of work, it’s certainly playable now, so here are some screenshots..
Here’s the main menu screen. The AI Cheats option isn’t implemented yet. It’s just an idea I had to make the AI more challenging. One of the hardest parts was to decide on how to layout all the different aspects of the game. In the end, I decided to be lazy and gave myself a fixed 1280 x 960 screen. This means it won’t work on smaller screens but it does give me lots of real estate to play with.
User input is required in many situations and I use modal windows for this purpose. This is harder than it sounds. One reason for this project is to learn Python and specifically the Pygame library. Unfortunately, while GUIs are easy to implement if you’re working in, say, Microsoft Visual Studio or even with Java Swing, but Python doesn’t come with a standard GUI toolkit and I had to spend some time pondering different options until I decided on PGU, a Pygame library that implements GUI features among other things. Otherwise, creating things like modal windows, buttons, scrollbars and the like from scratch would have been impossibly difficult! This also means that a lot of the work is ad hoc and inconsistent. For example, all of the info on the left of the screen aren’t GUI elements at all, since I wasn’t very familiar with the capabilities of PGU when I did them. Instead, they are separate elements that are carefully and individually blitted onto the screen!
Caylus: Magna Carta creates a virtual board out of cards as the game progresses, and the more players in a game, the more cards get played and the longer the road gets. So I stole the idea from Keldon’s implementation of Race for the Galaxy to use small image sizes for the cards in the field but display a large image of a card whenever the mouse hovers over it. This still isn’t enough space so the virtual playing field is scrollable, either with the mousewheel or by hovering the mouse over the top or bottom of the main game window. I thought that might be hard to implement but it was actually rather easy.
Naturally some modal windows are harder than others because of how much functionality they must have. I found that while I enjoyed programming, I hated anything that smacked of graphic design or heaven forbid, opening Paint and mucking around with image files. Figuring out the logic behind what combinations of resources to pay for a given cost would be legal is fun. Laying out the different elements of a GUI form so they line up correctly and look neat is not.
I worked on the project based on the principle that I should always be doing what is immediately necessary to proceed, hence I didn’t spend much time planning out the overall architecture of the program. For example, I originally thought I’d create a working game first and then insert AI later. But I couldn’t test what I’d implemented without players actually doing stuff in the game so I’d basically implement something and then immediately write some simple AI code that knows how to use it. This meant that I implemented things phase by phase. At first I implemented the phase which allowed players to perform their actions but after they were done I’d clear the board of workers and jump to the next round, without moving the Provost or executing card actions. The next phase was added only after the previous phase was completely finished. Hence, the batch offering screen was done only yesterday!
One of the challenges involved in that user input is required in many different parts of the game, so whenever that is needed, I basically need to pause the game, wait for the user to make a decision and then have the program continue on where it left off. It was quite hard to get this working right at first. I needed to remember to disable and enable buttons depending on what the user is supposed to be doing. Imagine the user clicking the draw card button when he’s supposed to be deciding where to move the Provost! Currently the whole thing is over 5000 lines of code long. There are so many things to keep track of that I even forget that I’d previously used a variable for one thing and now I’m using it for something else. This is especially tough in Python which doesn’t have statically typed variables and doesn’t enforce variable scope.
Naturally, there isn’t space on the screen to display the Prestige buildings available for construction, so clicking the button causes a window to open to display them. Sometimes, I have to decide on user interface issues when it isn’t immediately clear which way is best. Should the flow be click button, choose card, choose residence to build on and then allocate payment or should it be click button, click residence to build on, choose residence and then pay? I didn’t have room to display the discard deck either and I wasn’t sure if you’re allowed to view through the contents of your discard deck. This wasn’t implemented at all, though you should at least always be able to see the top card of your discard deck.
While it’s currently possible to play a game to completion, the AI is downright crappy and extremely predictable. All it does is basically take random but legal moves, modified by some very simple heuristics, such as: don’t place a worker on the Lawyer if you don’t own a residence dumbass! The next task will be improving the AI but that will be difficult given the ad hoc architecture I used. I probably need to spend some more time cleaning things up and fixing bugs first. And yes, there are tons of bugs!
Regardless of whether or not this game ever gets any better than its current state and whether or not anyone than me and my wife ever gets to play it, I really enjoyed the process of working on it and naturally learned a great deal. Actually this took up so much of my time that I barely played any actual games for a month. For anyone who has played video games since childhood, I guess it’s natural to feel like one day making a game of your own. Well, implementing a well-established boardgame into a video-game doesn’t count really, but it’s still much closer than I thought I’d ever get. Maybe one day I might even work up the courage to implement one of my own crappy boardgame designs as a videogame!
P.S. – In case I get any questions, yes, I’m aware that there is currently an officially approved iOS version of Caylus. Actually I only read about it last week but it doesn’t really affect me as this project isn’t intended for public distribution and I only wanted to make this for fun.
One Response to “My hobby programming project”
Trackbacks
Leave a Reply