Archive for November, 2012


Visual Studio 2012

I installed it yesterday. It was a huge download which I had to run overnight on my creaking internet. Other than that installation was smooth, it automatically converted my project and everything worked straight away. It does break linking in VS2010 with no warning (nice one, Microsoft) unless you uninstall and reinstall some components and generally mess about. But I’m not going back so that doesn’t affect me.

There is an elephant in the room in the form of the UI. I know they like to change it in every release but what were they thinking? It’s been described as ‘fifty shades of grey’, but that’s a bit charitable as you basically have a choice of completely white or completely black. They seem to have dropped the old icons in favour of programmer art.

Why are we still using floppy disk icons in 2012?

I was able to download a theme that at least lets you see where the windows are.

Enough of that, how about new features? Well, they seem to want you to use test driven development because the first item in the right-click menu is ‘Run Tests’. Regardless of whether any tests actually exist or whether you have any intention of writing any. The next item is ‘Insert Snippet’. Look how useful snippets are; you can make an ‘if’ statement in no less than 20 mouse clicks. The actually useful item ‘Go to definition’ is buried somewhere in the middle. Guess I’d better get used to the keyboard shortcut.

C++11 is mostly there, enough to make the upgrade worthwhile. I don’t know why they are still lagging, but Microsoft has always had its own interpretation of the C++ standard.

Code Analysis is a nice feature, but seems to focus purely on potential crash bugs rather than any other errors. In my project it only complained about a buffer overrun (impossible due to the logic), a null pointer dereference (also impossible) and something about WinMain (hey, you wrote that!). Maybe I’m just that good, but I expected more.

That’s about it. The best feature is that I don’t have to pay for it, because the Express edition is enough for my needs.

Advertisements

Language

I used my first ever bit of C++11 today. Adding support for different collision types meant storing a shape pointer on the physics body, so naturally I disabled copying of physics objects because there’s no need for it and I didn’t want to have a reference counted pointer. But then I couldn’t store them in a list anymore because the only way to get an object into a list is to copy it. C++11 has emplace_back, which allows an object to be constructed in place on the back of a list. I was so impressed at this fix to an awkward part of the language I decided to install Visual Studio 2012 to get the rest of it. I’ll try to use it for convenience and simplicity and not go crazy with advanced features.

The outcome of that is that I can place doors, which have box-shaped collisions. Unfortunately they get pushed down the corridors. They aren’t fixed in place yet.

Dynamite

Sometimes, code threatens to blow up in your face. I don’t mean it crashes, that’s no disaster for a programmer (unless it starts happening after you release it). I mean several apparently simple elements of the design, when put together, cause the complexity of the program to increase exponentially.

You can start frantically coding to try to patch up the holes, then realise the new code doesn’t work either and is actually even more broken. The best approach I find is to sit back. Take a walk. Sleep on it. Maybe you just missed something. Adding complexity is never good, because when the next problem comes along it will get even worse. If all else fails, you will have to re-think the original design.

In my case, undo/redo, instances and actor links were the explosive scenario.

Now, the scene code knows nothing about undo/redo. There are many functions to modify it, and they just operate as if there was no such thing. I like this. It keeps the classes simple. This works because operations on a tree structure are inherently reversible. If I need to modify a node I copy it and then swap. So the command list doesn’t need to know much about the scene either. Create links between nodes though, and that’s not quite true anymore.

Problem one: if a node is instanced, and it is deleted, the instances should disappear too. But they didn’t. The problem was that the undo buffer was keeping a pointer to the original node. These are reference-counted pointers. The extra pointer meant that the object was not being deleted, so the instances (with weak pointers) were pointing to a valid object. Simple enough, you might think. Just copy the object and keep the copy in the undo buffer instead. But then how do you redo? All the instances will be pointing at nothing. I was contemplating having to maintain a list of all references with each node, or hacking the smart pointers to replace a deleted object.

Luckily, I didn’t go too far with either of those ideas. There’s a simpler solution. Every node knows the scene it belongs to. If a node is removed from the scene, for example by being deleted, the scene pointer is set to null. So all the instances have to do is check whether the instanced node is part of the scene, returning null if it isn’t. One line of code.

Problem two (even worse): This trick doesn’t work with actor links. It’s not possible through the actor interface to hide the broken links. However, in this case the links are already two-way. So it’s easy to delete and restore a link, and from there create a command list to unlink and relink a hierarchy of nodes. It’s a still a slight explosion, because the code to manage links for cut/paste and undo/redo is larger than the original link code, but it’s manageable.

Which leads to problem three: deleting an instance unlinks the original node. The linking/unlinking code has to ignore instances. This is also why the instances have to disappear when the original is deleted (I considered using a strong reference so they would stay around) – the links are gone so they don’t work anymore.

Any more lit fuses lying around? I hope not, I’ve just got all this stuff working..

Actors and Objects

I had actors working a while ago, but I only just added the functionality to place them using the editor.

I settled on treating actors as another node type. I considered treating them like sprites, which are not nodes but are kept inside rooms along with the tiles, or making everything potentially an actor by attaching arbitrary data. Using a specialised actor node seems like the sweet spot between clarity and flexibility.

Actors need data, and my plan was to use JSON again, attaching a file to each one. This turned out to be problematic. For one thing, I could not find a decent offline JSON editor. (Seriously? No one has written one of those?). I also didn’t fancy managing lots of little files with the scene. Anyway, it didn’t take long to write an embedded object editor using the immediate mode GUI.

The other thing actors need is connections to other actors . If I have a door actor, it needs a trigger zone that tells it to open. This has interesting implications for copy/paste. If I copy an actor, should it still be linked to the same actors as the original? I would say no; if I copy a door, it will probably need a different trigger zone. What if I copy a door and trigger zone together? Then the copies should be linked to each other, but not to the originals. If anyone ever decides to clone Kevin Bacon, I hope they take this into account.

Instances

Instancing is the killer feature of the scene editor, and I finally got it working properly.

It’s often used to save memory, and speed up production by reusing elements. I’m not worried about memory on this project, and copying (which most editors support) would also achieve reuse. But what I really want to do is block out the scenes using placeholders, and fill in the details later.

The choice of what to instance is very flexible, because nodes can be grouped in any way in the hierarchy.

The interface is as standard as possible. I use cut/copy/paste, but there’s an extra option – copy ref. This is just like copying a shortcut in Windows. You paste it as normal but what you get is a link to the original node instead of a copy.

The tricky part was designing the behaviour of the nodes so that instancing would be useful. Separation of concerns is the key here. When I instance a node, I don’t want to instance its position; that would lead to two nodes overlapping. So there has to be a separate transform node. But I do want to instance the branch that sits below the transform. So that has to be a separate node as well.

And that’s why it didn’t work in my original code. A transform node needs to have sub-nodes, so I inherited from branch node. Big mistake. It doesn’t need to be a branch node, it just acts like one. In general, nodes are containers of their sub-nodes, and the branch part of a transform node is contained inside it. It still looks like one node in the interface.

The lesson, if there is one, is that wanting to acquire the behaviour of another class is not a reason to inherit from it. Inheritance is like chaining two objects together – you’d better be sure you never want one without the other.

Fog of War smoothing

With some better-looking (albeit stolen) graphics in the game, the visibility fog was looking a bit ugly. Most games with this sort of system smooth the edges of the fog for a better appearance. Could I do that without too much work (after all, this project isn’t about graphics)?

Here’s an article that covers the subject pretty well:

http://www.appsizematters.com/2010/07/how-to-implement-a-fog-of-war-part-2-smooth/

Essentially, you take sub-samples inside the squares and use the results as a bit-mask to look up a shape.

However, this technique can be improved by using samples along the edges of the squares rather than inside them. Internal samples are redundant, because the visibility of a square is determined completely by the visibility along the edges. Using edge samples ensures that the shapes will tile correctly – this won’t always be the case with internal samples. Also, samples along the edges can be shared with adjacent squares, so you get double the sample count for free.

Something that should please most programmers is that two samples on each edge gives 8 bits, rather than 9 for a 3×3 grid. Allowing for rotation and flipping there are only 16 possible shapes.

Still, I can’t be bothered to draw the shapes and store them as tiles. All I need to do is draw an alpha-blended polygon over each square with vertices where the non-visible samples were. If I had an SDL library that could do gouraud shaded alpha polygons it would be nicely smooth. As it is it still looks a lot better than before.

Sprites

After tiles, the other visual component of a 2D game is sprites. They resemble tiles in a lot of ways and are rendered almost identically, but there are important differences:

  • They are not placed on a grid, but at arbitrary (x, y) positions.
  • They can be any size (though I am using only multiples of the tile size).
  • They can be animated and moved by the game engine.

The last point is the tricky one. How exactly should that work? When placed in the editor, sprites belong to a room, but in the game they aren’t necessarily going to stay in there. Also, for purposes of loading and saving the game state, dynamic data has to be outside the level structure entirely. Should sprites be turned into Actors (see previous post on Game Objects)? Perhaps, but most of them are only going to interact with the physics system, and not do anything special.

The simplest solution is probably the best. On initialisation I copy the sprites into the game state, with an optional link to a physics object, and render them from there.

Now I have crates! Surely the most ubiquitous game object of all time.

Playing the level

It took a day to merge the prototype game with the level from the map editor. This was mainly due to generating the navigation data. As I’ve mentioned before, this data is a series of connected rectangles, and I had code to generate it from a grid of tiles. It’s an interesting problem, and not as simple as it sounds because ideally you want to minimise the number of rectangles that comes out.

But the level is not a grid of tiles, though it may look that way. It’s a hierarchy of nodes of different types; some nodes containing a list of tiles in several layers.

The trap I had fallen into was making the algorithm much more dependent on the data structure than it needed to be. For which I blame OO with its easy access to members. So a refactor was needed.

There’s a long way to go before this is a proper game. But making a level in the editor and walking around it is a nice milestone to reach.

Tiles

It took a while, but now I can place tiles.

Graphics stolen from a well-known Amiga game.

Mainly because placing tiles relies on a lot of other functionality: all the UI, the scene hierarchy, saving and loading, and undo/redo.