Anyway, I have at least made a little progress toward my goal of a first playable this year - but if I was half as honest with myself as the guy was in hackenslash, I'd probably admit that I was a tiny bit behind schedule. I'm currently trying a new strategy for making it playable, where I sit down with my project and load it up - and the first thing that doesn't work like an actual game goes to the top of my todo list (note I very deliberately didn't say "look like an actual game" because I'm trying to avoid polishing thing ... well that and I'm a bit of a crap artist).
Suffice it to say I didn't get very far without finding something ... so this entry will look at the startup menu =) Nothing fancy mind you - just a basic front end to the game - I'm even going to skip the game options for now. We'll start by looking at the result, and then I'll show you all the grief underneath it:
So how does this all work? Well, I had some very crude UI elements (menus, buttons, text labels, etc) kicking around from the game's editing tool (covered in a previous entry), but they not only looked pretty utilitarian, but they worked a lot like the MFC UI elements - with a bunch of callbacks into the code with user-defined event Ids. Essentially, it meant every time you wanted new UI, you had to write a bunch of C++ to do whatever it was that menu was supposed to do.
In typically bad style, I tackled the ugliness problem first by extracting the UI "style" out into a separate object that "skins" a set of generic UI definition objects. This means a Column menu can look one way in the Editor, and a totally different way in the game. It also means when I get around to writing my World War II POW game, I just have to write a skin and away I go.
Next I looked at the harder problem of how I could build a menu without writing a whole bunch of C++ code every time I did it. But before I get too far into the solution, I should perhaps explain something else about my engine - you can do everything from objects and/or script. Well, not everything, but when I find something I need that I can't do, I add it. This includes creating instances of game characters, loading/saving maps, setting the screen resolution, etc, etc. So the plan for the UI was to turn the UI widgets themselves into part of the engine's "Object" system. This not only allows them to be serialised (so you can build some UI, save it to disk, and load it back in) - but it means they can use (and can be used) by anything else in the game. So you can have UI widgets that open doors in the game, or a door that pops up a menu.
Here's are the Objects behind the main menu, including what to do when the item is selected:
[Note that the editor boxes don't show up too well on that black background ... whoops]
With a shiny new startup menu allowing me to start a "New Game", I quickly hit the next thing that was pretty un-game like: the game just drops you straight into the world with no idea what you should be doing or why you're there. Now I wanted to go for a bit of a comic/graphic novel style to my game, so I figured the next thing to add would be narration dialog. Just like the menu UI, there's a generic "Dialog" node, and then the "skin" renders it into the game. Here's a shot showing a narration box with an in game menu just because I can:
The one thing that occurred to me while I was putting these test scenes together was that I'm very quickly going to need programs with loops in them. And in the current code, the connection "loop" would create a memory leak (because upstream connections hold references to the downstream targets - and a full loop means they all keep each other reference counted even if everything else in the game has forgotten about them). After a few minutes of panic thinking I'd need to embark on some performance glitching garbage collection scheme - I think I've come up with a way to detect loops when the connections are made and then just store a description of the loop so that I can clean it up when the next map gets loaded in. Quite a relief that.
I now need to work out where to next. I'm a little overwhelmed with the whole damage/death/load/save bit ... so maybe a bit of plot/story work first?
Cheers!
Don't be so quick to dismiss garbage collection and come up with a home-made algorithm. I was interested in the whole "dangling reference" topic once before and I thought I could solve everything; after some thought, I had to throw all my ideas away, because all of them had some fundamental flaw. Then I learned to recognize that when something is considered by the research community as a "hard problem", it means someone else put a lot of thought into it before I ever did, and some puny algorithms usually don't stand a chance! ;)
OTOH, I really don't mean to discourage you on this topic, and if you'd like to describe a bit what's on your mind I'd be interested.
On a lighter note, I think you just need to figure out who should be the cows' mortal enemies, and go from there! x)