Lunar: Post-mortem

Not a "strict" plan

This time I didn't have a complete game idea but some notes in a piece of paper. I don't know if that's the reason why this PyWeek has been less stressful than the previous one, but in "For Science!" I had a clear roadmap from the beginning and in "Lunar" I had more or less a story I wanted to tell and basically I had to implement things to make it happen. It may sound like it is the same but it is not, "Lunar" approach is more flexible.

I wanted to make something in 3D and I wanted the story to be a central part of the game. I played a lot of point-and-click adventure games back in my day, and I tried to make one myself when I was 14 (gwbasic, CGA 4 colors and the confidence of a teenager) but I'm not an artist and the visual part of the adventures is quite important.

Also I read recently the SCUMM diary, so I thought that may be using 3D graphics (I've been practising with Wings3D; still a lot of things to learn, my texturing abilities are almost zero!) and using tiled I could implement a simple adventure... in a week.

The truth is that this kind of game is not a very good idea for PyWeek because you have to work double: make the game engine and then... make the game!

That's the main reason why the game is not too long. I had time to put some background to have a backing story, but then there was time only for a couple of puzzles really :(


This time I went for just pyglet, and I think that was a good idea. I used a couple of things I have never used before, but pyglet docs are great and the source code is clear and neat so that was OK.

More or less the same with OpenGL. I had to implement a couple of things I didn't know how to do but reading the docs and with some luck I finally managed to get most things done. The only part I'm not entirely happy with is the positioning of the "attention" icon: I couldn't get the 3D to 2D projection of the character right and that's why the final result looks a little bit "wrong" depending on the perspective.

I had a couple of "crisis" though. As I didn't have a strict plan, I had just a vague idea of how to implement some things.

First big problem was when I was going to animate the doors and I realized my rendering engine was wrong and it didn't support animations... so I had to rewrite a big part of it. I was using ONE OpenGL list to render the scene, and I had to split the layers in different lists because redrawing the whole scene in each animation frame was killing the frame rate (more about performance later).

I didn't have time to investigate VBOs (or pyglet's batches, it's the same thing) and the code I had to load and render Wavefront objects was using lists (an example contributed by Richard to pyglet). I was already writing my own code to read tiled JSON files, so I had to workaround the issue having a different list per layer and re-compiling the foreground layer (the one with the doors).

That was difficult to fix, but I think I got it right at the end.

The second problem was that I misunderstood how tiled manages tile layers and I was setting properties in the tileset without noticing that it meant, for example, that all the doors had the same properties. So when a door was opening and its "z" coordinate changed, all the doors moved at the same time!

I fixed this in a "simple" way but I had more or less the same issue with other parts so I ended having an extra JSON file per map to add actions (doors), info points, and define the map exists. Also tiled only supports text properties and I wanted objects, so having the external file was easier to manage.

The approach to draw the scenes is a little bit too simple and that did hurt the performance. It works like a regular 2D tile engine, but my tiles were 3D objects and that's it. This approach has its limitations, but the worst part of it was just to split the "quarters" scene in two because there were too many things to draw. I tried the game in a 5 years old netbook and it did perform perfect, so it wasn't that bad.

I was willing to try a shader to have some shadows in the scenes, but I didn't have the time. I think it was for the best because using simple OpenGL stuff means the game will be more portable.

Finally I left the sound for the last moment and I was a little bit too tired. The end result is OK, but man... I had to repeat the door opening/closing sound effect a dozen times!

Another thing different this PyWeek was testing. At some point the engine was powerful enough to implement the story, but then there was a lot to test... and it was really tedious. At this point my wife helped me beta testing the game (when there was a game, last day by lunch!), and she found several bugs. So if you plan to make a game like this, add testing to your list of things to do!


As I already said, this PyWeek was less stressing. I spent 20% of the time modelling 3D objects, 20% tackling tiled and writing the story in JSON files, and just a 60% writing code. I think in previous PyWeeks I spent way too much time just programming... so I think shifting part of the work to high level tools (although loading tiled JSON files wasn't too easy) was a good idea.

I'm happy with the result, even if the game is a little bit too short because of the limited time for just one person to do everything. But well... that's PyWeek, isn't it? I'm happy I finally made my first adventure!

(log in to comment)


Just for the record, my punchcard for the project:

That's not exactly a week, is it? Because of my job, obviously. Also the amount of commits doesn't reflect 100% the amount of work done, but close enough.