Friday, November 19, 2010

The Vortex of Doom

A while back, I mentioned that my doom-ometer reading was at a 10, so what was I talking about?  Well, first, let's talk about what doom is.

There's this horrible thing called the Vortex of Doom.  This is a place where you have too much to get done, but you feel so doomed that you get nothing done.  Since you're not getting anything done, you feel horrible about not getting any of your to-do's done.  Since you feel horrible, you're not getting anything done.  Rinse.  Repeat.

The Vortex of Doom is very hard to get out of since it is a self replicating cycle.  The best way to escape it is to just stop.  Give something up, take some time out, and then get back in the game.  However, the Vortex of Doom is very sneaky - you often don't realize you've fallen into it until it's too late.  Once you're in the Vortex, you become blind to many things, including the solution.

So how do you avoid falling into the Vortex of Doom?  First of all, manage your time.  Less obviously, you need to monitor how doomed you are.  If you're aware of how doomed you feel, you'll be a better judge of when you need to take a break or some time off.  This is where a doom-ometer (alternatively doom-o-meter or doomometer) comes in.

Enter the doom-ometer.
A doom-ometer is a way for you to measure how doomed you feel.  As such, you should be the one to make your doom-ometer.  Pictured above is my Doom-ometer from last year - it ranges from zero (no doom) to ten (overwhelming doom).  It's simple with a rotating arrow.  Creating and personalizing our doom-ometers was a great team meeting - very similar to our meeting spent personalizing our sprint board.  By attaching these to our sprint board, we could update our doom reading at the start of each meeting during check in.

Another example of a doom-o-meter, more in the style of a pressure gauge.
The idea is that once you're doom reading hits a certain threshold, you should take a break.  In fact, the team will force you to take a break.  We agreed early on that if our doom level ever reached nine or more, then your task for the meeting was to take time off.  It didn't matter if what you had on the ToDo section of the sprint board was critical - you were excused and covered for.  Luckily, we only had to call in this rule a few times.

Our third team member's thermometer style doomometer, complete with paper slider.
By taking that time off, you would have time to recover and get away from the Vortex of Doom.  It was guilt free time off - we had agreed on this early on in development, so even if a milestone was just around the corner, you were good to go and relax.  If it had to get done, someone would cover for you.

Overall, the doom-ometer was a great tool for our team.  It allowed us to monitor how each of us was holding up, as well as when we just needed some time off.  It was a fun meeting making them, and it added a lot to our sprint board.  Having our doom reading as part of check-in each meeting was a nice way to sum up how all the 'I feel's.  Of course, it also made each of us aware of our internal state - and knowing is half the battle!

Thursday, November 11, 2010

Overnight Development - Crunching for Engine Proof

Let's face it, sometimes you just don't have time to work on things right now. You push off what's not due tomorrow, and then it keeps getting pushed off for other assignments. Suddenly, you realize that what you've been pushing off has come up and it's due in the next couple of days, and you've got three days to do what you were planning on finishing over the course of three weeks.

Welcome to DigiPen, a balancing act of time management. You've got a game to work on, and four or five other classes worth of work on top of it all.

Yesterday was the presentation of Engine Proof milestone, and three days before that, I was sitting on the Tech Demo of my game.


How it all started on Sunday.

For those of you not in the know, a Tech Demo is really just proof that you've got some of the basic technology working for your project. Engine proof is meant to show that all that technology is working toward your project. After Engine Proof comes First Playable, where you show the "first" version of your project itself (i.e. a full level of your game). Since I'm on a solo project that I only plan to work on this semester, I need to deliver the next milestone, such that my Tech Demo was really an Engine Proof. More specifically, the player could run...



And jump...


And glide...


And hide...


And even win...


As you can see the engines are working together to give the general idea of what my game is going to be. So, for the Engine Proof presentation, what I needed was a First Playable. That means that I wanted to show my first level from beginning to end, complete with splash screens and a main menu. The first that I needed to do was create a level system and move all of my game code out of the core loop and really just do everything in a better way. so, here's what I came up with.

Ta-da!.... Wait, isn't that the same thing?

Okay, so it looks no different from my starting point, but that's the point. What you don't see in that screen shot is my level architecture working in a way that makes it indistinguishable from when I was updating each character in the game's update loop. With a level system, I could add more levels, in particular levels to handle the splash screens and main menu. However, that would have to wait. First, I needed to move PJ (the kid in pajamas) off of some invisible line and onto an actual platform.


That's more like it!

So what cosmic significance did this have for my game? Well, it's a platformer, so unless I feel like making PJ's movement code handle each platform individually, I needed it so that he could see if he's landing on a generic platform object and move around on said platform. The old way, featuring magic numbers and invisible lines, would require hundreds of lines of bad code that would doom development. Anyway, what's next?


Naturally, moving platforms.

Of course, once we get platforms into a game, the first feature everyone wants is moving platforms (or at least that's what every ProjectFun student wanted during the platformer). Rightly so, moving platforms are cool - they add all sorts of neat options to the level design. All I need to do is add the platform's movement vector to PJ's right? So, I started with the vertical. It seemed to work...


Nope, definitely not working.

So what's the problem? He moves with the platform just fine, and he could even run back and forth. Why can't he jump? Basically, I had done some silly things when he was running along the invisible ground plane, so now it was interfering with the way it should work. Easy to fix right? Well, yes, but not if you go about it the wrong way. That wrong way would be just removing some odd multiplication and hoping it works. That sort of thing causes horizontally moving platforms to not work quite right...


Why didn't I just add the platform's velocity like I said to?

Alrighty then, got that fixed by going with the original thought I had. I'm still not sure what happened between me thinking it through and implementing it. Anyway, moving platforms work (I made sure to test in all directions). That takes care of the platforming part about my game, so onward to the scrolling!

Scrolling involves getting some sort of a camera going along, and as far as I know, Flex handles everything in camera space. So how do I move the camera when the camera is always at the origin? Easy, I move the world around the camera in the opposite direction. Just like how the ship in Futurama works, right?


Well, it almost works.

Mind you, that little bug there is after quite a few other silly issues (like the camera just taking off on it's own). Sadly, I don't remember what I did to fix it - I had thought my screenshots would remind me. I also thought I'd be writing this three days ago, so...


Oh look, I fixed it!

Alright, camera's working, moving platforms are working. Let's make sure that I can move the position of my camera down a ways, place some platforms, and let's make sure it's all working as planned. At this point, I through some platformer down as a horizontal plane and ran around. So far so good. Then I tried a stair-step formation.


Uh-oh. Why's he jumping once he gets close to the next platform?

So maybe there's some issues with platforming still. After looking at the platforming code and face-palming again, I figured out that I had placed some of the "stop falling" code in the "on ground" state - such that he would see the next platform and suddenly put himself on that one.


There we go. Able to jump and no teleporting issues.

So, now platforming works, right? Moving on to walls. Why walls? Well, I wanted to have a wall within the first screen of my level that keeps players from moving on without understanding how to jump and glide. Knowing how to do that is important for my game, so with a wall, I can keep players from moving on until they figure out how to jump over it.


Oh hai wall! I can't run through you? You're tearing me apart, wall!

Walls working, check. Reference to The Room, check. Now let's start laying out my level. As part of being able to jump over that wall, you have to jump up some platforms. However, once again, my platforming controls were off: When you jumped from a higher platform onto the ground below while gliding, you would just pass right on through.


Aww, c'mon! Off by one error...

Alright, so platforming works now, right? Okay. Let's get that wall set up. And you know what, let's get some smaller platforms in so that it can all appear on the first screen.


This is the basic controls tutorial. You must use gliding to get over the wall.

Quick lesson in game design: Let's say you want to teach the player something. The best way to do this is to tell them, and then make them prove that they know it. The way to do that is to make a challenge that they can only get through by using what they learned. Here, I have the basic controls test: The player can only get through here by moving right, jumping up to the high platform, and then gliding over to the platform on top of the wall. After this test, I know that the player knows the basic controls. How can I make this better? I need to add a sign reminding the player of what the basic controls are - which I plan to. Now that they know how to move, jump, and glide, what's next?


No one lives forever!

Immediately after learning the controls, I put a second test. Again, I need a sign to instruct the player, but here's what I want them to learn a this point: Falling in pits is bad. If PJ falls into this pit, the player restarts the level - a minor punishment but it should do well to get the point across. Note that PJ can get over this pit with just a jump - he need not use his blanket as a parachute to glide. However, no harm done in gliding, right? Correct.

As is, that pit is placed so that if the player jumps from the platform, he lands before the pit. If the player glides from the top of the platform, they make it past the pit, but not by much. This makes it so that the player should not land in the pit by jumping from the platform. Again, this is deliberate. I don't want the player to feel cheated because they jumped off of the platform at the end of the jumping tutorial into a pit. That would just suck. So what lies beyond this pit?


Oh noes! A monster!

Again, I need to add a sign to instruct the player how to succeed at this challenge, but again, they cannot succeed without understanding their abilities. To pass this monster, PJ must hide under his blanket. The player cannot move while hidden, so they have to use a bit of skill and timing to make it through. Again, the point is for the player to learn how to use their hiding ability. If they get caught by the monster, they only go back a little ways, so it's not a harsh punishment if they fail.

As before I placed this tutorial very carefully. The player cannot run into the monster from jumping over the pit. If the player uses a basic jump to get over, there's plenty of ground to cover before the first monster. With a glide, there's still enough space that the player will see the monster ahead of time. What about gliding from that one platform back there - the one above the wall? I thought of that too. Gliding from that platform gets you about where you would land after a normal jump over the pit, so there's plenty of ground to cover still.

With my tutorials done, I'm sure at this point that platforming and camera movement are working properly. So let's start adding in all the elements of my level...


Sweet, seems to be working. Almost.

At this point (about half way through putting my level together), I started to experience slow gameplay. This lag was not good, especially with only half of the level implemented. I decided to just push through it and finish my basic design. I could look into optimization later. So onward I went with my level.


Hurray for multiple paths through the level!

So far, so good. As I got it all in, I needed to make sure that I could beat my level. I still wanted to be able to win the game at the end of it all.


This was one of the trickiest parts of the game.


Yay! I did it!

With my level done, I took a brief look at optimization to get rid of that lag. I tried removing most of the walls since only a few were used to actually block the player (the others were largely there for asthetics). I made physics work a bit faster. Ultimately though, I was still getting lag. However, I didn't have time to track it down quite yet, so I went ahead and put the splash screens together.


DigiPen's splash comes first, as required.

Finally, all that remained was getting the main menu together using some placeholder art. However, I realized at this point that my original plan was likely not going to work (which I later realized it would have, but it would have been pretty ugly). I started adding mouse controls into my input manager, thinking that I'd have it done no problem. Then I went into testing.

The Play button didn't work. So I threw a break point into it's behavior after checking if the mouse had been clicked. Ran it, clicking all over. No break. If the behavior isn't returning true on the mouse click when I click the mouse, then it must be an issue with the input manager, right? So I threw a break point into the IsPressed function. Nothing. Threw break points into my mouse event functions. Nothing. Basically, I couldn't see the mouse at all.

My first round of searching revealed nothing useful. No one was having such a simple issue as an event listener not triggering. At that point, I decided it best to take a half hour break. When I came back, I tried again with Google, searching some barely different keywords, coming to the livedocs for Action Script. Right there was my answer: only certain objects could search for mouse input.


It works!

All that remained was to add some sounds. The first issue was music. I had spent close to three hours looking for fitting music over the last week with pretty much nothing but some okay fits. I had settled on some music from the ProjectFun Workshop library - which we DigiPen students return to time and time again. However, there was a slight issue I had forgotten about.

Flash can't play .mid. Also, I have nothing that can convert .mid to .mp3. With no choice left but one of the less fitting music tracks, I attacked with Audacity (the audio editing software), coming up with a cut of the more fitting bits that looped nicely enough. Once I got it in the game, I was pretty pleased, actually.

As for sound effects, I dove straight into the Workshop library. Sound effects were in .wav format, which Audacity can convert quite easily. Luckily, there was a nice soft effect called "Grass4.wav" that worked out for landing from a jump.

And there it was, my next milestone hit at 100%. Satisfied with my progress, though still worried about the lag, I tossed it up on the game website in preparation for my presentation. On the web, the game ran without the slightest hint in lag. Basically, when I had been running it before, even in release mode, it was using the debug player. Lag was gone, the build was uploaded, and all that remained was to throw a presentation together.

So what's the real moral of the story here? It definitely is not procrastination - that's what got me into this whole crunch thing. Time management? Not so much. I guess the real moral is to have a plan. If I hadn't had my level designed on a whiteboard before hand, I would have been screwed - that alone took about four or five hours to get right. The entire time, I knew what I wanted my game to look like, and I knew exactly where I wanted to be.

Also, having a solid architecture helped tremendous amounts. By using a component based design, I was able to make each of my levels quite quickly and near painlessly. My engine was designed so that I could attach behaviors as need be, such that adding some debug movement would take all of five minutes - and that five minutes includes starting the development environment and testing.

Finally, knowing when to break is key to crunching. There is a point where you're not going to find the answer if you just sit there. There's a time when you're just not going to get anything done. Once you're aware that you've hit that point, go grab a bite to eat, talk to someone about your problem - or about something else. Your brain just needs a moment to reset. Once you come back from your break, you might just have an epiphany or otherwise. You might just be attacking the same exact problem, but you'll be doing so with a fresh outlook. Sometimes, that's all you need - a chance to step back, take a breath, and look at the big picture.

Monday, November 1, 2010

We Interrupt Your Regularly Scheduled Broadcast...

This Week In DigiPen has been postponed until the author escapes the Vortex of Doom. We apologize for this inconvenience and are working to correct the issue.

That's the plan anyway. Here's the short version.

Week 7
Monday - Stayed home on account of not feeling well.
Tuesday - Boerkoel homework due, so very little sleep acquired.
Wednesday - Tech Demo of game due. (Wanna see?)
Thursday - Boerkoel midterm.

I don't really remember what happened after that... Yes, his tests are that intense. Did I mention it's Number Theory?

Week 8
Monday - Working on AI until 9am Tuesday morning.
Tuesday - Go to math at 10am. Midterm review for graphics and sound.
Wednesday - Feeling pretty lousy and shaken already, I went through a mock interview in game class. It didn't really boost my damaged confidence. Went to the Microsoft interview prep session hoping it wouldn't take too long and I could study before it got late. I was wrong.
Thursday - Feeling down and out already, suffered the graphics midterm - which was 19 pages long (not multiple choice mind you). Then sound midterm happened - which was better, but still kind of harsh.
Friday - Microsoft interview. It went okay, but I'm not getting my hopes up. I don't think I could stand to have them dashed.

Current status: Burned out hard.
Doomometer reading: 10.

Coming soon! Further explanation of doom.