“Artwork” might be a bit of a generous term in this case, but here it is. I’m working on the first map of the game, on the ship going to Enceladus, drawing the tiles necessary to convincingly depict an interplanetary vessel. Here’s the outline of the ship as it appears zoomed way out in the map editor:
Not very ship shaped at the moment
And here’s what it looks like in the game:
I’m using Pyxel Edit to draw the tiles, then laying them down with Tiled. It’s a reasonable workflow for the most part, except that I have to make sure to never, ever change the order of the tiles in the exported tile sheet or else face starting over entirely. Also, I’ve found some annoying, but not deal-breaking, issues with Tiled’s auto-mapping feature, which I’m using to automatically fill in the collision layer with whatever is in the foreground layer. The system is convoluted and confusing, there’s no concept of a wildcard, and I just learned that each orientation of a tile counts as a different tile in the rule set. Even for the very limited tile set so far, I have a huge auto mapping rule.
This is already getting out of hand.
This map also exposed some buggy behavior in the camera controls during room transitions (very obvious in the video) that I’ll have to sort out. I’m a bit torn how to fix this issue in the general case. The problem is that the character is moving between two rooms with different height ceilings, so his vertical position on the screen will have to change. It would be easy enough to make that a smooth transition, but I’m left asking myself a question that I ask myself embarrassingly often: What Would Super Metroid Do? I have a gut feeling that Super Metroid would design the level map so that the ceiling height of two adjacent rooms is the same. I’ll have to sleep on it.
Today I plunged in to the arcane and confusing world of Direct3d pixel shaders, which I will have to put to good use if I want this game to look even a little impressive. Here’s a prototype of a shader that renders a wave of energy advancing outward from the character’s position:
This is to enable a tool I’m excited to implement, something I’ve been calling the sonic excavator, which will help players find hidden passages.
In many exploration games, there’s some tool that allows you to inspect the game world to see if any solid-looking terrain is vulnerable to one of your weapons, thereby opening up a secret passage. Super Metroid has the X-ray scope, Shadow Complex has the flashlight, and Insanely Twisted Shadow Planet has a sort of scanning beam. Of these three, I consider the latter two failures, since they take any mystery out of exploring. In Shadow Complex, there’s literally no reason not to keep your flashlight on all the time, and since it makes any vulnerable terrain you walk past light up like a neon sign, there’s almost never any doubt about where secret passages are. In ITSP, your scanning beam just tells you what tool can affect a given object. This isn’t as bad as Shadow Complex, since you have to switch to your scan beam and then wave it toward the thing you want to scan, rather than it just happening all the time in the background. The x-ray scope in Super Metroid is the best of these, since 1) it’s an optional pickup that you find relatively late in the game, and 2) it’s a bit cumbersome to use all the time, since it stops the action and it takes a while to scan the whole screen.
Exploration games have quite a lot in common with mystery novels — the author gives the player hints and clues and then lets them figure things out by themselves. It’s a kind of pact between the creator and the consumer, a promise that “I’m telling you everything you need to know, but you’ll still have to think.” Many modern games break this pact by holding the player’s hand every step of the way, turning the game into a kind of moderately interactive guided sightseeing tour. Just to make sure this metaphor is squeezed good and dry, the flashlight in Shadow Complex is the equivalent of the following passage in a mystery novel:
As the butler entered the foyer, Detective Sanchez noticed he had spatters of blood on his pristine white gloves and a sooty hand print on his starched collar. Sanchez looked at the dead chimney sweep crumpled on the ground, his throat opened and a trail of bloody footprints leading to the door through which the butler had just entered. Just then he got a text message from headquarters, and pulled his phone from his pocket to see that the butler was wanted for murder in six other states and had spells of psychotic rage.
Except in an actual mystery novel, the above passage would be a guarantee that the butler was innocent. If modern video game designers were in charge of writing this hypothetical novel, it would wrap up six pages later with the butler’s successful conviction.
Anyway, I want to restore some sense of mystery to the player, and the way you do that is by letting go of their hand and letting them figure things out on their own. The sonar excavator is an exploration tool that aims to keep the player guessing. It will fire a pulse of sound at a wall, and if there are any points of interest hit, such as a destructible tile, it will respond with a ping sound, which varies based on what was hit. You’ll start with a very narrow beam, and throughout the course of the game your successful exploration will be rewarded with upgrades to the excavator that make the beam wider, or makes the target that you hit glow, or also kills weak enemies, that sort of thing.
Speaking of sounds, I played around with a lo-fi sound creation tool created for Ludum Dare called sfxer. It’s pretty keen, and quickly gave me some basic chip-tuney sounds for lasers and landing after a jump. I’m almost to the point where I want to start plugging in sounds for a lot of the game content, and this will let me prototype placeholders really rapidly.
I got three small-ish features cranked out today: 4-way shooting, selectively (not universally) destructible tiles, and doors. Have a look:
Doors and selectively destructible tiles are both easily edited using an object layer in Tiled, and both can be keyed in to respond only to particular weapons, again using the map editor.
Right now the doors are three tiles high, and the character is two high. I’m a bit torn on this point: I think I would ideally have them both be one tile higher, mostly just because that’s what Super Metroid does. I’m kidding, kind of. In any case, the reason that Super Metroid did this was because they couldn’t easily deal in partial tile distances, and they needed to have three distinct character heights for the Morph Ball, kneeling, and standing (one, two, and three tiles high respectively). And Samus is pretty chunky in Super Metroid, even in profile — assuming she’s six feet tall, that makes her two feet wide at the shoulder. Must be the armor? My motion capture model is pretty svelte, but I won’t have a really firm idea on the proportions until I prototype the actual motion-captured sprites.
Still thinking about yesterday’s project, I did quite a bit of reading about various camera controls used in other games. There’s remarkably little out there on this topic considering how fundamental it is to a game’s playability. I started with this article someone posted to /r/gamedev on reddit today, then found this analysis of Super Mario World.
It’s very interesting to me how very few people would pay attention to the behavior of the camera in a 2D side-scrolling game, despite it being of such paramount importance. I can honestly say that I had never considered how the camera in Super Mario World worked until watching that. In some sense, you could say that a camera system (like most software) is like plumbing — you only notice it when it doesn’t work properly.
Of course there has been plenty of advancement in this field since Nintendo’s heyday, even if you almost never hear it mentioned, especially for 2D games. Insanely Twisted Shadow Planet did some inspiring work on this front.
In fact, I was inspired to download it from XBLA, and I’m going to go play it now.
When exploration is the driving goal of your game, you want to make it easy to navigate around the game world and contextualize your current location. Breaking the world into discrete rooms is important to this end, since it helps the player break the problem of navigation down into manageable chunks and contains any puzzles and encounters in a known area. Today I implemented rooms in my map engine:
I’m not quite satisfied with the transition between rooms, but it’s good enough for the time being. As you can see from the video, the game loads and unloads the dynamic content (like enemies) and physics model of each room as needed. This will make it a lot easier for the physics engine to cope with lots of on-screen action as the world grows in size, since only the current room is simulated at any time.
I have a couple things to note about this implementation before I sign off.
First, rooms are rectangles. At first blush, this would seem to impose a constraint on level design: that any two room exits to the west, for example, would need to be vertically aligned. That’s not actually the case, owing to how it’s implemented. There are two ways to exit a room: either enter a door or leave the room’s boundary. Doors will be smart enough to guide a player into any adjacent (or overlapping) room in their direction, even if they don’t sit on the room boundary, and I can add “virtual doors” to hidden passages if I absolutely need to. I’ll post a screenshot or two if and when this comes up to demonstrate what I’m talking about.
Second, before this change, the position of a tile was located at its center. This makes some things convenient, but when it comes to working with Tiled maps, where you can draw object layers on top of tile layers, you really want this position to be the top-left corner of a tile, so that what you see in the editor will match up with the world you build in the physics engine. I took the time to make that change, since it was leading to some less-than-obvious behavior in the implementation.
At this point I have the basic mechanics of level creation, destruction, and movement working about how I want, so I’ll be moving on to prototyping various weapons and power ups to figure out which ones will feature in the game. Actually, I lied: before I do that I need to get shootable doors working and add selective destructiveness to the mapping system. But those are both small, manageable changes I hope to bang out tomorrow.
Every great action-exploration game has one thing in common: tight, responsive controls. If the character doesn’t respond in a consistent, intuitive way to your commands, the game is going to be frustrating to play at its most basic level. Control is so crucial that I’m spending quite a bit of effort early on to make sure it’s perfect. There are project dependency reasons to focus on this up front as well — knowing how high and far a character can jump, for example, can profoundly influence level design.
Like everyone who saw it, I was deeply inspired by Bret Victor’s talk about game development at Inventing on Principle. The most relevant portion is reproduced below:
I’m not nearly as fancy as Victor is, mostly because I don’t want to spend as long on my tool chain, and because my choice of language (C#) makes his demo slightly more complicated. But the basic idea of being able to play around with simple variables at runtime, without having to recompile or restart the program, struck me as absolutely vital. So I built my own small system to let me do that.
This version allows you to increment or decrement various character control parameters as you experiment with them. The hardest part is actually knowing which parameters might be important and how to use them to produce engaging control characteristics.
Just as a simple example, what happens when the character is standing still and the player presses right on the stick? Do you start accelerating to the right at a constant rate? In practice I found this makes the control feel beyond sluggish. I have my character instantaneously accelerating to a pretty good clip right away, then accelerating smoothly afterwards up to a maximum speed. Both these parameters are configurable so I can play around with them to see what feels right.
Jumping is even more fraught. It’s important to the player’s sense of control that holding down the jump button longer makes the character jump higher, but how to implement this behavior is anything but straightforward. For now, I have a few parameters controlling it: the initial jump speed; how much to accelerate the character for every frame the button is held once airborne; and how long this effect should persist. It’s interesting to play around with very high values for the latter two variables — setting the air boost variable above the acceleration due to gravity turns you into a rocket.
I’m also realizing that I really need to be able to fool around with gravity in this sandbox. At the moment the jumps feel downright floaty, which is an artifact of the character launching off at over 10 meters a second — it’s gonna take you a while to fall back to earth with that kind of kick. For reference, each of the tiles in the game world are one meter wide, and the character is two meters tall. Since you want a brief tap of the jump button to result in a tiny little jump, it’s becoming clear to me that the initial jump speed will need to be much, much smaller, and that the air-boosting effect will need to be much more prominent, probably involving a fade function of some sort to diminish its effect over time.