Final version

Lunar

Lunar

Year 2040.

Two decades have passed since the first corporation established a permanent lunar base under the surface of the Moon.

Today the Lunar Commerce Commission maintains a frail balance between the different corporations competing for mineral resources.

Accidents are frequent, although officials refuse to admit that they're due to sabotage or an undercover war for the rich lunar underground.

Please download the source code for Linux and Mac or the binary bundle (ready to go) for Windows. Check README.txt for instructions.

Video of the intro (no spoilers).

For post-compo updates and more (Debian/Ubuntu packages) please visit: Lunar.

Awards

Give this entry an award

Scores

Ratings (show detail)

Overall: 3.6
Fun: 3.4
Production: 4.1
Innovation: 3.4

5% respondents marked the game as not working.
Respondents: 17

Files

File Uploader Date
final_version.png
Final version
reidrac 2013/09/07 16:52
lunar-pyweek17.zipfinal
Final version, source code
reidrac 2013/09/07 16:37
lunar-pyweek17_windows.zipfinal
Final version, Windows binary bundle
reidrac 2013/09/07 16:35
screenshot0.0111129283905.png
The avatar
reidrac 2013/09/04 20:02
screenshot0.0123400688171.png
Few assets
reidrac 2013/09/03 20:32
screenshot0.01606798172.jpg
Some progress
reidrac 2013/09/02 20:11
screenshot0.0171370506287.jpg
Early alpha
reidrac 2013/09/01 20:17

Diary Entries

Day 1: Foundations

I didn't like "Moon" at first but after looking for ideas for the other themes I changed my mind and went for it. I'm glad "Moon" was the selected theme!

I want to do something with 3D this PyWeek, although it may turn out not to be a good idea. Also I would like the story and the mood to be an important part of the game, but I'm not sure if I will be able to accomplish that.

Today has been a tired and slow start. I must prepare a "code base" for next PyWeeks because it is absurd the amount of work to bootstrap a game; yet to start writing the game itself!

Early alpha of the engine

Anyway I think I have reasonably good foundations for the rest of the contest.

I'm using plain Pyglet so today I've been working on the structure with scenes and scene states (kind of like cocos2d, but way simpler). I've started working in the game core, based in tiled maps rendered into 3D, and pretty much that's all for today.

2 comments

Day 2: Textures, doors and problems

Here we are, at the end of the second day and far away from anything playable :)

I'm starting to think that going 3D was a terrible idea, but well... it's too soon to say it is impossible, isn't it?

Some progress

First the good stuff: tiled layers work (floor and walls are by now in the GB layer, the doors are in the FG layer). I managed to draw some textures (although I can see some glitches here and there; I'll look at them later) and started working on the switches; until I found my first problem. Something seems to be wrong in the way the model is loading and I don't know why :(

I'm tired and I need some rest for tomorrow; so I'll leave it here for now. Hopefully tomorrow I'll be able to get the switches right and start modelling some objects before starting with the character.

EDIT: found the problem with the switches: the texture had the wrong size. I though it was smart to use a 128x128 texture for a such small model (Wings3D renders it OK!), but oh mysteries of OpenGL... it doesn't work in my program :) - back to 256x256 for the win!

4 comments

Day 3: Assets and sound

Today I've been working mostly with the 3D modeller to have few assets to make the lunar base look nice, or at least to make it look like a lunar base. So far, so good. I can't use more time on this, I'll come back to it later if I can!

Look at the following screenshot, I'm getting there!

Assets, assets, assets!

Besides the assets I've added some sound to the intro (I've played a silly tune with the guitar, not sure about it though) and the cut scene (yes, there's one with very lame voice acting!). All together I think it works to set up the mood.

Tomorrow is time to model the character and/or start to make something playable. I count on Friday (I'm off work) and Saturday for the final sprint, but I need to keep moving forward with the story-writing and the engine otherwise I'll end with a nice looking non playable game :(

Anyway, enough for today!

1 comment

Day 4: But it moves!

Today has been quite productive.

I have around 45 minutes commuting every day so I've been using that "dead" time to write part of the story, and that led me to model more assets (ufff); but it's OK: without a good story the game would be a total failure, and a good scene makes the story more effective.

I modelled the avatar (a droid) and... well, it looks like a droid (more or less) so I'm happy!

http://media.pyweek.org/dl/17/useboxnet4/screenshot0.0111129283905.png

I've implemented basic movement (no collision detection yet, but if I'm right it shouldn't be too hard).

It doesn't look like a big advancement, but I think it really is. I'm not confident in my modelling abilities so having enough assets and a character for the player to move around and interact with the scene is a big win.

For tomorrow I plan doing the collision and start the interaction with the scene (I plan to implement two verbs: "see" and "use", or something like that). If that gets done I'll be in a good position to finish a the game between Friday and Saturday.

Also tomorrow I'll try to use my commute to close the script because at the moment I don't know how to close the story :S. Stay tuned!

Add a comment

Day 5: Collision detection, new rendering engine

Today hasn't been great, but well... that's "planning" in my book.

I did the collision detection and I'm very happy with the results. I tried to make the movement as fluid as possible, making "subtle corrections" in the trajectory to make easier to the player to move around without getting stuck (some locations may be a little bit narrow).

I'm too tired to explain how it works, but I can point you to this post instead: http://old.troygilbert.com/2006/10/the-movement-and-attack-mechanics-of-the-legend-of-zelda/

I've been worrying all the time that implementing that kind of collision detection would be too expensive but the end result is really smooth and the frame rate is still 60 FPS with plain Python and pyglet (no numpy or fancy stuff like that!).

Then I started to deal with the animations of the scene (ie. a door opens) and there you go, three hours wasted :(. Basically I had to rewrite the rendering engine to render different layers in different steps so I could animate the doors in the foreground layer without wasting time with the background layer. Now I can invalidate just one layer. Again, 60 FPS. Yay!

I misunderstood how tile layers work in tiled and turns out that what I was planning to do can't be done :'(. I've been looking for a solution and I think I can make it work but I guess that I'm moving the "spaghetti code" expression to the next level. It's all right, that's part of a PyWeek :)

Finally the story is more or less clear. I think I can provide a good experience (don't know for how long).

The spirits are high, although I have lots of things to do and only two days left!

Add a comment

Day 6 (1): Most interaction elements are working!

This is a quick update, I'll write another post by the end of the day.

Just a quick preview of how things look so far: https://www.youtube.com/watch?v=KOJaGCS1zMA

Still lots of things to do, but so far my hack to workaround tiled limitations seems to hold in place!

Add a comment

Day 6 (2): Maps almost done

Last night I tried to write a post but either my connection was failing or the website had problems, anyway... this is the second part of day six.

I was a little bit wrong about my workaround for tiled's maps, it wasn't working (well, it was almost working). I realized it was wrong when I had in a map two doors based on the same tile and when one of them was opening, the other was opening too. It turns out the hack was a good idea but it was bad implemented. Now it's fixed :)

Another problem I had yesterday and got me stuck for a while is the translation from screen coordinates to map coordinates. I did all my tests with just one map and it happens that my translation of coordinates was wrong but for that particular map wasn't noticeable. When I started to test another map... oh, I can walk through the walls! It's fixed but I'm worried something like this could happen by the end of the last day and it could be fatal!

I don't think I have time for unittest everything but I could use some tests. The engine complexity makes difficult to spot a bug; and when it's fixed, that could break something else and I wouldn't notice.

I have 6 maps already and I think I'll end with 10, so there will be a good sized moon base to explore ;)

I have several things to do in the last day, so let's do this! 18 hours left :)

Add a comment

Final version uploaded!

I know the countdown says more than 7 hours to go, but I'm exhausted and everything is in place, so I've uploaded the final version of my PyWeek 17 entry: Lunar.

This time my wife helped me a lot playing the game today and finding embarrassing bugs (still don't know how she managed to "moonwalk" between maps); so I've been fixing things for the last two hours. 

Anyway, I didn't have a chance to test the game in Mac, so I booted the windows box I have just for building the binary bundles for PyWeek and tried the game. It works perfect, I'm pleased with the performance. Because I already booted the machine I built the binary bundle, so you can download the source code for Linux and Mac, and the binary bundle for Windows.

Linux and Mac require Python 2.6+ and AVBin installed, in Windows just run the EXE. There's more information in the README.txt.

Today has been a long day. Started finishing the maps and polishing the story, and left the sound to be added after lunch. That was probably a bad idea because by noon I was too tired to tackle SoundTracker. At the end I got a bg track, not too bad.

Well, I'll write a post mortem in next days but needless to say that I'm extremely happy. Yet another game delivered!

Add a comment

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 :(


Development

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!


Conclusions

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!

1 comment