locked doors and broken dishes

The locked door problem is driving me crazy.

It’s been said specifically about Half-Life, but applies to many other games, that a player winds up having to travel through miles of monster-infested corridors just to get to the other side of a locked door. Concerned made good use of this trope: you’ve got a crowbar, a pistol, a machine gun, a rocket launcher, and you can’t get through a locked door? Hell, you’ve got a foot. Door frames aren’t made from adamantium.

Of course, the door can’t be blasted into bits because going down the monster-infested corridors is the point of the game. The locked door enforces the narrative flow.

Another way of enforcing the narrative is to let the player go anywhere they want, but lock them into a sequence of interactions. Bob won’t talk to you until you’ve talked to Amy, and Amy won’t talk to you until you’ve found the broken dish, and the broken dish isn’t even visible until you’ve talked to Steve. Seriously. Like talking to Steve made it just magically appear. Steve is not a fucking wizard, okay? And what’s Amy’s deal, anyway? Why’s she acting like a stuck-up dork? I didn’t break the goddamn dish.

Same problem as the locked door, but in some ways, more frustrating. In the real world, people won’t refuse to talk to you just because you’re missing an item of crockery, and things certainly don’t just appear out of thin air because it’s the “right time”.

There is a third option: the out-of-order narrative. Let the player go anywhere and do anything, and let a narrative assemble itself from these interactions. No plan, no flow. It’s the mode of play that most resembles real life, but oddly enough, it’s used the least. Wander around a city sometime looking at random things, and talking to random people, and see how much of a story you can put together. Human beings don’t find this sort of thing very satisfying. We need to see the arrows: this happened because of that.

The reason I’m obsessing about this right now? I’m writing the narrative for a new game, with as much detail and thoroughness as possible up front, and I’m getting angry over how much work I’m going to have to do to keep the bits of narrative from bumping into each other. Like, okay, there’s a corridor over here that holds plot point 1A, and the room over here holds plot point 1B. There is no earthly reason why you can’t go to 1B if you haven’t gone to 1A yet. And yet, to maintain a linear narrative, I have to put a locked door in front of 1B (that magically unlocks once you’ve dealt with 1A) or take 1B right out of the game (and have it appear, mirable dictu, just when you need it).

Or I let players visit 1B before 1A, and the game makes no sense half the time.

Most successful game designers just pick one and get on with it. I’m not there yet so I have to rant a bit. It strikes me that the problem arises from wanting a game to work like a story and like real life. This is something that writers deal with all the time. You can make a story realistic or you can make it interesting. Even gritty cop shows have to use dramatic conventions to keep viewers from tuning out. Every reality show involves some degree of editing to cut out the dull bits, or even to synthesize conflict out of random bits of tape.

I haven’t found the right compromise. Still looking.

Also: Darien Acosta of webgl.com has written some very kind things about Gas Food Lodging. Bookmark that site.

a little post mortem

After the last project, I said that I’d be trying to write the game script sooner in the process. I was half-right, though I’m not sure which half.

I started by writing down the basic idea of the game—you were a young alien chef in training, trying to make a name for yourself by coming up with the greatest dish ever. I figured you could travel around looking for ingredients and advice, cooking for people to get a sense of what they liked, and sooner or later someone would let slip some bit of information about one might go about creating the greatest dish known to, er, alienkind.

I had the basics. I went to work coding the environment and the NPC models.

Once I had those, I started working on the script, and discovered I hated the idea that I’d just spent the time laying the groundwork for. It was stupid. I wanted something—well, something else. Meaty. Grim. Dead Space-level grim, not primary colors in a sunny sky. Wandering through a dark clutch of scary weeds, bumping into the bodies of people you knew. Sweeeeeet.

After toying with this idea for far too long, I told myself to lighten the fuck up and have some fun. This is always good advice. I’d still lost the time, though, and I still didn’t want to make a game where you went around cooking for people without risk, without a motivation other than ambition. (Ambition is a fine motivation in life, but in stories I find it uninteresting unless it leads characters down darker paths.)

I briefly considered combining the two, and creating a game where you had to go around a dark, scary clutch of weeds and cook for people to stop them from killing you. I still think the sheer stupidity of it would have worked, and I may go back to it someday.

In the meantime, I was tinkering with the code. This isn’t usually a bad thing. It’s a useful process, on occasion—test this, try this out, find alternative methods. However, it’s got to be part of a plan, or the tinkering takes over, and turns into bike-shedding. I lost a significant portion of those three months arguing with myself over what color to paint the weeds (so to speak).

Eventually, I came up with the idea of writing a short farce. (Can’t imagine how.) It still took a couple of rewrites to come up with the idea of a reusable minigame. That one got a big cheer.

In all, I suspect I spent half the time thinking how much I disliked my ideas, then desperately trying to come up with new ideas to dislike. This isn’t going to cut it in future.

For the new project, I’m going to try writing a good bit of the script up front before I start coding. I’ve resisted this because writing doesn’t feel like work—at least, not in the way that coding does. But if it saves me time and tedium, then it’s well worth it.

gas food lodging

Hey, gamers! Tired of playing the Chosen One, the hero that saves the world? Haven’t you always wanted to play a fussy hotel manager with a handful of difficult guests? Of course you haven’t! My God, I’ve just wasted the last three months of my life in a pointless exercise!

But what if I told you that the hotel manager is a flying alien from a gas giant planet? And the hotel is a cluster of weeds? And this bucket of dead fish is really my collection of gold coins? I’m rich, I tell you!

Welcome to the world of Gas Food Lodging.

Let’s bring our cast out for a big hand.

Our aliens are called paddlers. They’re asexual bags of gas (insert joke here) living it up in the atmosphere, high above the thick impenetrable undercloud. Paddlers eat, talk, dance, play sports, and stay in hotels. (That’s probably not all you need for a viable civilization, but I had a strict remit.)

You’re Hische, the hotel manager. It’s your responsibility to make the guests feel at home, and it’s their pleasure to call for you at every waking moment. Cross the weeds, find out what the guest wants, and make it happen. Simple.

In real life, sound doesn’t look like this. It’s actually mauve.

The flashing red bullseye tells you someone’s bellowing for your help. Follow it to the source—though once you get there, you’ll have to chase down the guest, who’s too busy calling you to notice you’ve arrived. Once you’re close enough, the guest will stop. Face em and hit E to get an earful. (The em isn’t a typo. An asexual species requires non-gendered pronouns, and I’ve chosen e, em, e’s. Yes, I’m aware that it makes everyone sound vaguely Cockney.)

Most encounters with a guest will require you to do something, like making dinner or dancing. Fortunately, nearly everything in this world can be accomplished by shaking yourself in some fashion. (A planet of pop stars? The mind boggles.) As you move, you fill the progress bar.

The chef makes the best denatured proteins this side of Low Cloud.

Once you complete a task, you’ll be rated so many stars out of five—much like a hotel rating, oddly enough. At the end, you’ll receive an aggregate score. Oh, and there’s a story, or something, but you can ignore that if you’d rather focus on your dancing and stuff.

Gas Food Lodging. Save the world all you want, pal. You’re still paying for the minibar.

Note: if you’re attempting to play this on an integrated GPU, you have my sympathies. I did all I could to optimize the drawing without losing the visual style I wanted. Didn’t help.

summer freeze, makes me feel fine

Gas has entered feature freeze. My last crack at the script prompted me to add a few new things to the codebase, after which I said enough, it’s fine, leave it. However, I tossed most of that script away, so it’s going to be another couple of weeks before I can release it. (Release Gas? Ha, ha, ha. I’ve been holding that one in for ages.)

I said after Easy Does It that I’d be trying to script earlier in the process than later. Though I did start the script early on, I kept thinking hey, let’s see what this looks like, so I’d look up a week later and find a new game concept (that I might actually use, or might not) and a half-finished rough script that didn’t read so well anymore. It didn’t help that I completely changed the point of the game twice. Indecision seems to be a problem, but who can tell?

bridge ideas

Gas, my current game project, has reached a turning point at last. I know this not because I’ve written a whole bunch of new code—actually, commits have fallen off a little lately—but because I’ve started removing the code that implements the bridge ideas.

I think most developers have this concept, even if they call it something else. For me, a bridge idea is only obvious in retrospect, a feature that I spend considerable time implementing but have to throw away in the end. A bridge idea moves the project along, and though it no longer suits the project, the project could never have been completed without it.

I just wish I had a better analogy than a bridge for this kind of idea. Yes, they both get you somewhere, but you usually don’t throw a real bridge away once you’ve crossed it. (Unless I’m missing a trick here. Disposable bridges? Get my people on the phone.)

drawing rooms and gas giants

I’m deep in the game script at the moment. Oddly enough, what I’d planned as a science fiction story about a clash of cultures on a distant gas giant world is turning into a 19th century drawing room comedy. It’s still set on a distant gas giant world, though. I hope that doesn’t confuse anyone.

On the technical side, one new approach I’m trying out is paying off. In the games I made previously, most objects were “smart”—that is, they contained all the game logic that concerned them. The player object knew about damage tables. A state machine for determining when an antagonist would break off an attack would be found in the object that maintained the antagonist, and so on. Each object maintained its own state and its own business logic.

This seemed logical to me until a couple months ago, when I was going over the source code for Easy Does It and realized that the game logic—code that describes how the game actually works—is all over the codebase. Hard to understand, hard to debug.

For the new game, I dipped into design patterns and came up with a model-view-controller like pattern to use. All drawable objects are dumb, knowing only how to create and draw themselves, rather like views. The game logic is maintained in one source file, broken up into several different modules. These are the controllers. And the tables that drive the game—the models—are maintained in another source file.

It feels right, and I’m finding it very easy to develop and make changes. I’m never wondering where a given feature or mod should go anymore. Every code function has a definitive place where it belongs.

Back to the drawing room. More tea, vicar?

when time isn’t a constant

I noticed a problem last night with Gas (working title for my current development effort). NPCs were jittering as they moved. I hadn’t noticed it much before, but I couldn’t unsee it now. I debugged my way down the chain.

Behavioral state machine, check. Physics, check. Drawing, check. I couldn’t find the reason. I set up a simple test, enlisting an NPC to run away from the camera at top speed, and I followed it, moving at what I thought would be the same speed.

It wasn’t, though. Acting on a hunch, I monitored the velocities of the NPC model and the camera, and found that the difference between them was fluctuating from frame to frame, sometimes as much as 10%. I checked the directional vectors—same. Speed? Same. What’s left?

Well, distance equals velocity times time. I checked the time intervals I was using to update the camera and NPC positions. They were varying by 5-50 milliseconds. Couldn’t be, I thought. I use a single time base calculated by my SOAR library on every animation frame. It had to be consistent!

Unless of course, the camera and the NPC were updating in two different frames. I couldn’t see how it was possible, but was all I had to go on. I started tagging frames to see which phase each update was happening in.

The camera and the NPC were indeed updating in two different frames. Since the time interval between animation frames can vary wildly, especially under heavy loads, a model updating its position in a frame before or after the camera updates its position will be drawn out-of-phase, so to speak, with the camera. This becomes significant at higher speeds, manifesting as jittery movements.

So, why were they updating in different frames? Three factors.

In the main application loop, updating and drawing are performed in two different methods. This way, if the player pauses the game (freezing all updates) then resizes the window, I can still redraw the scene with the new aspect ratio. This is usually fine, but it helped create the issue in this case.

I schedule the draw method to follow the update method. However, due to some fiddling I was doing with the SOAR library, scheduled methods are run in reverse order—the draw method is actually being executed before the update. Therefore, updates to a model aren’t drawn until the next animation frame. Now, that’s not actually a problem, as long as all the physics calculations are performed within the context of the update. You’d be fine as long as you didn’t do something stupid—like handling physics inside the draw.

Ahem. Well, I was trying to save some time. My display list handler iterates over all active drawable objects. Early on, I figured I could stuff in a quick call—if the drawable object is updatable, then update it. However, this forced the updates to the NPCs to be handled in the context of the draw, which was executed in the animation frame previous to the frame that updated the camera. Inconsistent timebases → mismatched velocities → jittery models.

I moved the NPC updates out of the display list draw and into the update handler. Result: rock-steady models. Boo-ya, I guess. It did strike me as funny that Time, the one parameter we usually assume constant, was the wildcard. Well, that and Stupid.

presented In glorious smell-o-vision

The game I’m working on now, which I’ll refer to as Gas until I have a real title, involves locating clouds of smelly stuff and sucking them up. I mocked up a cloud of tiny black triangles to serve as a test model, and discovered they were invisible against the busy background of the game world.

You can’t see them until you’re right on top of them, which defeats the purpose of drawing them at all. How do we make it easier for the player to detect them?

My first idea I ripped from Batman: Arkham City. In some quests, Batman has the unenviable task of homing in on a signal without any directional information. The player has to look at the distance to the signal and determine if s/he is moving closer or farther away–kind of a high-tech version of Marco Polo.

Well, that’s how smell works, too. You can’t home in directly on a smell–it’s based on molecular concentration, which isn’t directional. I whipped up a readout of how close the player was to the nearest cloud of smelly stuff and slapped it on the HUD.

It worked, but it was really a pain in the ass. I had to bob this way, that way, down and up, then left a bit. It works in Arkham City because the map is effectively 2D: much, much wider than it is tall. Gas is 3D. It’s as tall as it is wide, and your target may be right over your head or just under your feet.

Or: several hundred meters under your feet. It’s a big place.

Also, you don’t have any feet.

Anyway. The Marco Polo method didn’t work for me. I needed more information. I decided to try out an idea I’d had a while back, a solution looking for a problem. I’d wanted to create a low-information version of the scene itself, like when a game uses simulated night vision. You block out aesthetics, and only show stuff that a player absolutely needs to see, or the stuff they normally can’t see.

I called it smell-o-vision. It rendered the clouds of smelly stuff as black blobs on a big square canvas off to one side of the screen. I stepped back and admired my work. It didn’t take me long to see that it looked hideous, and was completely stupid. You’ve got a GPU pipeline, why are you writing a software renderer?

I wiped it out, and made a small change to the shader instead. Now, the triangles that make up the clouds render as white, not black. You can see them for miles.

If you want players to find stuff, you can give them readouts and gauges and clog up the screen with fancy HUD gadgets. Or, you can just make it easier to see.

Is the question really that (forgive me) black and white? I’m not sure. I think it has to depend on what’s fun about the game. Gas is a flight-based game. You’re flying about in the sky, and that’s pretty fun. If you have to read a little meter and stop and turn, read it again and stop and go down, read it again, and so on, it’s not so much fun anymore.

In Batman, you do glide above the ruins of Arkham City. It should be fun, but it’s Batman, so it’s really severe and gritty and technological and loaded with guilt. As far as I can see, the only fun Batman really has is punching goons. Punching goons is the best thing in the game. Everything else is pretty much window-dressing and getting from one place to punch goons to another place to punch goons. The meter doesn’t get between you and the goon-punching, so it’s really not a problem.

Plus, Bruce Wayne’s parents were gunned down in a back alley. Dealing with a dinky little meter isn’t going to make any impression on him at all.

easy does source, and prototypes too

Little progress on my latest project. I’m running not into code issues–I wish I were as those are much easier to solve–but questions like should it really work this way and do you need combat in a game to create risk and why does internal monologue register as italics, anyway, I mean, who thought that up and so on. It’s frustrating, but it will pass.

Anyway, I put the source code to Easy Does It into github, right here. I hope it’s of use to somebody.

One big code style change I forced on myself over the last few months was using the prototypal model in deriving JS objects. For Foam, Fissure, and Pavo, I used classic inheritance and object creation: function objects and the new operator. It looked familiar enough from my days as a C++ developer, and when you’re trying to get a foot into the door, familiar is good.

However, in JS, classic inheritance feels like what it kind of is: an attempt to shoehorn a familiar pattern into a language that was built with something else in mind. Prototypal inheritance is that something else, and I have to say, I’ve come to enjoy it. I rebuilt my WebGL wrapper, Foam, into a prototypal library called Soar and I’m happy with the results. Easy Does It is all prototypal, as is the game I’m working on now. I haven’t seen a new operator in months.

For objects that I’m going to create more than one instance of–drawable objects in particular–I’ve found this pattern incredibly useful. No idea if it has a formal name, but it’s like having a static function on a C++ class.

GAME.enemy = {

	init: function() {

		// create shader object shared by all instances
		this.shader = shader.create(...);

	},

	create: function() {

		// create an instance and populate it,
		var o = Object.create(GAME.enemy);
		o.position = this.getRandomPosition();
		o.damage = this.getRandomDamage();
		return o;

	}
};

...

	// initialization code
	// creates all shared resources
	GAME.enemy.init();

...

	// create lots of objects
	for (var i = 0; i < lots; i++) {
		list[i] = GAME.enemy.create();
	}

...

	// activate the shader for this type of object
	list[i].shader.activate();
	// draw all instances of this object
	for (var i = 0; i < lots; i++) {
		list[i].draw();
	}

Changes to the base object are, of course, propogated to all instances. I find this oddly pleasing, more so than I find the idea of a fixed base “class” as in C++ and Java. I have to admit it’s taken some time to warm to it, but here I am. Good place. Good place.