Thursday, June 30, 2005

Coming Back To The Clock

So let's say you've followed my tutorial over there and have a nice clock and you can do groovy animations and various other things all to your hearts contents.

. . . then you decide you'd like to add a bit more functionality . . .

          Yeah sorry about that - it's not the easiest thing to work with.

My current version of the clock includes pausing, deleting and saving & loading (of time events). It also allows a number of clock instances (it's no longer a singleton, not really anyway.) But this proved rather difficult.

In this post I'll suggest things you might like to add and some of the pitfalls you might encounter. As well as a few brief notes on what I did.

Here are a few things you might wish to try your hand at!

Extension Challenges

  • Pause a single time event.


    In the clock class try to write the functions: Pause(TimeEvent t) and Unpause(TimeEvent t). You will have to extend the TimeEvent class, also watch out when sorting the time event list.


  • Delete a single time event


    Try writing the function Delete(TimeEvent t). This is pretty easy. Of course for some object, that-is-creating-and-using-timeEvents, to use this you'd need it to store a local copy of it's TimeEvents. (an orc, let's say, would have to keep a copy of all the timeEvents it send to the clock - like Attack Attack GrowlFiercely, if you decided you didn't want to growl you'd then be able to write Clock.Delete(GrowlFiercely)). I didn't do it this way.


  • Saving and Loading


    Needs some thinking about. I had the TimeEvent class implement ISerializable. The MSDN docs on this are great - I couldn't find too much useful information elsewhere. Try not to think about how to save the delegate until the end.




Notes on how things can get tricky

I avoided much trickiness by not going for the most general solution - rather I kept in mind what I needed and merely handled that.

Delete

How do we know which event we wish to delete without storing a local copy?

Reads one of my comments at the top of the clock class. A Delete() function that deletes everything isn't hard to write. We merely set the kill flag and run the purge events function.

Constraints is the answer. For my purposes I don't need a delete saying "oh delete the third timeEvent I added". What exactly do I need then?

Let's imagine you're fierce warrior is surrounded by 100 orcs. In the TimeEvent queue there are six attacks waiting to happen. Your warrior stabs one in the stomach and it goes down dead on the floor.

Now - we need to get rid of that orcs attack that was due to happen in 3 seconds. Not just it's attack but any time events currently relating to it. We could do with a function saying delete all time events that are parented by object X. In our Orc case we'd want Delete All TimeEvents that the Orc is a parent of.

There's possibly a way to find the parent of a given timeEvent using reflection on the delegate - but I failed utterly to do this. If you know how to do this please drop me a comment or a mail.

I made all time events store who created them. This allows enemies to die without causing problems. After this I created
the function Delete(parent, call). This took killed all TimeEvents of a given type parented by a certain object. If you've just broken the orcs sword he can't still run his stab event - it must be removed. Therefore Delete(orc, StabAttack) is called. (Though this could always be handled in the StabEvent code in the Orc class.)

(I dearly wanted to use reflection for that too but I couldn't get the method's name from the delegate I only ever got Invoke. - I know the actual method name's hiding in there somewhere though.)

Loading and Saving

This is tricky to begin with. Once you create a new clock and wish to load old events they're going to be running on different time lines than before. Maybe this is hard to visualize so I'll try to be clearer.

Clock 1 - Current Time: 5
EventStarted: 4
EventEnds: 8

No problem. We're going to fire in three seconds. But wait! Let's say the user has just saved and quit! Then let's say we just save exactly what we've got . . . well problems abound! The player has just reloaded. His machine time will be totally different!

Clock2 - Current Time: 10000
EventStarted: 4
EventEnds: 8

Well bang the event fires immediately. Maybe now you see the problem. Also remember we may want to save Paused Events and we may also want to save events that are going to repeat once they die - therefore the time they take to execute must be stored.

These problems are a little tricky but (well at least for me - I can't do arthimetic in my head) a small pad of paper and a little bit of time and the problems can be overcome.

The tricky bit is the Delegate. The time event is suppose to call a function. How on earth are you going to save that?

*Possibility 1*
Every object using time events is given a HASH (unique identifying number). This is saved with the object. These hashes are permenant over many loads and saves.

Then we store a copy of the hash in the time event. (also could be useful for delete - use hash to decide who is the parent of the current time event).

All the objects in the game are stored in a hashtable with this hash as their key. (I'm sure you know O(1) access and all that the look up wouldn't cost a lot at all). Let's use the orc example       HashTable(Orc.Hash) -> Orc.

In TimeEvent we store
   a.) The Hash
   b.) The Method name

Then we load an event. The event throws the hash into the hash table and is given the object. Using some nifty reflection with the string of the method name we get the delegate to point to the correct method.

The result is we can load and save entire clocks (provided all objects are loaded first).


And that's one way. But that's seems to be a lot of work. Also it couples the Clock to my code. I don't really want that - I'm after nice and modular. Even though it's small I have thoughts of putting Clock into it's own library that I can use anywhere. I also have trouble doing reflection to get the pointer to method (though with a little messy coding I could have just about managed this).

Also what if the object hadn't been loaded yet - surely a nasty crash, although this probably isn't a big program. Anyway I decided against it. So we go to possibility two (constraining my needs).

*Possibility 2*

Make objects responsible for saving their own children.
They load them, sort out the delegate (using a simple switch statement and some of the code I've implemented with delete) and then add themselves as parent (using the code that was added with delete functionality)


So the second possibility was more to my taste. It seems to work pretty well, too!

Why would you ever want to load and save time events?

You might not! In fact it's entirely possible that you can get away without ever needing to do this! But let's say you wanted to allow saving during combat.

You need to save the current attacks and when they'll fall. Has the magic elf finished concentrating on his battle winning spell - that sort of thing. Of course if it's turned based and not using time events for battle stuff you don't really need to either.

Another example might be a timed mission. If the bombs going to go off a six. You really should remember to save that.

If your world is going to be quite dynamic though - you are going to need to save your time events.

Final Note

So there's one issue I just came upon today that I thought would be worth mentioning.

A problem arises if you want a TimeEvent to create another TimeEvent.

And we all want to do this because it's groovy :D First let's go ove why there's a problem then the solution.

The why. Well the clock trawls through all it's timeEvent at once. It's in the timeEvent queue. If one TimeEvent says "oooh let me add a new TimeEvent" - there's a problem. We're trawling through the queue we can't change it's size mid-trawl. If you try to do this you will get a vague error that will leave you midly baffled.

So the solution follows much the same pattern of how we kill TimeEvents (using a killflag). We add bool ExecutingTimeEvents. This is set to true at the start of the list and set to false at the end. Then in the add a time event function before we add to the TimeEvent-Queue we check if we're executing. If we are we instead an to a second queue called something like pending. Then after we trawled the entire list we take all the TimeEvents from pending and put them into the actual list and then sort it.

And that's the fix now you can do more cool stuff.

Monday, June 27, 2005

Setting Flags

I've been curious about how to flags with bitwise operators and all that for ages but I've never really looked into it.
(Or ever thought up the proper search terms - I guess bitwise operators would have been a good one oh well).

Basically it's how to write setup code. I'd seen it in Windows and in DirectX

windowStyle = NoBorder | ReallyShiny | SlightlyBlue

I always thought that would be quite useful. Anyway here's a nice little article on how to use them.

Currently I messing with Time and have decided that the singleton I originally made was the wrong way to go :D There's still some static stuff in the new class but it's not as singleton heavy as before.

Sunday, June 19, 2005

Keepin' On Keepin' On

I now have a nice XML configuration file to store how the menu should be presented to the user. First (as nearly always) I created a small tester program and then I wrapped it up into my main code.

I also noticed this which is maybe the C# port of Ogre (which I'm interested in, but would be even more interested in if I saw more things developed for it). I'm not sure. I was looking for GUI stuff. It seems interesting but the site itself is extremely sparse on documentation. It's something I want to look further into.

I'm actually zipping down some of my older to-do lists. Which means the end of stage two is in-sight. The end of stage two means something that looks vaguely like a game.

The stuff built on top of my GUI library needs to be tighten up. The GUI library itself needs to be wrapped up into a dll file. This may be what I focus on next. For this weekend I've really done what I set out to do.

Saturday, June 18, 2005

Lua Console

It all works very nicely in my main game. The only problem is the GUI libaries input needs adjusting. It works fine for my keyboard but I think it may have problems with other keyboards (@ sign being somewhere else and that kind of stuff).

It's nice to get that in. The next thing I'm going to be doing is getting the menu system fleshed out. I may put some screen shots up when things are looking prettier.

Friday, June 17, 2005

The Weekend.

Well my console is working nicely in my main game build.
This weekend the main goal is LUA intergration which should be a snap. I may even extend my Lua article.

I've reworked most of the second game programming for monkeys tutorial so it works with the latest SDK and the code examples are prettier and better formatted. So I'll upload that soon. Of course I still have to do the first one and review the rest :D

Tuesday, June 14, 2005

Well my console is practically finished (working and can be used)



I did mention that I was going to give a tutorial but I'm not! It required far more work than I expected. (to do it the way I wanted that is. Basically I first built a very nice GUI library - totally modular and apart from my code. Then I tested it with my code and resolved any problems. Then on top of the library, again away from my code I wrote a console object. I borrowed some code from my earlier attempts and finished with something I think is very cool).

The last step is to link it entirely with my code and LUA. This will be easy.

Everytime a command is entered a "Command Entered" delegate is fired. So I just hook this up to a function, do some preprocessing for special commands (like reset_lua or load_map_maker) and then pass it to Lua to sort out. All Lua's textual output can go through the consoles output pane.

There's a command history which works well. I've locked the number of items at 10 though this is invisible to the user - apart from they can only go back 10 steps. This is a simple const and is easy to change. I'd just use an array list or something but unbounded memory (even as an unlikely a problem as this) always worries me, so I've clamped it down. 50 should be more than enough for the final thing.

It can have any kind of image background and I think can do transparency and alpha blending with an extra call. (as supported by GUI library) Fonts and colours can also be tweaked in similar calls. I'm happy with it enough for my main game now.

Functionality wise it's the quake standard. It doesn't display all key strokes yet but this is just a little fiddling with the text box class. There's an input pane, pressing enter on this transfers the command to the output pane above it. This is all placed on a console window that drops down from the top of the screen on a keypress.

Main game itself is looking a lot better lately as well. Of course you can't actually play at the moment but the start menus are far prettier :D The next stage will be fleshing out a good proporition of the menu system before you get to the game. This will allow testing to go a lot quicker.

Sunday, June 12, 2005

Frame Independant Movement

I've just about caught up on sleep, Tokyo was crazy, so I'm ready to do a little programming again :D

I'm still fine tuning my quake like console. I want to have frame-independant movement for my drop down console. This makes sure that on all machines the movement is relatively the same. On machines in the future extra speed won't mean an unplayable game. This is taken care of in a round about way in the game animation code in the Game Programming For Monkeys tutorial. Here though I'm trying to create a modular library. Code re-use can be done but code sharing is a bit of a no-no. My timing stuff is a bit heavy for a light GUI library. I want a simpler solution.

As with a lot of common problems Gamedev has a tutorial. This tutorial is by Ben Dilts thanks to him we can all whip something up much faster.

Of course as with most tutorials it's in C or C++, here I present some slightly modified code for C#.

internal sealed class FrameRate
{

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
out ulong lpPerformanceCount);

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(
out ulong lpFrequency);

private float targetfps;
private float fps;
private ulong tickspersecond;
private ulong currentticks;
private ulong framedelay;

private float speedfactor;

public float SpeedFactor
{
get{ return speedfactor; }
}

public FrameRate(float targetFPS)
{
targetfps = targetFPS;
QueryPerformanceCounter(
out framedelay);
QueryPerformanceFrequency(
out tickspersecond);
}

public void SetSpeedFactor(object sender)
{
QueryPerformanceCounter(
out currentticks);
//This frame's length out of desired length
speedfactor = (float)(currentticks-framedelay)/((float)tickspersecond/targetfps);

fps = targetfps/speedfactor;
if (speedfactor <= 0)
speedfactor = 1;

framedelay = currentticks;
}
}


You can ignore the internal sealed stuff. Also I didn't want to import the LARGE_INTEGER definition so I just used unsigned longs. I hope this doesn't have any awful repuccusions. I feel there should be some use of mod in there to make it all perfectly safe forever and ever. If any one wants to make this addition I'd be interested. (This is to do with the interger getting to big and resetting at some very large number)

Oh so you called SetSpeedFactor everygame loop. Then when you want something to move you do the following.

Robot.Move(5 * framerate.SpeedFactor);

Simple. Now your code is frame independant.

Wednesday, June 01, 2005

Back to the roots

Originally I just used this blog as some way to monitor my progress. This is all that this post is about!

Well pretty slow but steady I'd say. I was at a bit of a rut and what was required was basically a decent GUI. I'm well on the way to finishing a nice modular C# DirectX GUI. It works very well and very easily. Currently it has windows, buttons, labels and a textbox.

I've built it from the Sprite helper class. And I'm going to use this to create a drop-down console rather than the other more direct way I previously had in mind. (That one was practically finished but it became apparent that soon I would need lots of GUI bits).

I've also implemented some of the bare bones of my menu system and this will grow as the GUI is polished. I actually see the next big step being combat but that's a ways off for now. I'm going to have a hopefully very powerful, very easy to use ingame editor this will all be based around the script-enable console.

Lua scripting is no problem but some of the latest Direct SDKs have a C# scripting example and that may sound more attractive. Anyway these decisions should be come pretty soon.

I'm in Tokyo next week for meetings so I don't think too much will get done super-soon but I'm happy with the direction and pace. (next time a lot more planning and I'll have it all written up in dotProject before I even start to code :D )