Of cats and cake

This has been a successful month, but not very graphically so, so you’ll just have to take my word for it. I created my own programming language, Tig, which is what Ghostworld will mostly be written in. It consists of a compiler, a virtual machine to run the compiled program on, and the language grammar itself. A very simple program written in Tig might look like this:

event robotTea { 
 "The robot abruptly turned around and glided away into the back room. I noticed that it had left its cream cake on the table.";
 option "I hurried after it." backRoom;
 option "I stealthily helped myself to another slice." stealCake;
 option "I remained seated." remain;
};

event backRoom {
 "The robot was just settling into an armchair as I arrived. ""Where is my cake?"" it demanded.";
 option "I apologised profusely." killed;
 option """Fetch your own damn cake."" I told it." killed;
};

event stealCake {
 "Just as I was tucking in, the robot returned. ""CAKETHIEF!"" it grated, and tore me limb from limb.";
 option "I allowed my ghost to float somewhat implausibly back in time to our first meeting..." robotTea;
 option "I decided to call it a day." quit;
};

event remain {
 "After a long time the robot returned, and cut itself another slice of cake.";
 option "I smiled nervously." robotTea;
};

event killed {
 "Alas, I had underestimated my host. ""BAD GUEST!"" it grated, and tore me limb from limb.";
 option "I allowed my ghost to float somewhat implausibly back in time to our first meeting..." robotTea;
 option "I decided to call it a day." quit;
};

event quit {
 "The end.";
 end;
};

If you compiled that source code and ran it on the virtual machine, you could interact with it like so:

The robot abruptly turned around and glided away into the back room. I noticed that it had left its cream cake on the table.
1: I hurried after it.
2: I stealthily helped myself to another slice.
3: I remained seated.

?1
The robot was just settling into an armchair as I arrived. “Where is my cake?” it demanded.
1: I apologised profusely.
2: “Fetch your own damn cake.” I told it. 

?2
Alas, I had underestimated my host. “BAD GUEST!” it grated, and tore me limb from limb.
1: I allowed my ghost to float somewhat implausibly back in time to our first meeting…
2: I decided to call it a day.

As you can see, Tig makes it easy to write branching narrative games. But it can already do a lot more. You can make player options execute code statements, such as “robot.temper = ‘piqued’;”. You can create objects simply by writing “object cake has description ‘A daunting confection of mascarpone and sponge’, weight = 20;”. Many more powerful features will follow.

Writing your own programming language is no easy task – why go to such trouble? One reason is that it’s a basic rule of good programming that you separate your code and your data. In the case of a platform game, for example, your code is the bit that handles input, graphics, and so forth, and the data is the level. You could mix all the level data in with your code, but it would result in a gigantic, unwieldy morass of numbers and C++ statements, and every time you wanted to change a single brick in one of your levels you would have to hack around in that monstrosity and then recompile the whole thing. Keep code and data separate, and all you have to do is write one clean function that does a thing when it encounters a brick, and you’re free to create and tinker with as many brick-based levels as you want in your level editor.

OK, so this argument gets stretched a teensy bit in the case of Ghostworld, because my game is a work of interactive fiction and so its data has to include code of its own – but, shut up, because the same principles still apply. A text-based, interactive game’s script is its data, and designing any game in its own dedicated, user-friendly language is far easier than trying to hard-code it in C++, or Unity or GameMaker for that matter.

The other reason I’m writing my own programming language is this guy:

Tig

Tig and Cas were our first cats, and Tig was the first to die, in 2008. It came out of nowhere, it wasn’t fair, and when he was gone I really missed that little guy. To amuse myself, and to keep his memory alive in some way, I decided to call the programming language I had just started to create back then ‘Tig’. I found the intricacies of language creation fascinating, and it became a wildly ambitious project, boasting dynamic typing, multiple inheritance, and much more. Alas, I was not a great coder in those days, and it was all built on messy, amateur, poorly thought-out C++. Improving it became harder and harder, until in the end I just quietly stopped, but I always felt a little pang of guilt for not doing right by my mog.

When I decided to make this game, I quickly decided that it needed its own scripting language, and I knew immediately what that language would be based on and what it would be called. I made myself start from scratch, but that first attempt helped hugely: I knew what worked and what didn’t, but most importantly this time around I knew how to code it properly, which is why this month has been a month of rock-solid progress. Thanks, little dude.

Advertisements

Strange fruit

October marks an exciting change in direction for the development of my game. Exciting if you’re the one who’s been writing the thing for the past five months, anyway. Less so for everyone else.

For a start, the game formerly known as ‘my game’ now has a tentative name. How does Ghostworld grab you? Yeah, I’m not too sure either, but it will do for now.

The bigger change is that I’m putting graphics development on the back burner for a while.

I had a six-month plan to produce a rough, playable game, where each month was dedicated to another part of the graphics engine. October was meant to be Make Buildings, and November Shadows and Water. But my game – sorry, Ghostworld – was always supposed to be a work of interactive fiction too, and I’ve been guilty of sidelining that. I started to feel a little uneasy a couple of weeks back, as I wrestled with recalcitrant fractal plants and realised I had a lot more work to do here, and also in a whole bunch of other graphics areas, before I would have anything that looked remotely like a game. Should I just plod on like this? And on, and on, and on?

The received wisdom is “no”. Derek Yu and some guy called Tom Francis both made playable prototypes of their games as quickly as possible, and then evolved them. A lot of other devs advocate the same approach. And it’s a lesson I’ve already learned over and over in fiction-writing: get a rough draft finished before you do anything else, as fast as you can, no matter how bad it is. If you stop to fix and polish bits, you lose momentum.

You don’t play with the graphics in my game. You play with the interactive fiction. If I want to make something playable, it’s the text side of things I have to get working first, as fast as I can. So that’s what I’m doing.

This will result in less graphically exciting blog posts, which is probably one of the subconscious reasons why I’ve been ignoring the IF stuff all this time. Another, I suspect, is that as long as I’m not working on the actual game, I don’t have to worry about how good that game is, or indeed how good I am at making games. I’ve been living with myself for some time now, you see, and I know how my mind works.

So here are some current screenshots of Bedquilt Land, just in case it’s a long time before I post any more:3DTest 2017-10-01 19-42-05-38.bmpScreenshot 2017-10-05 15.40.12Although the fractal tree improvement didn’t get very far, what I did achieve was to get trees and grass growing in more natural clusters, rather than uniform, unbroken swathes. So there’s that. And yes, my trees have square fruit now, shut up.

 

Committing trees-on

I think we can all agree that this looks pretty bloody amazing:

opener.png

That’s because this week I tackled something I’ve been wanting to explore for years: creating fractal trees. I’ve always been fascinated by fractal graphics, ever since the early days of grinding out the Mandlebrot Set pixel by pixel on a BBC Micro in a dizzying eight colours. And one branch – if you’ll pardon the expression – of fractal graphics is fractal trees. Using a few simple rules, recursively, it’s possible to create startlingly natural-looking vegetation. Once you know that, it’s very hard to look at plants and trees in the real world without noticing how they’re all made out of simple patterns recurring at different scales.

As I say, it’s something I’ve wanted to explore for years, but it’s only recently that I’ve had a platform on which to do so: my game engine. (Which I really should find a cooler name for than “my game engine”.) It turned out to be surprisingly easy to set up. In almost no time at all I had a little C++ class that made wireframe trees by recursively splitting branches into sub-branches, the sort of thing you’ve probably seen before:

Screenshot 2017-08-15 16.51.39

Then I added a function for creating solid 3D geometry, and got results like this:

Screenshot 2017-08-16 17.35.40

Finally, I added routines to temper the symmetry with randomisation, and a sample that had previously looked like a piece of broccoli turned into this:

Screenshot 2017-08-18 14.04.48

Isn’t that brilliant? And there are about 50 million more where that came from, because it’s all based on a random number seed. That’s what 740608 looks like, in case you were wondering.

I was so pleased with the result, and it was so near the end of the working week, that I almost left it there. But I just couldn’t resist seeing what would happen if I plugged my trees into the instanced drawing system I’d used to cover my procedural terrain with grass. Amazing scenes, that’s what happened. I’d totally forgotten that left to its own devices, my game engine colours every model differently, according to a simple algorithm for creating harmonic palette sequences. It’s like something out of The Magic Roundabout. Take a look.

How green was my valley

Screenshot 2017-08-11 11.39.18

…pretty f**king green, as it turns out.

Screenshot 2017-08-11 11.43.07

This is just a quick update to show what my terrain looks like when you replace comedy stand-in cubes with actual grass textures, which is what I spent this morning doing. The effect is amazing, if I say so myself. (And I do. “Amazing”. There you go.) I still can’t get over just how much stuff I can draw, and how fast, on today’s graphics hardware

The joke is, the finished game probably won’t even have grass in it. Or at least, not great rolling swards of it like this – I want it to look like an alien planet, not Middle-earth by way of New Zealand. But this was a great proof of concept.

Next task: making my grass sway gently in the breeze.

Screenshot 2017-08-11 11.52.43

…OK, the comedy stand-in coloured cubes were more fun. Let’s have the comedy stand-in coloured cubes again.

Instanced karma

This month is supposed to be about adding vegetation to my terrain. It started well, then went badly, and is now going well again. So that’s OK, I guess.

The good start was making a Poisson distribution function for grass. For a convincing 3D game landscape, your digital grass has to be spread out randomly but smoothly, and smoothly random is something computers are very bad at. If you just used an ordinary rand() function, it would end up an unrealistic mess of statistical gaps and clusters. Poisson distribution generates random points that are smoothly spread out, and I couldn’t have been more pleased with myself when I got that working.

Remind me again what pride comes before?

The next stage was to mould my 2D plane of smoothly distributed points over my 3D terrain. This is trickier than it sounds, because basically for each 2D point – and there are thousands and thousands of them – you have to sample all the vertical space they could occupy to find the surface of the terrain at that position. And you have to do it fast, because your player is waiting. Doing it fast means using shaders, and shaders can be a bugger to code.

I created a reference texture of my terrain’s height – a sort of snapshot from above – so that I could read the height values off of that as needed. And for some reason I could not read that damn texture back – I just got garbage or zeroes. I wasted the best part of week trying to find out why, because once I’d wasted a certain amount of time doing that I felt I had to keep going or I would have wasted even more time. The kicker is that I still don’t know: eventually I had to cut my loses and give up. Return on time invested: zero.

The good news is that I found a different solution, and a better one. I’m rather proud of it. I feed the points into a shader that samples the terrain at two different heights, and if the surface lies somewhere between them it calculates where by interpolation. The clever bit is that you do this about a dozen times, raising the sampling height each time and feeding the data it spits out back in as the next round of input. Your 2D points rise to the surface like bubbles in champagne.

Finally I could get onto the instancing, which is something I’ve been itching to try.

Instancing is where your graphics card saves you a massive amount of bandwidth by letting you draw the same model over and over again for almost no extra cost. If you ever wondered why games once couldn’t show you things like vast asteroid belts in Elite: Dangerous, and now they can, it’s because of instancing.

Making instanced grass can come later. After all my hard work mapping those evenly spread points to my terrain, I wanted to see how they looked. Answer: amazing. I knew instancing let you draw lots of the same thing at once really fast, but I was still amazed by just how many of that thing it would draw, without my badly unoptimised code even breaking a sweat.

If you ever wondered what seven hundred and thirty one thousand four hundred and sixty coloured cubes looks like, it looks like this:

Screenshot 2017-08-09 14.19.28

I had great fun running around what was suddenly a very busy landscape.

And then I had an idea. What would it look like if I turned off the landscape, and it was just cubes?

Answer: Even. More. Amazing:

 

 

A road trip in Dali country

After the previous month’s physics hell, July’s task was pretty much a holiday. A scenic journey with a dead Spanish surrealist artist doing the navigating.

For years and years now, long before I even started work on this engine, I’ve been fascinated by the idea of procedural terrain. Landscapes that just go on forever, without ever repeating. A whole, world-sized world inside your PC, that you could in theory spend the rest of your life wandering around, like some ice-bearded Edwardian explorer pointlessly mapping the endless wastes of the polar ice shelf. And all of it spun out of a small algorithm and a handful of numbers. “Wouldn’t it be great to make something like that myself one day,” I used to think.

Screenshot 2017-07-28 11.53.51

This was the month I finally got a taste of that. My scheduled task: “make playable terrain” – a vague goal for a vague concept, but I had some ideas.

One problem with procedural terrain is that it is naturally homogeneous: it may not repeat the same exact feature, but it will keep showing you the same kind of terrain, on and on. So once you’ve seen one area created by a particular algorithm, you’ve seen everything that algorithm has to offer. Exploring further becomes unrewarding, because everywhere looks like everywhere else. This was very much the problem with No Man’s Sky’s infinite worlds. In theory you had the dizzying prospect of a whole planet to explore; in reality, once you’d walked around the place for two minutes you’d seen everything you were ever going to see.

Another, subtler issue is that procedural terrain lacks drama. Good game terrain is normally handcrafted by a designer: you follow a preplanned route, the scenery changes to keep you engaged and to provoke particular moods. Epic vistas open up before you at the point when the designer wants you to feel epic. Procedural terrain, in comparison, can feel bland and meaningless.

Battling those twin challenges is going to be an ongoing project. This month’s task was all about finding and coding a small arsenal of techniques to bring to the fight: ways of making random landscapes interesting to be in. Things like Distant, Dramatic Mountains:

Screenshot 2017-07-28 10.19.17

In the finished game that flat, circular space will be where you play, and will have its own varied scenery. The Distant, Dramatic Mountains are simply there to give you something exciting to see on the horizon.

The real fun starts when you decide to throw in a little three-dimensional simplex noise to liven things up. Like so:

Screenshot 2017-07-29 11.32.17

Yeah, it’s kind of hard to see what’s going on in there, isn’t it it? But I think we can agree that it’s not boring. In fact, I ended up spending ages just wandering around that place, marvelling at its weird, Daliesque features and thinking “what hath God wrought?” God being me, in this instance.

A few snapshots:

Screenshot 2017-07-28 12.59.57Screenshot 2017-07-28 12.56.06Screenshot 2017-07-28 12.55.14Screenshot 2017-07-27 20.29.21Screenshot 2017-07-27 19.33.30Screenshot 2017-07-27 13.42.06

And that’s not the half of what I saw.

Fleet world hack

Cubes, not falling

Being a games programmer involves spending a surprising amount of time in the company of  coloured boxes.

So it turns out game physics is quite hard to code. Who knew, right? Well… you, probably. And me. And also just about everyone we know. And yet for some reason I just had to go and code it anyway.

This has been a tough month of development. The fact that it ended up five weeks long, which is unusual for June, should tell you all you need to know. And to think I thought this would only take me a couple of weeks.

In my defence, as I noted in my last post, I only wanted to do very simple physics where you move around my landscape and don’t fall through it, but apparently even that is really hard to code if your main qualification is in English Literature.

The problem with game physics in a nutshell: physics is a continuous process, videogames can only simulate it in discrete chunks. If your game runs at 60 frames per second, then 60 times a second your physics code gets a chance to update the simulation, but there’s a tiny microsecond gap between each update, while your PC is off doing something else. If your objects are just flying through space this isn’t a problem, but if they collide it suddenly is, and a huge one. In fact technically, the physics isn’t even the problem: it’s the collisions.

Your objects will collide between the nothingths of a second in which your physics code runs, which means by the time your code tells you about it it’s already happened. How bad can that be? Let me put it this way: because of physics, when a crate is resting on the ground in your simulation, it is actually colliding with the ground 60 times a second. Ah.

Physics: Hi Tony! While we were away some downward acceleration called “gravity” was happening to that crate, so I moved it down a bit. Into that stuff called “ground”. Hope that’s OK?
Me: You idiot.

You have to move the crate back, and you also have to remove the velocity it gained during its little sojourn into the ground, which now never happened. And you have to get the numbers right, or it will start to vibrate as your code gets caught up in a mad spiral of overcompensating and undercompensating at 60 frames a second.

And vibrations will always happen, because you’re working with clumsy approximations rather than the infinite continuity of the real world. Fix one bit and you mess up something else. It’s like trying to mend a watch while wearing boxing gloves. As the month I’d allotted for coding the physics drew to a close, I seriously considered jacking the whole thing in and using an off-the-shelf physics engine such as Bullet Physics instead. But that would have meant maybe another month getting that to work, and maybe finding at the end that it wasn’t a better solution anyway.

Finally, I found what was causing the vibrations and how to fix it. Then I found another problem. Sometimes, running downhill made you bounce up and down. Note the “sometimes”. That took most of this week to solve. Then I had a problem with jumping.

Ah, it’s good to write about these problems in the past tense, from the comfy perspective of having solved them. Which is kind of why I didn’t post anything earlier. Maybe I should try to do that in future, to keep this blog more real.

Anyway. Ever since I started coding this terrain engine, well over a year ago [edit: two years ago], it’s been my ambition to one day run around on its world, just like in a real game, rather than simply flying around (and through) it. The difference in realism is immeasurable, and hard to put into words. How does it feel, after all this time and a final, brutal slog through seemingly unsolvable physics problems? It feels like this: