Making a Big Pile of Languages

On November 10, 2011, in King Machine, Technical, by bateleur

It's amusing, looking back twenty or even as few as ten years how peopleStack of books seriously used to debate whether high level languages were a good thing. Programmers – and not just the sort with big beards who wore sandals in winter – would sometimes claim that C was just fine and there was no reason for anyone to use anything else. C++ had rather more advocates, but even they were keen to stress that the overheads introduced by their more expressive language were very small. If you did things "right", you were still in some sense writing assembler code. Allegedly.

But all along there have been people who have been quietly doing different things. Even back in the 90s, Tcl/TK could be used to build a fully functional UI for something in under half an hour. PERL has long been used to do all sorts of text-related things with incredibly short dev times. And ultimately even some of the C++ programmers started to bind Python and Lua to their C++ projects. "Scripting" was the word used for these secondary languages, because to admit that they were being used for programming would be to admit defeat.

Now environments like Flash and Unity take things a bit further. You write essentially your whole program in the local ECMAScript dialect (or something similar) and all the C++ is stuff that someone else has written, somewhere in the library layer. Like a kind of OS. Or, if you prefer, like the CPU's microcode somewhere in that layer you probably never even think about. Not that this is really new either. People have been doing approximately the same – albeit without garbage collection – since the 8-bit era.

But what is new is that programmers are finally realising that this is programming after all. In fact, not only is this programming, it's the bit of programming we really care about. Getting things done!

Guess what I'm doing to King Machine this week? I'm adding another language to the big stack of languages.

KMScript is, despite the obvious sounding name, not really a scripting language. What it actually does is to behave like a little virtual machine inside the game. Does that sound completely insane to you? Particularly for a game that's "almost finished"! (In quotes because of course these projects never are.)

In fact this is not some kind of absurd complexity creep. It's the opposite. King Machine's codebase is a huge, sprawling mass. In order to fully debug it and stabilize it ready for release I have to clean it up. But due to the ad-hoc way it has grown that isn't an easy process. I've spent a long time looking through it, searching for ways to simplify it. My conclusion is that there are very few functions that can be shared further and very little complexity that can be removed. However, most of the game's code I don't need to look at most of the time. When it occurred to me that this was rather like having two layers of functionality, I knew what I needed to do…

Within the game world, things happen like a block is created, aligned with another, activated, rotated by 30 degrees or whatever. These are simple things, but currently they are not simple to work with at the code level. So what I need to do is add a new layer of abstraction. So, for example, instead of having a class for "push beam" blocks that inherits from "block" and implements the push beam effect when used such a block should instead be a block containing a small code fragment in a new language internal to King Machine. In that language, a beam within the King Machine world is a known kind of thing and a "push" is a known action, so the behaviour of this block is very simple to express.

So far so not-very-interesting. But the real payoff here is that things like save files and replays can be encoded in this same language. This unifies all the data in the entire game and means I no longer need to add support in four different places for every feature in the game and keep them carefully synchronized. Even better, testing and debugging becomes so much easier because the level of code sharing will be far higher and all the code will be exercised more often.

OK, I lied, that's not the real payoff. The real payoff is that it's going to be fun! What's the point of being an indie developer if I can't have fun, eh?

Tagged with:
 

The Silence of the Engine Writing

On October 26, 2010, in Knights & Ruffians, Technical, by bateleur

Games are fun – if they weren't we wouldn't bother with them – and for the most part games development is fun too. However, the kind of blog friendly design exploration that people think about when you say "game design" is only a small part of the whole. I sometimes call myself a game designer because I design games every day, but most of the time during those days is spent programming.

Towards the start of a project the programming that needs doing isn't even particularly sexy. That is, most of what you're writing doesn't relate much to the interesting gameplay, doesn't involve any especially clever algorithms and isn't the sort of thing you can get done in a day. Modern approaches to development involving short "sprints" between working prototypes sound appealing, especially to novice programmers, because of the word "short". But in reality there is sometimes a big task that needs doing that you can't meaningfully split up.

So, what I've been (mostly) doing for the last few weeks is writing the core engine code for Knights & Ruffians. I use the word "engine" here because I like it, but really I'm just talking about rather dull basic modules on top of which I will build everything else.

However, there is one aspect of this I felt was worth a quick mention: why is it that I decided to write the entire motion and collision system using only integers (!).

Let me tell you a story. When the original Fantastic Contraption was released I immediately loved it and played it a lot. The first level I didn't solve straight away was Awash. Once I had eventually managed it I decided to link to my solution from my blog. My solution was messy and took a long time to complete, so I asked for suggestions for improvement. One of the responses that I got was interesting. As well as an incremental improvement, the poster pointed out that in fact my solution didn't work! Further investigation revealed that for some players it was fairly fast, for some it was slow and for others it failed outright. I posted our findings to the Fantastic Contraption forum.

What had happened was this: In common with almost every Flash application ever written, Fantastic Contraption was using Flash's built in Number class for its floating point arithmetic. This is a good thing, but one feature of doing so is that the underlying hardware is doing your floating point work for you. As it turns out, not all floating point hardware behaves 100% identically.

So the bottom line is this: if I want my game engine to run 100% identically on everything then I cannot use Numbers at all (except for purely cosmetic things).

Why does this matter? Well, suppose I use some attack which does variable damage to opponents depending on their distance from the centre of the blast. That could give rise to a situation where on my machine a particular enemy dies, but on yours it lives! This can be fixed by adopting a Diablo-II style approach where you allow your client data to drift apart but you then continously attempt to resync-it. However, this is messy and difficult to get right and even Diablo-II sometimes fails (following a period of lag you can suddenly die without warning).

The remaining question is whether the probability isn't way too small to care about. Again, the answer is no. The reason being, collision systems amplify errors very rapidly indeed.

Working with integers in Flash isn't fun since there is no 64-bit integer built-in type. Consequently you have to be very careful of overflows. But for now everything seems to be debugged and working, so more interesting tasks await!