Friday, November 30, 2012
Monday, November 26, 2012
After much tedious pixel painting of blocky arms and hands over guitars, I now have characters who can walk, run, jump and idle while holding their instruments.
Some problems I dealt with during this "minor" task:
- Forgetting how I set up the run animation. This was an embarrassingly big one, I had the guitar sprite animating properly during the walk cycle, but when the player started to run it got all funky and out of sync. I was in the dumps over this for hours; was there a timing problem when using multiple anims with RagePixel? Was I calling the run anim in a different way than the walk? Was there some holdup causing my Update function to skip a tick when accessing certain other functions? I came to believe I might have finally hit a wall, and was contemplating the ugly option of starting all my drawings over, making the character sprite big enough to hold a weapon, and just adding "with weapon" versions of all current anims to my original sprite sheet.
Thankfully, my memory came to my rescue: last week, when I was setting up the player run animations, I decided to change the framerate for run to be slightly faster than walk so it would look more natural, because the sprite was moving faster. I then promptly forgot I had done so. Once I remembered this I was able to simply adjust the framerate of the weapon animation and everything locked into place. This is the best argument I could muster for working in a team of at least two: you never know when you're going to have a show-stopping "senior moment" that can cost you a day, but that would be solvable by anyone else who knows your code base and isn't wearing tunnel vision goggles.
- Calling on types instead of instances. In Unity C#, when you want to get reference to a script that lives on a GameObject, you declare it with the name of the script file as the type, which is something you created yourself, so in my case, rather than something like
public MonoBehavior playerControlScript;
where MonoBehavior is the generic type for all scripts and playerControlScript is my script name, you instead have to use
public playerControlScript playerScript;
or some such, where the "type" is the name you made up previously for the script, and the variable name is a new made up name for the container that holds a reference to that script, within the current script that you're writing. Easy enough to work out, but if you're new to it it can get really confusing because my default assumption is that anything where I made up the name is a thing I can use for reference rather than an immutable static type. Therefore I would write something like this:
and then freak out when Unity told me "An object reference is required to access non-static member", and run around with my head on fire for far too long until realizing the simple solution is instead to write:
because I was trying to use a type instead of an instance without realizing it. Hopefully I'm over that one now.
- Realizing way too late that for more realism I should have placed the instruments behind the player's entire body when they are facing the other direction, this way it appears that the players flip their instruments from shoulder to shoulder as they turn. This is actually less of an "oops" and more of a "well, if I were willing to double the number of animation frames and completely change the way I do directional facing, yeah that would be pretty rad". This is one of those moments when you realize you have to put a lid on a feature somewhere, or else you will continue to refine and improve it forever at the expense of the rest of the game. Something tells me there will be a lot of those moments coming up.
Friday, November 23, 2012
The problem with user-created editor extensions is that they are not meant to be universal or universally supported, the tools dev has done this out of the kindness of their heart, and if it's not working how you expected, well, your options are to either hack in your desired functionality, find a way around it, or become one of those people who haunts the extension's github page petitioning your grievances.
Since there's a decent chance that my headaches are simply a result of not knowing enough about the tools, I'm loathe to waste other peoples' time and most likely will attempt the middle option, using the aspects of the tool that work for me and otherwise freeballing it. An example: this game features a pretty standard thing where the player character will pick up a "weapon", which will then stick to him while he moves around. Rather than create alternate weapon-holding verisons of the sprite (which would be problematic because the size and shape are different), I decided to spawn a new sprite, parented to a "socket" attached to the player. Pretty basic, and RagePixel has a nice concept of numbered layers, where you can force sprites to render in the order you want without mucking around in the z-axis. It worked great when just dragging the new sprite into scene view, but what was required was to create the "weapon" during runtime, when it gets picked up, which meant instantiating it from a prefab. Here's where things got weird.
When instantiating a RagePixel sprite in the same area as a pre-existing sprite, the engine stubbornly refused to accept RagePixel's layering functionality, placing the new object visually behind the one onscreen, regardless of my settings. It was hacking time and I had a few options:
- Dig into the RagePixel core scripts and locate the layering code, then play around with it until it starts working. I admit with some shame that I did not seriously consider this option for very long. I mean, I'm sure it would be an educational experience, but no thanks.
- Work some magic with Unity's own tags / layers system. This would involve assigning objects to layers, then using multiple cameras and culling masks so that each camera would show only a certain layer (scenery, characters, props), in whatever order required. I get a sense that I'll need to do something like this eventually, and I wandered gamely down this path for about half an hour before finding myself even more confused, at which point I had a slightly better idea:
- Bump the "socket" where the object gets instantiated out a few pixels on the z-axis, so it's effectively hovering in front of the player.
That did it, giving me the visual on the right side of the picture above. I'm somewhat concerned to have broken out of the 2D world and into the z-axis when maybe I didn't strictly need to, I hope that doesn't result in complications down the line, but at this point it gets me past that hump and allows me to move on to other stuff. For this feature, the next step is drawing item animations to match each of the player's movement animations, so as the player walks I can paint their hands etc in place on top of the weapon without having a third layer of sprites. I sincerely hope this is a good way to go, as my number one bottleneck right now is hand-drawing frame after frame of animated mediocre pixel art ... but no one can say this was not a bed I chose to make. Next game is going to be constructed entirely of royalty-free stock photographs.
The only other really scary thing here is that little voice in the back of my head that keeps whispering "overdraw ... overdraw" ... i.e. I'm drawing multiple layers of pixels to the screen on top of one another, which will eventually result in a performance hit, most likely when and where I can least afford it. There's a good chance that the simplicity of the project, combined with the environment I'm aiming it at (average computers using their web browsers) means that this will never really matter, but then again it might.
I've been told to "beware of premature optimization", so that's the story I'm sticking to. I also noted that Unity apparently has an overdraw visualization mode, so hopefully when the time comes I can once again stand of the shoulders of really tall people when approaching the problem.
Tuesday, November 20, 2012
I'm using Unity for my current solo project. Here's why:
Price: The amateur version is free, which works for me since I'm using it to build a portfolio, if I decide to make the leap to commercial development it's only a few hundred bucks for the various mobile kits.
Portfolio Integration: I can build a game using the "webplayer" option, which spits out a folder, which I can then upload to my server, and then anyone with a browser who is willing to download the Unity plugin can play the game. Only Flash offers out of the box visibility with that much ease.
Scales to 3D: and here's where Flash falls down. If I move from 2D to 3D in six months or nine months, I don't want to have to learn an entirely new environment.
IDE for fools like me: The other day I was importing some bricks (the artistic masterpieces shown above) and they were showing up all blurry in game. I figured something was up in the texture pipeline, and started fooling around with checkboxes and drop-down menus. Within minutes, I had switched from bilinear to point filtering and the problem went away. I'm not even totally sure what those words mean, but I know that if my game consisted of a series of text files in Visual Studio I would probably still be working on this problem. There's no substitute for a savvy engine programmer on your team, but if you're a tyro working alone, a full-featured IDE that does some of the heavy lifting can be a lifesaver.
Extensions and Plug-ins: My current project uses RagePixel, a plugin that allows the user to draw and animate pixel art right there in the game engine editor. Unity is rife with various user-created tools like this, mostly free. The less time I have to spend re-inventing the wheel, the more time I can spend on gameplay.
Tribal Know-how and Tutorial Heaven: If you can think of something to do in Unity, chances are not only has someone else done it and left their code lying around online, it's likely enough that someone has created detailed step-by-step instructions on how they did it. I've seen tutorials on everything from vehicle physics to using normal maps to acheive 3D lighting effects on 2D pixels. The game I'm working on is ever so loosely based on a series of tutorials for a Mario clone provided gratis by the Walker Boys. After this project, I have my eye on some 3D RPG stuff over at Cooking With Unity. Top shelf virtual mentors are only a click away!
Resume: I keep a close watch on what companies are looking for in their game designers. Using a modern 3D IDE and scripting with C# are both employable skills, whereas Cocos2D stuff, for example, is a bit thin on the ground.
There is of course the danger of becoming the guy who pounces on every bright shiny new thing, abandoning projects on a whim or worse, rebuilding the same unfinished game in engine after engine, and I am wary of that trap, but at the same tiem I'm pretty confident I'm on the right track for now. Even if I have to turn everything upside down next year, I know that as long as I'm learning, no time is lost and no effort is wasted.
Sunday, November 18, 2012
So ... A lot has happened.
I spent 2011 and most of 2012 as the lead game and level designer at a small studio. I shipped two titles for iOS and Android, both of which garnered downloads in the five figures internationally, and brought in non-trivial in-app purchase revenue. The team was me, two or three game programmers, three or four graphic artists, a couple of producers, and a handful of management, web techs, core programmers, marketing and HR staff, pretty much the bare bones of a game studio. It was a heady atmosphere, relentlessly creative and detrmined, and I had a fantastic time.
All good things must come to an end, and this one's end was abrupt, as the company simply no longer had the funds to operate at the capacity they had previously. Many jobs were eliminated, and the company refocused on support and maintenance for titles already in the marketplace. The remaining staff soldiers on, and they have my good hopes that their fortunes will improve and the company will start to grow again.
In a sense, it could be argued that my inexperience as a game designer cost me my job. If I had been able to develop a hit game idea, champion it to the rest of the company, and guide its implementation, we would have become successful and there would have been no need to downsize. At the same time, I recognize that this kind of guilty equation is monstrously unfair; consider the devs at Rovio who cranked out dozens of also-ran titles before stumbling across Angry Birds. Sometimes you get lucky right away, but even the well-known stories of "first-time" success like Braid or Super Meat Boy gloss over the fact that these were most certainly not the first games those folks made, they were just the first to attract enough attention to be viable in the market at large. I can't beat myself up about not single-handedly lifting my former employers to the top of a devilishly competitive marketplace.
Since then, things have ... not been great. A blizzard of applications constantly flies from me, recruiters clog my phone line, occasionally I get to go talk to someone in their office ... the last go-round was a full on Interview Loop at a Major Studio, which consumed my life for weeks, and ended in nothing. For all the painful second-guessing, the only knowable truth is that I was not a strong enough candidate.
Which brings us back here. A college dropout, with games industry resume that contains some good stuff but appears to have been written with a shotgun, about a decade older than your industry standard caffeine crunch monkey, adrift in a recessed job market awash with CS grads who probably coded something akin to my current solo project when they were about 10. It's a pretty grim looking situation.
When I was younger I wanted to be a professional musician. Strike that, I still do want to be a professional musician, but I no longer really believe that I will be. I learned that as hard as I try, ultimately I will only be as successful as the audience decides, and if not enough people like the music, well, I'll have to figure out some other way to live. Many years ago I took an entry level job in the video games industry and had a series of mild epiphanies, in which I discovered that a day job could be fun and interesting sometimes, that spending your day with a group of passionate, like-minded people making cool things wasn't always "work", that delivering cool ideas and experiences to people in the form of games can scratch some of that same itch that delivering music can scratch, that there might be a place for me in this world, that games are fascinating on every level, that games might, in some small way, be able to change the world.
Now here I am years on confronting those same thoughts and feelings that have plagued me about music for years, things I thought I had put to rest, like a conviction that I'm not good enough, not talented enough, a fraud and a charlatan. I guess we all have those feelings from time to time. It just feels too familiar, turning my back on a music career in the name of sanity and reasonableness, embracing my second choice career as a lifeline that allows me to funnel time and money into the music that sustains me, while giving me challenges and triumphs every day, creating cutting edge awesomeness with the smartest people I've ever known. It was great. Now it feels like my second choice career is pushing me away too. A little voice in the back of my head says "if you take a job doing some dumb thing like commercial database zombie or internal sales guy, then you can play your little songs and make your little video games on the weekend..."
Well, fuck that. If there's a point to all this ranting, it's here: at some point you have to look at your life and say "this is exactly how many compromises I intend to make in the name of getting along in society, and I'm not making any more." At some point you decide that you've bent far enough, that you've reached far enough across the aisle, you've been prudent and sensible and realistic enough. At some point life tells you to lower your expectations just one more notch and you say "You know what? No." At some point you fight.
OK, that's more that a little overdramatic, but the point is I believe in myself. I don't have to take a job at a call center or some other hellhole because I refuse to wash out of my career. I have a lot of great experience, I provide a lot of value to employers, and I'm going to get back on track to my dream gig - senior content designer / creative director at a significant studio by age 50.
So, between here and there is the undeniable fact that my code stinks to high heaven. That, at least, is something I can do something about.
I'm working on a solo game project that coincidentally involves my band. More about that soon, when this blog steps down from this heavy stuff and returns to its original purpose: chronicling the technical hurdles and solutions that stand between me and a finished game.