AboutBecause of travel and work, I had less time than usual for PyWeek. I decided to go solo, which I haven't done since PyWeek 18, because coordinating always takes a lot of time, and scale back the scope. Given that, the game turned out okay.
For the core mechanic I focused on the word "behind" and what it means to be behind something in a game. I had just watched a Super Mario World ROM hack where there were platforms in both the foreground and background, and I thought, what if there were a platformer where things that were behind something in the foreground didn't exist, and what the player can see is reality. (I was also inspired by a popular indie platformer game Closure, where things that cannot be seen effectively don't exist.)
My original idea was a lot like the popular indie game Fez. In a way it was the reverse of Fez. Instead of an apparently 2D world that was actually 3D, I was imagining something that seemed 3D, but behaved like it was 2D. In fact, it was so much like Fez that I decided I had to change it (the entry I was on for PyWeek 12 was criticized for being too much like Braid, after all).
My first day of design was me asking myself, how can I make this less like Fez? I avoided a square grid and pixel art (which I generally avoid anyway). I switched the idea from a puzzle platformer to an infinite runner, and removed the ability for the player to control the camera directly. This meant I had to give the player the ability to move forward and back. With the infinite runner mechanic, the only way to "move" certain foreground elements in front of certain background elements is to change the moment at which you interact with them. This turned out to be a very crude method of achieving what I originally had in mind. I wanted the player to have to figure out where to stand for different challenges, but this is far too hard to do given the pacing, so I put up arrows to just tell you where to stand. I also realized that the ability to go left/right opened a long jump mechanic, but rather than try to design around that, I made it an explicit part of the game.
I always say that for a platformer, more than any other genre, you have to spend a lot of time getting the feel just right. The responsiveness of the controls really makes or breaks the game. I spent a little time replaying Canabalt, which is widely considered to define the infinite runner subgenre, and this inspired me to go faster and "heavier". I gave the character a lot more inertia than I normally would for a platformer, but that seems appropriate. I'm still a little unsatisfied with the character motion on slopes, but overall it's okay.
I made two subtle changes that hopefully you didn't notice. If you press "jump" while falling through the air, but within 0.2 seconds of landing, you'll jump as soon as you hit the ground. Also, if you press (and hold) jump while running, but within 0.2 seconds of reaching the ledge, your jump will be delayed until you reach the ledge. Playing it myself, I can't tell that it's this way, but it makes a big difference on how often I'm able to make jumps.
The graphics are not great, but as usual I was able to make it work with arbitrary resolutions by using procedural generation. Each hill is an image that gets generated as needed. I found a pretty effective way to draw hills as needed as the game goes along, while spreading out the work to multiple game frames so there's not a noticeable lag when a new hill is loaded. I'm thinking about extracting this part into a separate library for future use. Overall I'm getting 30-60 frames per second on my Intel NUC. People keep saying there's a limit to pygame performance, and I believe it, but I've never run into it during PyWeek.
I made the character have a dress so I wouldn't have to animate legs for the walk cycle, and I wound up swiping the overall character design from this animation.
I didn't have a musician for the first time since PyWeek 18, so it's good to see that Kevin MacLeod of Incompetech is still making great royalty-free tracks. I wanted to use ChipTone for sound effects, but it kept crashing my Flash plugin, so OpenGameArt came through. You think you'll save so much time by using pre-existing assets, but it's never as true as it seems like it should be.
I had a great time participating, as always! Thanks to everyone who made it possible, and the community!
(log in to comment)