Tuesday, October 11, 2011

The Job That Ate My Blog

Just a post here to say that I am working on games full-time for at least the next couple of weeks, and the time I have to develop my own game projects is basically zero, but I'm not complaining! So what can I talk about, publicly?

I have in fact learned enough in the last week, especially about Box2D (cheers to Mr. Catto), to where I'm realizing that many of the approaches I intuitively took to manipulating objects in my games were somewhat misguided and ham-handed. I owe more than a little thanks to the tutorials at iForce2D.net, and I still haven't exhausted the tutorials that site has on tap.

Basically, moving an object by directly setting its Linear or Angular velocity is for squares, for the birds, for rubes, it's bush league, it's a Gerry, it's beneath you. Move objects by applying forces to them over time, in the case of something you want to push up to its top speed, or by applying impulses, in the case of something you need to hit with the equivalent of a baseball bat.

Same thing with Angular Velocity; the cool kids use Torque. I'm just playing, there are of course many scenarios in which one might need to directly alter the velocity of body, but when you do so you have to be aware that you are in effect taking that body outside the physics simulation and treating it like some dag blasted UFO and in that case why bother with a physics system at all, Einstein?

In any case I hope to be back with more updates to Skeleton Wizard and Solar Trucker in the not-too-distant future.

Friday, September 9, 2011

I really should stop doing this

My usual slapdash method when I feel like I'm on to something is to write out roughly what I think the function probably should look like, and then pepper it with statements like
print("This function won't work, dummy") 
at the no result ends of what I think are correctly formed functions. Invariably every one of them goes off when I run the code.
The solution is to set aside some time and really learn to use things like assert and try/catch, lua supposedly has a nice system for this sort of thing that will give me a lot of detail on where I'm wrong and improve my efficiency pretty severely. Sooo maybe soon. Maybe real soon. I don't know if I wrote this before or if somebody else did, but I'm calling it a Law: "You will learn something when the pain of not knowing it becomes greater than your perception of the pain of sitting down and figuring it out." The perception part is important, whenever I envision a task with more than a few steps I'm prone to suddenly feel like some poor prehistoric chump pulling a block in Giza. The fantasy of how dull this complex task you have to do will be is often plenty of motivation to continue doing whichever unproductive but however-marginally pleasure generating activity you are currently engaged in. More than a small part of the overwhelming effort that seems necessary to log out of the website, put down the crack pipe, finish the novel, refactor the code, etc. is to overcome that initial fantasy about how much ball-bustingly hard work is going to be involved in reaching the result. It's true, but we are really not good about estimating the future, as human beings, we get emotional and we're naturally clumsy with time and we have great imaginations, and yes, often some of the small, short-term, easily accomplished sub-tasks that need to be completed at any and every phase of the plan are actually kind of unpleasant and tedious, sure, of course, but it's a mistake to imagine every second is going to be like that!

Right, well . . the point is, if you can recognize that initial wave of resistance is going to come at you every time you try to self-motivate, you can at least brace yourself for it or try to . . dive under it . . surfing metaphor yeah . .  the imaginator's best friend is his worst enemy . .      

Thursday, September 8, 2011

Some Crude Planets And Some Cruder Math

Well, these aren't going necessarily going to catapult me into a sweet Art Director position anywhere, but they're good enough for Solar Trucker, says I. That wraps up the art section of this sprint (heh) unless I lose all remaining common sense and decide to implement that animated dotted line thing I was thinking about last night while I was falling asleep. That would truly be foolhardy. I have found as a rule of thumb I tend to resist a problem when I realize I'll have to create a test bed for it. I even have templates, it's not a pain at all, but something about it is not as much fun as hacking away at the main game, however fruitlessly.

I decided early on to try and make the game conform at least in the loosest possible manner to the actual distances between planets, so that players could do things like weigh the differences between a milk run to Venus for peanuts and a long, asteroid-fraught haul to Jupiter with a big paycheck at the end. I'm now wondering how much I should fudge the numbers.

For instance, if I decide that my basic Earth - Mars run (48.6 million miles) will be the gold standard of the amount of distance the player should cover over a "standard" arcade game level, let's say about two to three minutes. That seems like about as long as anyone would want to plink at asteroids before seeing another screen. So let's say if there were no obstacles, you could point the ship at Mars and dock in exactly two minutes. Seems reasonable. That's a basic speed of 24.3 million miles an hour.

If we want to keep everything roughly in scale, we'll have to plot the other trips with that top speed in mind. See where I'm going with this? The Earth-Jupiter run at top speed would take just about sixteen minutes, which is a Long Time to spend plinking asteroids, even with salvage and aliens and whatever else.

So, make the meta-game less "accurate" or make the core game more interesting. Time, Distance and Speed . . .

Edit: bonus old school dev tools screenshot

Tuesday, September 6, 2011

Where There's A Map


Here's a quick pic of the second between-missions screen for Solar Trucker, the route map. It doesn't have much logic hooked up to it yet so I haven't uploaded a build with it in place. This is one of those little humps where the basic idea is simple, but in order to implement it I have to do a ton of grunt coding. That is, I'll need gameplay art for each planet, plus calculation of distances, variable asteroid dangers, and of course the police and salvage features I haven't even begun on yet . . but once the basics of this are in you'll be able to travel to a planet, pick another destination, travel to that one, and on and on, which is dangerously close to what a real game might look like.

Every day of progress is still kind of agonizing because I'm still floating around unemployed, entirely unsure of which of a dozen possible skills is going to put me over the top during my next good interview. For instance, if I was spending this time on Python or ActionScript instead, I might be looking at a slightly broader swath of opportunities, but things are so fast and unpredictable right now that this is just speculation. At least I'm free from wondering whether I should be building Unreal or Source maps: my laptop won't run that stuff and I'm in no position to go buy a new dev rig.

I just keep reminding myself that the most impressive thing I could possibly have to show is a finished product, regardless of the specifics of that project. This game surely isn't going to be all that, but it is going to be done at some point, and the next one is going to be better, and the one after that is going to be better still . . .

Monday, August 22, 2011

Misc: Why John Carpenter's The Thing (1982) is a perfect Call of Cthulhu scenario



YOUR GROUP
- Your group is physically isolated, possibly on a global scale.
- Your group's location is dangerous and/or inhospitable.
- Due to location, characters or circumstances, calling in the authorities and letting them deal with the situation is either impossible or a very difficult and/or unappealing option.
- Your group are academics or intellectuals, possibly with some blue collar muscle attached.
- Feats of academic skill are 60 - 70 % of defeating the enemy, the rest is brutal violence.
- Even the most practical skills have their limits ("Any way we can fix it?" "It's gone, McCready").
- Vital clues may lie beyond a language barrier, and for want of this nail everyone's lives may be lost.
- Your group may start to die, and once the dying starts it becomes less and less likely that the dying will stop.

THE PPB
- There was another group of people like you out here, but something terrible happened to them.
- Thankfully the Previous Poor Bastards (PPB) were copious, some might say obsessive note-takers, diarists and photographers, although some of their evidence may be for one reason or another outside your powers of interpretation.
- PPB research is always intriguing : "Seems like they were spending a lot of time at a little place northeast of their camp about five or six miles." If you ever hear anything like this, run.

YOUR ENEMY
- Your enemy, although possibly out of place, is vastly more intelligent than you.
- Your enemy leaves crime scenes and horror in its wake, narrative tableaux of desperate struggle followed by savage death.
- One of your early encounters with your enemy may be in the form of a corpse like no corpse you have ever seen before.
- The bodies and attitudes of discovered murder victims may be unintelligble at first, as though the crime were committed by a madman . . but this may not be the case.
- Your enemy can spread, like a virus, and corrupt even those closest to you.
- Your enemy, if somehow allowed access to and power over a sizeable human population, could spread quickly enought to engulf the Earth in short order.
- Compared to you, your enemy is very, very old.

THE GOOD NEWS
- Your enemy may be ultimately immune to physical harm, but in the cases of your enemy's incarnations and manifestations, things like fire and shotguns can be key to turning an unmanageable situation into a mangeable one.
- Fire is a language that everyone understands.
- When in doubt, burn the place to the ground.
- There can come a time when killing any (or every) other member of the party is the sensible, sane thing to do. ("What if we're wrong about him?" "Then we're wrong.")
- This is usually accompanied by the realization that one should probably kill oneself as well, followed by the brilliant realization that one actually needn't because "I know I'm not one of them!"
- Only knowledge of the odds allows for true heroism: "we're not getting out of here alive . . but neither is that thing."
- Dynamite is a language everyone understands.

REASONS AGAINST
It would be tough to keep any experienced players from wising up to the dog long before it got to spend time alone with anyone. That's the only thing that bugged me, even for 1982, wouldn't there have been enough general awareness, especially among scientists, of infectious diseases to where if you saw some Norwegians out on the ice frantically trying to shoot a dog with a sniper rifle, you might at least entertain the idea "escaped lab animal" before giving the dog the run of the place . . ultimately it doesn't matter, due to what happened in the kennel, if it couldn't have got to any humans quickly it would have gone for the other dogs, but that's assuming they captured the thing rather than going with the other option of considering the obvious frantic intentions of their fellow scientists who were burning helicopter fuel many miles from home in order to shoot the dog already.

Inspired by this video:
http://www.youtube.com/watch?v=SppG-I_Dhxw&feature=channel_video_title

Sunday, August 21, 2011

Test Driving The Rodent



I'm sitting here looking at this thing and wondering if I'm really going to take Solar Trucker apart and put it back together again using Chipmunk physics instead of Box2D. For some reason I was unable to get a proper handle on adding and removing objects to / from the screen in Box2D, I was constantly crashing the thing. I switched over to Chipmunk and hit upon a method that I think will give me all the behaviors I need, in a way that I find more intuitive. I recognize this might not be the best way to choose technologies, but look, one of the problems with using a very new SDK (MOAI in this case) is that while you may have documentation, you don't yet have this massive pool of amateur developers and their tales of workarounds, abandoned projects, successes, pet peeves, etc. that you would get by working in something like Flash or even Unity. Thus I end up spending way more time tinkering around in test beds like this one than I do actually working on the game, but supposedly this how you get good, so I don't really have a problem with it.

  So I'm 90% ready to make the jump, but switching physics engine midstream is kind of like trying to replace the transmission of a moving car. It makes a lot more sense to me to just rebuild the game around the Chipmunk implementation I have for this demo. At least I know it works, and how long could that possibly take, right?  


Right?

Monday, August 8, 2011

I Was Just Resting My Eyes


I should take a minute to post about what's been going on, as stuff is indeed going on. I was on my way to a family reunion a few weeks ago, killing time at the airport and started thinking about how I would use the MOAI system to create the classic player rotation movement of Asteroids. Well, one thing led to another and here we have a screen from Solar Trucker.  I'm getting fairly close to having the gameplay basics solid, but there are still some real problems with my rotation and "thrust" code.

For the thrust I am keeping the player at center screen and moving a starfield behind him, and that's the new second-iteration choice, I originally had the player floating off one end of the screen to appear at the other. I'm grappling with Box2D, which is one of a few physics systems MOAI implements natively. Moving objects with Box2D gives the movement a very smooth, kind of weighted quality that I like, but I haven't been able to get the amount of speed I want out of the code, regardless of how I tweak the mass of objects. It's a big library and I'm sure the solution is in there somewhere. I've been simultaneously messing around with moving things just by animating their "props" around with the native movement functions, and under that model it's easy to get that starfield flying by, but the handling is god-awful and really, why not use Box2D when it's right there at hand?
One of the most difficult parts is going to be knowing where to stop. Every day I think of another cool feature, but the most important thing right now is to get the very basics working and presentable. My homegrown rotation matrix works surprisingly well most of the time, but I just know I transposed a couple of digits somewhere, the player's bullets will occasionally float off sideways. 

Wednesday, June 29, 2011

How I Done It

I got the example code compiling properly and I can move on. In order to get here, I had to:

#1. Add the paths to DirectX's Include and Library directories to the solution's property sheet

#2. Change the name of the file "dxerr9.h" to "dxErr.h" because "dxerr9.h" has been deprecated since the time the book came out

#3. Change this:

for( DWORD i=0; i<m_dwNumBuffers; i++ )

to this:

DWORD i;
for( i=0; i<m_dwNumBuffers; i++ )

#4. Make a copy of "dxErr.h" in the same directory and rename the copy back to "dxerr9.h", because apparently it needs both versions? OK, sure.

This kind of mess is starting to not surprise me anymore, I wonder if that's a good or a bad thing. Also I shudder to imagine what this would have been like in the days before you could Google for any conceivable output error.

Tuesday, June 28, 2011

Dearest Microsoft . . .





. . . I've tried, really I have. Note: this post will not be full of triumphant useful goodness so feel free to skip.

I've recently had an opportunity to pick the brains of some folks making games with a lua-based framework, and it became quickly apparent that my innate lua skills ("It's like Python, right?") were just not going to cut it, so I started looking for some Dead Trees to inspire and educate me. Game Development With Lua (Paul Schuytema / Mark Manyen) looked like just the ticket, and I ordered it from Amazon with high hopes, ready to dive in.

Great book, none of my issues are the authors' fault, but . . I didn't realize that in order to follow along with the lua game-making tutorials, the reader should know his/her way around C++, as you need a C++ project to be the code base for implementing lua logic. *Gulp* but OK, not entirely unexpected, and thanks to XNA I can find my way around a Visual Studio project without being totally lost. Fine and good! Let's load up the source code from the handily-provided CD, build it, and start scripting!

VS needs to convert this 2005 code, again not much of a surprise, things move fast in .NET land. Let it do its thing.

Oh, it needs some DirectX SDK files, OK, we'll grab the installer for that.

Hm, when I build the book's projects, they aren't finding the DirectX files they need, even though I have the DirectX SDK installed . . looks like a job for the internet!

OK, cool, other people have had this problem. Looks like I just gotta add some paths here, change some settings there . . .

No, huh? More internet sleuthing . . .

Oh, searching on the error messages tells me some of the code from the book has been deprecated! Some helpful devs have offered workarounds and substitutions, which would be great if I was comfortable and fluent changing, updating and repairng C++ projects on the fly.

Oh yeah, if I was comfortable and fluent changing, updating and repairng C++ projects on the fly I would probably be employed as a programmer and wouldn't be doing any of this.

Look, I love to learn, but every time I get an error in a Microsoft product I have to descend into a thicket of internet rumor, conjecture, and neckbeard know-it-all-itis, and I did so for hours upon hours and still can't build the project that will allow me to practice my lua.

Here's the thing: as smug as the experts might be about this, its a problem. I feel like there is an attitude in the video games industry that says that anyone who could not solve this set of problems trivially has no place in a pro studio and should "go back to school and get a CS degree". I see this attitude all the time online, and my experience tells me it holds true in the Real World.

And yet at the same time, gamers gripe and complain (and rightly so) that characters are one-dimensional, plot twists lack credibility, dialogue is stilted and wooden, "story" is either unsatisfying or completely absent.

If the barrier to entry includes endless navigation of arcane, badly versioned, poorly documented development software like Visual Studio Point-Oh-It-Doesnt-Work-With-Last-Years-Code, then yes, the only people qualified to work in video games are going to be hard core coders with the skills to plow through this bullshit and find a working solution in this mess of broken crap.

Some would say that's a good thing, but I don't think so. The industry has suffered because writing and design is done by people who are hardcore coders, with no skills or experience in writing or design. Why? Because they are the ones allowed in the door. I'm motivated, I have a killer work ethic, I'm smart, and I'm fucking stuck because the example code in a five year old book doesn't work anymore. Thanks MS.

Monday, June 13, 2011

I'm an object factory (a lua poem)*

I'm an object factory ( parameters )
   
    I make a new Prop2D or whatever when the factory is called
        with ( parameters passed in )
    end construction
   
    I give each one of these created props some built-in abilities
       
        maybe it can modify its own appearance
        then delete itself
        and instructions about how it behaves in a thread (self:stop)
       
        maybe it can blink, or spawn other objects
        or who knows what
        and instructions about how it behaves in a thread (self:stop)
       
    end built-in abilities
   
    I'm the main function for any given instance of the prop built in this factory
        in certain circumstances, I may
            execute one of the built-in abilities described above
        or in other circumstances I might
            change some quality about myself, or create or delete a quality,
            or who knows what
        end circumstances

        when I'm done I'll pass control to another process until it's my turn again
        I could also return some information about my current state       
    end main function
   
    Here's the thread itself
    Please run this thread now
   
end factory


*have I finally gone off the deep end?

Monday, June 6, 2011

WHY U NO UPDATE BLOG?

I have put Skeleton Wizard aside for the moment! I know that's a bummer, I feel a dull ache myself every day I'm separated from the Purple Dude. As fate would have it though, my dev energies have been diverted down a different path, just for a short time I promise . . . if I'm able to get a handle on this new thing I may have to port my work so far.

I'm talking about a lua-based game development system called MOAI that I'm trying to learn by creating clones of some simple old games. More on MOAI later, but lua itself is kind of dumbfoundingly cool - while trying to pick up some basic concepts I resorted to just kind of typing in what I basically wanted the program to do, with some loose approximation of the syntax in some example code, and it just works, this is from somebody with less than a year's programming experience and I feel like I can talk to lua like it was my college roommate. Fundamental quality of the language, or just a sign that I'm getting slightly less dumb about code conventions? Little of both?

So I'll be modeling paddles and such for a bit. Been watching some youtubes about classic games from this guy Matt and I'm psyched to make something like the Atari Adventure, just so abstract as to be almost totally incomprehensible . . . I mean, how the hell did anyone ever figure out what was going on in that game?

Friday, May 27, 2011

I scroll, you scroll, we all scroll . . .


Making the tiles scroll was actually a bit easier than I thought it was going to be, and I feel like I leveled up a bit because this was the first Skeleton Wizard problem I tackled by just rolling up my sleeves and jumping in there, rather than comparing my code to another game that was already doing what I wanted.

I used to be terrified of the word algorithm. To me it evoked graduate-level math teachers scrawling impenetrable glyphs across lecture-hall sized chalkboards. After a few weeks of programming tutorials and books, I finally had a perceptual breakthrough: an algorithm  is simply your plan for solving a particular programming problem. When I thought I was just trudging angrily between my cubicle and the cafeteria, muttering to myself about why the damn tiles won't line up properly, and scaring small children . . what a was actually doing was developing algorithms!

So for the tile and background scrolling behaviors I devised a system that I figure is probably at least as old as Mario, and may not be optimal but it works: The player is always in one of three "zones", or vertical sections of the screen. If the player is in the center section, the wizard moves freely. When the player enters one of the left or right side sections, the wizard stops moving and the tiles move instead. Many tweaks were required to get the behaviors I wanted, but after another few days of lunch-break muttering I found the proper code to make the player interact with the environment in a way that feels pleasing.

If I didn't know any better I'd think this was starting to look like a game . . . is it time to add bad guys already?

Thursday, May 19, 2011

A Real Background and a Real Bug


Well, it's still dopey programmer art but at least I'm not looking at a flat grey-blue wash. I made this thing 4000 pixels long so once I have the scrolling code the art will be ready to go. Unfortunately, I ran into a kind of technical snag that I haven't encountered before: XNA is telling me that it's having assembly problems, and that some of my stuff was originally built with a different version of XNA than other stuff. It offers to fix it for me by altering an "app.config" file, but if I take it up on the offer the game throws an exception while loading the wizard's texture and won't start.

This is frankly the kind of baffling, scary, dot-net hokery pokery bullshit that I hoped to avoid. It really is true that if you are even dabbling in game development you'll eventually have to figure out just about everything related to your tools, but I dread trawling through msdn pages trying to parse out the nature of a Visual Studio compiler error. One minute you're sailing along making wizards jump over pine trees, and the next you're elbows deep in the dirt. So it goes.

I have been shuffling the build between work and home computers using ftp, could there be a difference between the two versions of Visual C# 2008 I have installed on each machine? If there was such a significant difference, why would it suddenly rear its head? I tried removing my most recent class, which controls the background, to no avail.

Here we have, for the first time, an entirely persuasive argument for version control, even at the toddler-dev level. Since I'm absolutely certain that this bug was not always there, when I get home tonight I can just step back through my version tree until I find a build that doesn't have the bug, then look at the changelog and I should have my answer. Easy, right? Like so many other things, before I try it, it couldn't look easier. . .

 EDIT: I had a bit more downtime this afternoon and did some search engine sleuthing . . . I still don't know exactly what the hell happened here, but it turns out if I go to Project > Upgrade it rebuilds the solution and the error goes away. Best guess: When I was creating the background class, I fat-fingered it and created an XNA 3.0 class instead of a 3.1, because 3.0 is still an option in the menu and it's conceivable I could have done that. Why just deleting that class didn't fix the problem I don't know, it must have done something to the compiler that could only be resolved with an "upgrade". Windows! Yeah!

Monday, May 16, 2011

I have levels!


The tile engine infrastructure is starting to pay off. After working out the animation bug (I was totally right about it), I whipped up some programmer art and implemented the idea of Collidability - different kinds of tiles will react differently to player collisions. You can hop directly up through a bridge and then land on it, but a block will stop you.

Things I'm looking forward to (the bullets are back baby):
  • Bullets (not the list kind, the shooty kind)
  • Enemies
  • A background
  • Scrolling - I want each level to be the same height as the screen but much longer.
  • More Hud stuff, level indicator, points
  • Some stuff to collect for points
  • A GUI level editor (no clue where to even start with that)

Sunday, May 15, 2011

A Disturbing Development


Here I was all proud of myself for doing a thing or two . . and I'm going to try to get through this update without a bulleted list, so here are the things I did: 'shopped up a doors.png with some doors and got the game to display them, created a placeholder title screen and at least the concept of a game over screen - it's currently blank but it happens in the right place! Still having a problem where SW will lose two lives at a time, haven't bothered to go looking for it yet but boy the kids would riot over a bug like that in my day, all those quarters lost . . gotta solve that one quickly.

SW also has a new jump animation, which is just two frames dependent on facing, and a four-frame falling animation that I actually feel kind of cool about. I set the animation to start when the player's falling speed was over a certain limit, and clamped the animation into two sets of two frames that the game flips between dependent on player facing. So in most cases when the player is falling he shows just a single posture, arms straight out, but if he falls far enough to where his speed breaks that limit, the animation kicks in and he starts waving his arms in panic. In the future I want to dial in the values around this to where you only start waving your arms around the fall height where you're starting to get injured . . . maybe. . . still not entirely sure I want to implement fall injury, but if I do I certainly want to use animations in this way to telegraph potentially bad falls to the player with a margin of error wide enough where the player can adjust, maybe be able to take a single bad fall so the controls aren't unforgiving . .

That's all great, but why does the Skulled One  have octopus arms? I'm not 100% sure, and it's late enough to where I'm in no shape to deal with the problem tonight, so I'm just going to be Armchair Developer and spin some theories here with my pipe and slippers, which is of course way more fun that actually getting in there with a mental machete and hacking your way through the code.

The Load Content function grabs a bunch of textures of the player, which get turned into animated sprites, and then in the Player.Draw function I go through a bunch of ifs and elses to figure out which way the player is facing, if the player is jumping or falling, etc, and then based on that the game grabs whichever animated sprite corresponds to that behavior and throws it on the screen.

My water cooler quarterback guess is that I put two if statements in a row when I should have put an if and an else statement. So the game says "Oh, you're facing right? here, have this sprite. Oh, you're jumping? Here, have this sprite too." I haven't properly separated these questions to produce the correct results.

I hope to the Gods of Programming it's something that easy.

Wednesday, May 11, 2011

That Grim Specter


Skeleton Wizard can never really die of course, but since this is a classic platformer, I have given our hero a number of lives, which can be taken away if he does something foolish like falling off the bottom of the map. At present nothing happens when you hit zero, so I'll need to do a state / screen framework to allow for a "GAME OVER" situation, which means I need a title screen, plus I'm getting tired of looking at that blue background, and the Wiz could use some jumping and falling animations . . . sounds like an art push lies in my near future.  

Monday, May 9, 2011

It was a TYPO


I had a modulo sign where I should have had a division sign, but it's an instructive moment for two reasons (I enjoy bulleted lists, does that make me evil?):
  • The reason I allowed such an elementary typo was that since I'm uncomfortable around unfamiliar or poorly-understood math (like our friend the modulus operator), my eyes will kind of glaze over and I'll just type in the code without paying too much attention. By contrast I never would have made that kind of mistake when, say, addressing a function with a bunch of parameters, I'd be on my toes syntax-wise. It's just another delightful little example of my math-related neuroses. 
  • The only way I found the end of this tangle of Xmas lights was by applying the same logic I used on the collision problem: I need information about the source rectangle for the block on screen, and I need to be able to change that information. Since I can see several different blocks onscreen, it's unavoidable to realize I must already have the information I'm looking for, since I'm clearly using it to draw blocks. The bug hunt then becomes a relatively simple matter of finding the variable holding your info (in this case it belonged to a method within an instance of a burly Dictionary data structure, which I still don't quite get).

Fun With Tiles and Blocks


Well it didn't take too long to get utterly lost again.  Rather than follow the plan and do some game state stuff, I decided block prettification was suddenly priority one. Since my blocks (arranged in a 5x5 square on my .png) all looked the same, I made the happy assumption that my game was just doing what I expected it to be doing behind the scenes, presenting a nicely random array of blocks that all just happened to be identical in appearance. Once I started adding some details, it became apparent that the game was only ever painting a small subset of the available tiles to the screen. With some detective work, I determined that I was getting five tiles in a diagonal row from the top left of the image to the bottom right. Here's an image of the .png, with a number layer overlaying it. The yellow circles indicate which of the tiles are actually being drawn to the screen:


Now if you look closely at the top screenshot, you can see I'm outputting an additional small number at the upper left of each block. This number represents the "tile sheet index", it is randomly bouncing around between one and twenty-five, just like it's supposed to. That's the number that I thought was telling the game which tile to draw, but obviously I was wrong about that.

This is the kind of fiendish mathematical bullshit that serves as a small barrier to entry for the novice game programmer. If you're just grabbing code you don't understand and plugging it in, when it stops working how can you fix it? You don't know how it's doing what it's doing. I really do want to get this fixed but I may have to shelve it in favor of some problems I know I can actually solve quickly.  

Sunday, May 8, 2011

YEAH BABY



My hour of darkness and tribulation came to an end this morning, as I finally got all my tiles detecting the player. I started from the premise that since I was already drawing individual tiles to the screen, somewhere in my game I was already detecting and making use of information about the size and position of each tile. Since my Intersects() function takes two Rectangle objects, I knew I needed to get a rectangle for each tile with this info in it. I added a blank Rectangle object called "boundbox" to the definiton of the Tile constructor, so now every time a tile was brought into being it was given a blank rectangle. Then I went into the loop where it loops through every potential tile placement on the screen and determines whether there is a visible tile there, according to the Dictionary object that reads that info from the level.txt file. In that little chunk of code inside the loop where, for each individual tile, the game assigns it a position and a texture, I just added an instruction for the game to fill up that particular tile's  "boundbox" with the relevant information before moving on to the next tile. Pass each tile's rectangle and the player's rectangle into the Intersects method every time we cal Update, and pow, suddenly we're in business.

Even in this trivial piece of code(against which I banged my head for the better part of two weeks) there are already things I see as being wrong that will have to be fixed. Let's make a bullet list:
  • The first obvious blunder I found testing it is that my method for extricating the player from a block he has sunk into is not very elegant. Basically if he's coming from underneath (player.IsJumping) I increase his Y value until he's out of it, and if he's approaching from the top (player.IsFalling), I drop his Y value until he's standing on the block. Looks great in most cases, but if you time your jump right and hit a mid-air block from the side, you get a popping effect as the player is suddenly repositioned above or below the block. The refactor is to do it the way it's done in the XNA example platformer, which I still haven't wrapped my head around, it somehow gives you the depth and direction of a collision between rectangles, so you can just push the player back in whichever direction he entered, however far you need.
  • There are a lot of places where, inside a loop, I'm calling some property of the Tile class or doing some fugly piece of math, many many times a second. Instead I should give the method some member variables that create all the necessary values before running the loop, and then just plug those unchanged values in rather than flipping them around at high speed. This is the kind of thing the Big Orange Book is teaching me about performance!
OK maybe two bullets is enough there, I could go a while listing the problems with what we already have, including the jump itself, which has no power curve and isn't timed in the way the walk is, which will probably cost me down the line. But today is not a day for worry and pessimism! Today I have swung the silver sword of the game programmer, and lopped off one of the hydra's heads. Surely this hydra isn't going to grow a bunch more heads overnight, right?

Next steps: Doors and Death
 

Saturday, May 7, 2011

Yea as I walk through the valley of the shadow of derp . . .

The internet is littered with dead blogs. I myself have made a few, perhaps you have too. When you start learning a new subject, your enthusiasm lights you on fire, and you feel the need to share your progress with the world, to share your joy at grasping new concepts, finding new paths, inspiring yourself!


And well you should. However, I think it's also important to document your down days and moments of despair, because everyone who works creatively has them. After all, what is the value of the creative artist if he/she is not a person who can walk up to an unfamiliar problem and immediately start coming up with, if not solutions, then at least ways to approach the problem that transform it from a mysterious bogeyman into a an abstract problem that can be approached, reasoned with, maybe bargained with . . .


You may have gathered from this, or from the lack of screenshot this week, that my "Skeleton Wizard" platformer has run into difficulties. Well, it's true, and if this blog is good for anything it should be good for exposing the weaknesses that cause bright-eyed indie game devs to plow straight into the earth at hundreds of miles per hour.


Now, this problem is probably trivial to most anyone who would be going through the back issues of some self-taught nerd's gamedev blog, but try to imagine instead that you are facing a problem that would stump you. And if there is no such problem, please close the tab and go f . . . ind something else to do.


Wizard walks and jumps on blocks. Kindergarten shit.


First time out, I got a class Block, which when called into being as a live instance is going to have some set attributes regarding its size and texture/appearance. Note that calling Block does not give the block a position, it just means that the game, at runtime, is going to create and gather a bunch of these objects that are examples of the for "Block" which is going to have some characteristics common to the Block class. My Game1 class has an array of these guys called blocks[], with its array length set to a static variable called iMaxBlocks, which is set to, whatever, 10 in this example. iMaxBlocks being what we'd call a "static member" of the class Block, a variable attached to that class that won't change and that will be the same for any instance of that class we decide to conjure up.


I apologize if this is so basic as to be worthless; there are probably lots of blogs by real, competent programmers that you could read. This blog is by a dude who had to re-take high school geometry, and the hope is that my hapless machete swipes through the field of game development may point the way for interactive media professionals even stupider than myself.


But I digress . . . The problem with blocks[x] is that I haven't given my Block class the same kind of drawing and placement "infrastructure" that Tile has . . Tile being based on a tutorial for tile maps allowing the designer to create levels using a text file with comma delineated lines keyed to cell contents, like a line with a small platform might read


'.''.''.''.''P''P''P''.''.''.'


or the like, which is basically a crude level design tool, and thus immediately attractive, but I am quickly faced by what must be a fundamental problem: how do I integrate the data structures I am using to draw these maps with the data structures I am using to check player collision with blocks - they are different and something has to give.


More on  this when I figure it out . . but if this post has a point, it's this: the "hardness" of "unsolvability" or "fuckthisishardness" of a given problem is not an inherent function of the problem. To a chicken, starting an automobile is an "unsolvable" level problem, while for a human it is trivial. If, when facing a problem that does not have an obvious point of entry, you cast yourself as the chicken in the chicken vs. car keys scenario, then of course you will not succeed. Find a framework, or a window, or a perspective, or a viewpoint on the problem that casts it into a place where you can work with it, like you would cast a (float) into an (int) if you had to.


OK maybe I've made my point.

Monday, May 2, 2011

Version Control


When I started my game programmer journey, I was aware of version control as one of many, many subjects I was going to need to devote a lot of study and practice time to. Within a week or two version control had elbowed its way to the front of my "to learn" queue, saying "uh, you want to just play around in your codebase and try random things? Without ME? Have fun reconstructing your project from scratch every time you make a horrible mistake . . that is, every time you fire up your IDE, haw haw"
To my credit I was not ignorant of version control systems. I had used Perforce in a few different studio situations, and felt pretty comfortable pulling files, making branches and then re-integrating them, keeping various versions with different purposes up to date with one another, I felt pretty good about my version control cred.

All that #swag crashed and burned the day I tried git. 
Undaunted, I grabbed svn and TortoiseSVN

OK, I'm still apparently dumb as hell. 

Thankfully, there's Bazaar, which I was able to download and configure. Maybe once I've had a few weeks with it I can upgrade to one of the more powerful version control apps . . . 

So I'm an idiot, so what, Bazaar is awesome, haters gon' hate.

Sunday, May 1, 2011

One Step Forward . . .


My second screenshot looks even uglier than my first, but it's actually a  leap beyond! That gold blob is the player, who can be controlled with the arrow keys and can jump with the spacebar. The player can interact with each of the tiles, and I can change the outline of the level by editing a text file. The jumping and collision are still a little rough, but I think this is a much better development "platform" than my previous version. Still don't know exactly how it's doing some of this stuff, but I imagine I'll find out in the process of fixing the basic movement mechanics.
 

Dead Tree Addict






The laundromat I go to most Sundays is a few blocks from a huge secondhand bookstore with an exhaustive tech section, and I have a weakness for acquiring these things . . why not? At $10 - $15 a pop used they are a great value, and to me there's nothing more inspiring than a heavy Tome of Knowledge that offers the promise of answers to any question you have . . . once you know enough to learn what questions to ask!

A big secondary project to the platformer I'm tooling around with is to forge through all the example code in the XNA book, entering it myself by hand. I've already managed to get a triangle onscreen which the book assures me is in 3D, although at this point I'll have to take its word for it. This book jumps into the deep end fast, and if I hadn't started with a bunch of the more hand-holding internet tutorials I would probably be lost already, or at least more lost.

The C# book is interesting, it starts out with a broad overview of game programming concepts, then gets really crunchy into using DirectX for graphics. The book pre-dates XNA and covers a lot of stuff that it looks like you don't really have to do anymore, but I think it will be a good resource for looking "under the hood" at how XNA is handling graphics.

The third book is sky-high abstraction, covering even subjects like how to decide who to hire for your game development team, how to run postmortems, all kinds of good stuff. This one I'll probably read straight through kind of slowly over the course of several weeks.

 

 

First Screenshot


This is my last working build of Skeleton Wizard, a platformer with a vague "Black Sabbath meets Mario" design philosophy. As you can see I wrote a bunch of variable values to the screen with a spritefont in a "Debugger" class . . probably a dumb way to do it but it allowed me to look at some info fast . . .

I say last working build because I'm currently going back over it and building the display and collision code from scratch. The pictured version treats blocks as objects in an array, and I just draw them and do collision on them using a for loop. This works fine for a line of ten or twelve blocks, but gets unwieldy when trying to do whole levels. I dug into the issue and found a bunch of  "tile engine" type tutorials, some of which I'm still investigating.

There's a row of about ten tiles the player is standing on, those are created with my old 1D array method and they have collision. There's even a nice little thing where if you approach jumping from underneath, your eventual position is determined partly by your jump speed . . one of those things where I was like "OK I don't quite understand why this works but it seems to make a difference". . . All the other tiles visible onscreen were generated by the method found in the tutorials and examples, where you have an external text file containing the level "map" that gets read in, etc. These tiles do not currently have collision, which is why I am starting over! Should have done it the right way the first time. . . 

Saturday, April 30, 2011

Dev Diary

So . . this blog is a chronicle of my attempt to teach myself to make some video games using C# and XNA Game Studio. My background is around five years as a video game QA guy, assistant producer, content designer / scripter, general all-around gofer, etc. I'm familiar enough with the process of making games to give it a go, but I have no formal programming education.

My goal with this project is to create enough cool demos to populate an online game design portfolio. Right now I'm focusing on just basic game mechanics, building a platformer from some tutorial examples I found on the web. I'm already fairly comfortable painting images to the screen, taking some keyboard input, doing some simple animations . . OK the animation code is still a bit beyond me but I've made it work.

I did a Pong clone from a tutorial a couple of weeks ago, and now I'm ready to do a Mario-style platformer, which I'll hopefully be able to customize and tweak more than Pong, and maybe get a handle on how some if this code actually works . . .

I'll try to post screenshots here as I make progress.