Because 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)


Hi,Cosmologicon, your game really surprised me this time, amazing, awesome. I also use pygame, but maybe it would cost me years to develop such a game like yours. I first attracted by the player moving smoothly at slop, when I check the code, I suddenly found that you also draw the hills,it is cool. I still do not know how do you do that, when player climbing up, and going down, the player position is calculated by the hill slop? Or just deal with its legs? And how to deal with the hill of 3D effect, close to the screen is bigger and moving fast? It is magic in my eyes, I like Fez, the author's story is also moves me, I pay great respects to the indie gamers, btw, do you teach making games? I really want to learn more :)
Oh, thank you!

Well, I don't recommend trying to learn anything from my PyWeek code. I'm sure it's badly written and badly commented. I would be happy to discuss any particular techniques if you want, but I don't have my thoughts organized very well on them, so there are probably better resources to learn them from.

Haha, how modest you are, I am sure you must spend a lot of time on it. Maybe you are perfectionist and cautious to give a tutorial,also it is time consuming. I will try to find the key :) I am your fan, and happy Halloween!
The idea of jumping between the perspective layers was very cool. It reminded me a bit of Little Big Planet but isolating the idea as a core mechanic really allowed you to flesh this out and play around with it as a timing puzzle.

How on earth did you do the level design? 

It seems like it would be incredibly fiddly to adjust the timings to make sure that the different layers arrived at just the right time. Given how long the "level" was that seems like it would be a nightmare to tune it all so that it was balanced.

The animation of the character was really great and the platformer mechanics tuned perfectly considering you were not just having horizontal and vertical surfaces. That's not easy to pull off and it felt just right (including the "hacks" you mentioned).