Friday, April 13, 2012

Crunch Mode

So it beings.

The beginning of the end.  The last push, the final battle, down to the wire and everything is on the line.

Well, not yet, but it's getting close to being that time of the year, and my college career.  That wasn't really supposed to rhyme, but for that you can blame David.  For some unbeknownst reason he has the uncanny and awesomely hilarious ability to rhyme in the character of the Lorax.  Yes, the one from the Dr. Suess book.  Some of his friends are a little annoyed by it, but I am under the impression that it's downright hilarious.  I wish I had that kind of quick mind to think of rhymes on the spot.

But there is a very good reason I'm in game design and development and not rapping, or singing, or majoring in math, or science, or business or medicine.  Because I'm not good at all of those other things.

The current stance of the game is interesting.  We are posed to submit to IndieCade to try and garner some attention for this little gem, but there are a bunch of hoops we have to jump through in order to get it submitted.  Same goes for Zombie yoga, we are both pushing for the 15th deadline.  Which is Sunday.

Yikes.

Better get crackin'

That, and on the rest of my homework.   Multiplayer Game Development, which should not be left to the last day, math (yuck) and Graphics, which was taught rather poorly to me and has resulted in a confusing mess.  I think I know what everything should be doing, but that doesn't mean it actually works according to plan.

This is no bueno.

Anyway, the game went through a small playtest on Thursday, and I think it went very well.  We have a lot of good data from the test, but we also have a lot of work to do.  I feel as if no game I ever work on will ever be finished, which is a very scary and discouraging thought.  I've only ever finished one game.  I've started many, but school and technical limitations have stopped the growth of many.  When I taught myself programming, I hit a wall of knowledge and understanding.  Now I'm hitting walls of time, priorities and some technical limitations.  If I just had capstone, this game would be sailing along, but I have to balance this with many other competing factors, I think the end result will just be little to no sleep (it is darn well near two right now) because we want and we need this game to succeed.  It won't bring in cash, and it was never supposed to.  This game is out there to show that we can be innovative, that we can find the fun in anything and extract that and give it back to players in a great package, and that we can make games, and that we are good at it.

I added some things in recently, mostly a lot of playtest tweaks, but some new features such as earthquakes and combo systems.  Brian is working on reducing and restricting the incoming enemy waves.  Justin is working on a new batch of art for the change in story direction that fits our scaled-down version of the game.

Just talking about this makes me nervous now, I feel like I should always be working and never be relaxing anymore, I just can't afford to do something like that.

Man, I can't wait to get back to judo, I really need that back in my life...

SOS.




-Kev

Tuesday, April 10, 2012

Humbug.

Normally I get hyper-focused at around midnight.

I don't know what it is about this week but it has been a mixed bag of really awesome and really crappy events, all in all I feel very drained and unfocused right now.  Spending almost my entire Easter Sunday trying to do math definitely did not help the matter at all.

And usually I eat quite a hefty amount.  In the past week I don't think I've had more than two meals in a day.

Now, I understand that's plenty of food for a person to survive off of, but considering my usual amounts of consumption this is very low and perhaps not a bad sign of... something?

On top of that I got chewed out by one of my favorite professors today.  The thing is I wasn't yelled at or reprimanded or given a stern warning or a bad grade or a bad critique.  Instead he expressed his extreme concern about the progress of our game.  That's a lot like your father sitting you down on the couch and explaining that he's not upset, he's just deeply disappointed in you.  Then he leaves the room and all you can do is hang your head and feel utterly devastated.

It was pretty much like that.  He was very concerned about my involvement in Zombie Yoga and if that will take over the Capstone project.  I know he's right, I know I have to be careful about how I split and spend my time.  But I'm giving all of my projects all that I have, I'm coding almost from sun up to sun down, especially now that my other shoulder is bum and I can't get out any of my code aggression in Judo.

I've been getting the small things wrong, bad variable names, bad values, not checking value ranges or forgetting basic features of IDE's and engines.

In my math class I'm flying through the examples the teacher gives with ease, but the homework has been thrashing my behind by being long and complicated.

Zombie Yoga had me smashing my head against the wall until just today where just barely in time for a playtest I got the new code in the game.  Only to have it not work for our lead designer/professor, Doris.  It worked for everyone else, but I couldn't even give Doris the ability to play her own game.

I had a small bug in the combo system that I've been developing for our Capstone Project that by all means should not have existed.

But I got Zombie Yoga working, I fixed the bug and within an hour or hour and half I had gotten the combo system visualized nicely and even added in features to the system in just 15 minutes.  I just wish I could be intelligent and responsive all the time, instead of only every once in a while, and that I could put in enough quality work for Zombie Yoga and Capstone to co-exist peacefully on my plate of ever diminishing time.

In general, I feel like absolute garbage, and for even more reasons than just being sometimes-bad at what I love to do and then for disappointing one of my favorite professors, but that's all I'm going to get into here.

Bah Humbug.



-Kev

Saturday, April 7, 2012

On Screwing Things Up

Mix of code-related and life-related postings today!  Mostly because I'm at similar junctures in both, or at least that's the way it feels.

First the code stuff, since that is the purpose of there 'ere blog in the first place.

If you asked me what my favorite part of programming was, I'd say it would be creating new and fascinating worlds, and learning how to do so in a faster, better, and more intelligent way.  If you took a look at what I do mostly when coding, it would appear that my favorite coding pastime would be screwing things up.  Most of the time, it's intentionally too.  I have a system in place, it works, it preforms as I need to, and I won't be happy with it.  I'll tell myself it could be more flexible, it could be faster, it could be more abstract, so I intentionally break it and try to rebuild it.

First lesson of the day, if it ain't broke, don't fix it.

Second lesson of the day, if you really want to fix something, start fresh and don't try and mold what you have into what you want to be (at least coding-wise, I'm not saying find a new girlfriend or wife, relationships don't work like programming stuffs... I don't think, it's been a while)

Molding the old to fit the new is a bigger pain in the rear than starting over.  That stands true for most anything, unless, perhaps, if its and entire huge project.  Even then, though, starting fresh is beginning to grow on me.

All I wanted to do was make the combo system I have more flexible, account for more options and situations.  So I had to make a bunch of changes that killed the system, so I couldn't test iteratively (misspelling? Not sure) and I had already propagated said system throughout the rest of my code, so I had to hunt down those spaces and make changes as well.

Then, when I had it working...

Perforce overwrote it all.  There were conflicts in the files that needed to be changed, so I went to press resolve and instead hit revert.  I spent all afternoon on this instead of my homework, and now I have nothing to show for the day.  Wonderful feeling, enough to make me sick to my stomach!

The thing about coding is, however, I'm rarely afraid of screwing things up.  The lessons I have learned in coding don't always seem to apply to my life lessons.  It's the same reality, though.  If you really screw things up in your code, or in your life, it's going to suck.  There's no getting around that fact, it is going to be terrible.  But it's not going to be the death of you.  Unless your mistake was crossing a mod boss or pressing the "do not press" button at a secret government facility.  In which case you probably killed us all.  Thanks.

My issue IRL is that I'm usually too cautious and concerned about making a mistake and suffering the consequences that I move in order to stalemate decisions instead of actually making them.  The problem is life moves forward, and if you keep side stepping you never actually get anywhere.  Even falling on your face is getting you headed in the right direction.  Take your pick, martial arts, relationships, other life choices, etc.  I don't want to fail, so I rarely take the risk to succeed.

This must stop. Just treat life like a program, plug your nose and dive in.  You're going to come out on the other side with experience, at the very least, and that's what makes up your life, a collection of experiences and stories to relive, relate, and pass on.

As they say, go hard or go home.

Though I wouldn't mind being home for Easter.

-Kev

Thursday, April 5, 2012

Rehash, Reuse, Recycle... Recreate.

Whoa nelly are there some awesome things to post about today.  Kinda/sorta.  Actually I'm not allowed to talk about most of them... Which means I'm potentially on the right track for game development if I am being included in hush-hush things.  Suffice to say, I really want to spill the beans about awesome stuff, but it's mind over matter, sorry everybody, I can't do that.

In vague terms, though, I can say that Kinect is making leaps and bounds within Zombie Yoga, and as of a few minutes ago I got the new pose system that David and I have dreamed up working full throttle in our C# version of the code, and now we finally have a way to get this code ported over into the game engine so Kinect plays nice with the rest of the game.

And, as I mentioned in my other shorter post, David and I received affirmation that we are not, how you say, doin' it wrong when it comes to the Kinect.  Lots of people are hacking away at this thing just to get it to work, and currently the best and easiest way to do this is... however you see fit, however you can fit it, however you can get it.  Anyway you want it, that's the way you need it... fill in the rest!  And our new system, though not thoroughly tested yet (It's just been me our little (yet huge... it's a funny room) studio apt. trying some whacky poses.  So far it's more forgiving (which, when it comes to the Kinect can be a good thing) and easier, which is all that we ever really wanted.

How does our new system work as opposed to our old?  Well, for starters our old system was based off of joint proximity, how close one joint was to the other.  That's all that's needed, right?  Well several problems arise from this, stop me if you've heard this before.  Or... I guess skip to the next section unless you can communicate telepathically with me RIGHT NOW. Oops, you are reading this, I posted it, too late.

But seriously, it wasn't a bad system... if you didn't have a lot of poses to check and everyone in the whole wide world was the same size.

We solved a lot of our problems pretty ingeniously, we had a complex yet effective means of eliminating "bad" poses when checking a player's pose, using outlying points to quickly scan through a list of poses and almost recursively loop through down these outlying points into the center positions (hip location and shoulder location, etc), each pass eliminating more and more poses until just one pose remained.

We also had a trick in terms of scaling the poses to be adjusted to the player's individual size.  We got a calibration before the player began the game, and compared these limb lengths with that stored in our pose data.  Every posed we had queued up then had it's limbs scaled appropriately, according to the calibration we just took and the calibration of the original yogi.

This system, however, only worked in practice. Kinect kept stepping in and kicking our butts, either by having a bad value during calibration (Left Hip was once (-infinity, 5, 5)...) or by it's lovely method of "inferring" joints.  Kinect doesn't always know exactly where your joint's are, it gets a rough guesstimate (Better than nothing!) but at times this could result in limb shortening or lengthening in the 3D skeleton data.. which is fine, if everyone's body types got this limb shortening at the same time for the same poses, but they don't.  So when the scaling was introduced with certain poses it would screw the rest of the data up by this limb shortening/lengthening putting the Yogi's original joints in strange, wild places.

There's ALSO the issue of player offset.  The Kinect returns joint locations as position in 3D Cartesian space (X,Y,Z, think graphing, remember High School math? Yeah, you DO end up using it for something) in terms of meters from the Kinect.  Which means if I'm in pose A and I'm a foot to the left of where our Yogi originally had the pose captured, then you would not be in the correct position.
This was a relatively easy fix, if you know vector math or understand 3D coordinate space all we did was make each of the joints relative to the center hip, or took each joint position and subtracted the center hip to make everything in "local space" as opposed to Kinect space.

Add, on top of this, the fact that Kinect loses your joints.  This is not a matter of if, but when.  The Kinect does great considering the fact that it's pretty much still just reading one dimension.  The problem is the minute things (read: limbs) start obscuring body parts, the Kinect beings to give it's best guesses as to where things are, which end up being really awful guesses.  So half (more than half, at this point, actually) of our poses involved a very three-dimensional stance.  Warrior One, and Warrior Two.  Google them.  Have safe search on, too.  You shouldn't need to, but I found out the hard way the other day that even something as innocuous and/or nerdy as C-strings (an oldschool format for printing lines of text in C) can give you very, very, very uncomfortable results.  Here's a hint, don't ever google c-strings.

Holy smokes that's a lot of workarounds Batman!  Why in the world did you do that?

Well considering Kinect only gives joint position and not rotation, it appeared to be the most straightforward and logical solution.  And in certain circumstances this would be the ideal solution.  For a small number of poses, if we had all of the tech we wanted down (appropriate body scaling, effective elimination system and not Kinect giving us random bad data) it actually could have been a good and flexible system.  It's highly accurate, pose definitions could be kept as tight;y or as loosely defined as we wanted to specify.  It's static, but that's all we needed for poses.  Before we got into the muck and mire of Kinect work, it seemed like a flawless plan.

Given what I know now, I'd go back in time and throw my past self out of a very tall building to save him pain, agony, and sleepless nights.

So what's the new system?  The new system is a combination of several different things that we thought were "hacks" but tend to actually be industry standard.  That is to say fake everything.

We combine a pose flag system, which is just a fancy programmer way of saying we store a lot of true/false (or binary) values in a single integer (4 bytes = 32 bits, each bit can be a 0 or 1, giving us 32 compact and easily comparable true/false values) that tell us information such as
"Are the player's hands above his head?"
"Are the player's hands togther?"
"Is the Right hand forward?"
and etc. to ad infinitum.
(Actually only to 32!)

These are our first test.  The really sweet thing about bit flags is that comparison between multiple true/false values is really simple and really fast.  So we use the pose flags as our first order of elimination.  A pose has  a specific set of these very general flags that must be true in order for the player to be in the given pose.  Just because the player's left foot and hand are forward doesn't mean that they are in Warrior Two, but it certainly means they aren't in Tree Pose or Warrior One.

This is fast elimination and means we don't have to use that really complicated (and expensive) distance-check for each joint location (lota joints x lota poses = big slow down)   To be fair, David had begun implementing the pose flags system in our old game too, but problems plagued that implementation, starting fresh really helped us out.

Then after that we ditch position.  Position data means nothing to us, now, we use the positions of joints to get the angular distance between them, and nothing more.

This is achieved by getting the dot product between two normalized vectors.  The result is the cosine of the angle between the vectors.  We take these dot products at the main joints, the elbows and knees.  The second phase is checking the these joint angles (anywhere between 0 degrees, the limb is straight, and 180 degrees, which technically is impossible for the human body, but that's the limb bent all the way back so that, say, your wrist is pointing in the exact opposite direction of your elbow) so that means Warrior Two is defined by the fact that, say, your right hand and leg are forward, your right elbow's angle is 0 degrees (or a dot product of 1) and your right knee is around 90 degrees or so (dot product of 0)

This is a terrible approximation, don't attempt those exact angles or you might suffer some joint strain, but you get the idea.

Now that's getting closer, but as you can imagine that still leaves a fair amount of wiggle room.  Or far too much forgiveness.  I could turn my torso so that my hands are pointing off at angles, but the angle between my bicep and forearm is still the same amount, and my right hand is still in front of my body, I'm just all twisted up.  The last layer on the triple chocolate cake is another dot product, but this time it's in terms of the proximal extremities.  Basically where your biceps and quads point.  We take these and change them into normalized vectors, and then also store these in our pose file.  When you the player are trying to get into a pose, we check the direction of your biceps/quads and see if they match, or are close enough too, the original pose file's directions.  This ensures that players are keeping, generally, the correct form and are facing all the correct directions, etc.

There's still wiggle room, but at this point we've eliminated the major stuff.  And the nice part about working with pose flags and angles is that they are all relative.  Pose flags get set by comparing positions in the skeleton itself.  Is the Z value of this greater than the Z value of that?  It's relative, it scales with the person playing.  Same can be said of the angles.  Barring the few possible exceptions, people have the same degrees of motion, and, if you remember trigonometry, angles are independent of size.  A 60-30-90 triangle can be infinitesimally small, or colossally large.  Same applies to the person on the other end of the Kinect.  As long as they fit in the Kinect's FOV (Field Of View) then the angles between their limbs and the directions of their limbs are independent of size and it makes no difference to the Kinect.

We eliminated our scaling and our too-hardcore accuracy problems by a base shift in how we work with the Kinect.  Our new system still needs to be thoroughly tested, but it's already been easier to set up and work with than our previous iteration.

Professor Ed Keenan is right, don't be afraid to throw away code, and throw it away often.  You build something, it kind of works, delete the code and start over with a better understanding and I guarantee that you will have a better and easier time dealing with the code than if you try and forge through with your old base code.  Again, their are exceptions to every rule, but I used to never do that, thinking it was a cardinal sin.  Well, I've only just started, but it's helped tremendously.

Delete old code.  Re-work it.  You get better, faster, and the end result makes more sense.

TL;DR, I know, sorry, no doodles for now, it's 0230, I need to sleep before class tomorrow.

And finish that math homework.

Fiddlesticks.

-Kev

Tuesday, April 3, 2012

Late Night Lovin'

Okay, I'll be the first to admit that's a terrible name for a blog post.

Regardless, let's take a look at what I've done in the past week or so:

Watched all of the Game Of Thrones.

Watched Girl With The Dragon Tattoo.

Hung out with friends a lot.

Celebrated Ricky's birthday.

Uh, wait... I programmed in there somewhere, right?

Yes, a little bit.  I fixed a massive processor-sink known as the "pit of constant memory allocation"
Our game has these really awesome scores that pop up when you hit guys and deal damage, and I worked my butt off creating a really dynamic (if a little costly) means of adding in our own sprite fonts, since I find XNA's defaults to be... messy.  Limiting. Primitive. Primordial. Neanderthal.  Really not cool.

The default sprite-fonts in XNA are not nearly as bad as I've made them out to be, but there were a number of limitations that caused me to balk at using them.  
-They required the computer to have the fonts pre-installed or packaged with the game (not that bad.)  
-They require you to use and allocate and entirely different font if you wanted to change the font size! (Kinda but bad, again, a good programmer can create systems to allow them to easily make up for these, creating an array of sprite fonts at different font sizes to allow for rapid font-switching)  
-Creating your own font meant learning how to create fonts according to standards (The equivalent of asking for directions, which guys never do. ...Right? Wait, why don't we do that?)
-To my knowledge, you couldn't do cool things like rotation and flexible scaling.

Looking back, it would have been far, far easier to just implement a system that simply didn't try and deal with dynamic rotation and scaling.  But I will not be dissuaded from my goal.  I crafted a system that lets a person use an image to specify a new font (adding it in is rather tedious, though) and after it's been added any string can be created and scaled, rotated, color changed, it can check for collisions and evra'thang!  The way it does this isn't necessarily great, it creates a new texture2d for every unique string generated, but stores all previously generated strings in a lovely hash-table for quick look up and grabbing the next time the same string  wishes to be generated.  This resets every time the game runs, so in theory a dedicated programmer could pre-populate his list of textures with his desired strings and lookup would run just that much faster!  Hooray!

Anyway, the long point of my story was that I was generating a bunch of new calls to create these little effects that called my sprite font, created themselves and then deleted themselves within a hot second (literally) and then sat around, presumably on some duvet somewhere in the lobby of lost memory allocations, smoking a cigar illegally or drinking heavily, waiting for the Garbage collector to come along, and when he did, boy would he have a lot of work to do.  Which causes the game to lag hardcore for a few miliseconds, and then return to normal.

Can't have that, that's just bad practice.  If games like Borderlands can run at 60fps (or near to it) on my computer then there is absolutely no excuse for my 2D game to lag.

Aside from that, I've just done some work on the score system, creating examples for Brian and making sure that it's at least visualized partially for upcoming playtests.

W00t w00t.

-Kev.

Oh yeah, you came for pictures, didn't you?



Cousin Collaboration

Guaranteed to solve most problems.