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?
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...
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.
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.
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.
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.
No comments:
Post a Comment