Montag, 4. Juli 2011

Coding Corner - Coroutines

Hey there,

one thing I really love about the creation of video games is, that it is an interdisciplinary process. To cook up a game a mixture of graphics, animation, story telling, character development, sound, music and of course a great deal of technology is required. All those things boil down to an interactive medium that in the end brings a fun experience to the one who plays it. I doubt that this is something that you can say about developing business solutions ^^

One thing I've learned is, that it is of utmost importance to implement all those ingredients into the game as fast as possible and can be experience and tested by those who have actually created the particular asset, may it be graphics, animation, visual effects, sounds, music or code. This will let your team get a better understanding if things work as intended, their vision of that particular part of the game.

That's one of the reasons I like to work with Unity - despite its weaknesses, it gets your assets into the game - fast!

Since this is my little coders corner of the blog, I'll write more about the technical side of the creative process. There might even be some code-snippets here and there. So the faint hearted have been warned!


So lets start:


What are co-routines? Wikipedia says: "Coroutines are computer program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations".

Ahhh, yep, so what exactly can I do with them?

Imagine you find yourself in the situation where you want to show a nicely animated dialog to the user. It basically goes like this: play intro-animation, print the text, start the talk-animation, stop the talk animation, wait for the user tapping the screen, print the next dialog-line and so on.

In the traditional flow of execution in a video game you can't just wait for an animation, because that would stall the rendering, you always need to finish your computations in 1/30th of a second so that your updates can be shown to the user. So to accomplish the above task you wouldn't be able to write something like:

animation.Play("intro");
while ( animation["intro"].isPlaying )
do nothing
print text


you would keep executing the while loop forever, because your animation isn't even updated. So what you might want to do is something like checking every frame (polling) if your animation has finished and if so, continue afterwards. You have to keep track what you're about to do with state-variables, timers and so on. This can become messy faster than you'd think and makes the code harder to read, because you have to track the state of all those variables.

But fortunately there are co-routines that allow you to resume the execution of your logic at certain locations. So while some lines of your function are called in one frame the next ones might be called in the next frame. In Unity it is done like this:


C#:

IEnumerator MyAweSomeCoRoutine()
{
animation.Play["intro"];

while ( animation["intro"].normalizedTime <= 1.0f )
yield return new WaitForEndOfFrame(); //execution is interrupted here
and picked up in the next frame, awesome!

animation.Play["talk"];
// ...
}


and in your Start(), or where-ever you want you just call

StartCoroutine( MyAweSomeCoRoutine() );

Other languages and environments support this concept as well, but you might have to do a little boilerplate coding, even though it's not that hard to do. python supports the yield statement out of the box. for c++ there's Win32 fibers and libcs swapcontext ( or just use Boost.Coroutine (http://www.crystalclearsoftware.com/soc/coroutine/index.html) ).


If you got hold of this concept, implementing logic constructs like the above becomes fast and easy. So you can move on to more exciting things like implementing this new Laser-Gun you just got some nice particle-effects from your artist.


Thats it
tk
Ben

Keine Kommentare:

Kommentar veröffentlichen