I did mention when I announced that my game has been uploaded that I wasn't as satisfied with this entry compared to my previous one, so I was pleasantly surprised by the majority of the feedback that I got. Firstly, I'm really glad that many of you found it enjoyable to play. That's probably the most important part of a game, in my opinion. :)
I was a bit disappointed to read that the game crashed for at least two people, but that's what happens when I implement most of the actual gameplay in the last two days of PyWeek. In particular, I didn't even get the shop done until about four hours before the coding deadline, and I just finished adding sounds about an hour before it, too. If it does crash for anyone in the future, feel free to post a traceback in the comments.
In the end, this PyWeek was even more fun and interesting than the last one, particularly since I felt that I learned even more from this one. I'll go over a bunch of thoughts and lessons that I have collected now that the judging period is over.
The parts that were never realized
I think the main reason that I was initially not as satisfied with the result was because there were so many things that I had to remove due to time constraints. Now that I look at how many .py files there are in the source code folder, I kinda surprised myself with how much I actually implemented during that week. Despite that, there are a lot of unimplemented things that could have made the game better.
The pacing of the game, which several of the comments alluded to, did suffer partially because of a “scripted” event that I did not have time to implement. It was going to occur on the third level, and it would have spawned a few enemies that you had to run away from after you got the coordinate data on that level. In retrospect, however, I should probably just cut that level out altogether since people probably understood the excavation mechanics after the second level, if not the first one. If I had done that, the player would have seen the enemies a bit sooner, which would help the game's pacing.
Related to that is that I was also going to put some story elements in the game. I was going to have log files (that were buried for some reason) that the player can read, an introductory wall of text when the game started for the first time, and an ending wall of text that explains just why that mysterious red crystal was so bad. This does sound ambitious, which was probably why it never made it into the game.
I was also going to make the first level be the tutorial, but I settled for writing a manual instead. I'm glad that the manual helped people understand the gameplay mechanics. A tutorial would still be ideal, though, since playing is more fun than reading instructions.
Many people also pointed out the lack of music, and that's one aspect of the game that I simply did not have time for, unfortunately. I agree that it would really help the game out a lot.
There were a lot of other things that I wanted to include, such as optional levels, but I can't have everything. Well...I can always work on this game more now that this PyWeek is essentially over, right? :)
The learning process
I implemented many new things for the first time during this project, and some of this stuff turned out to be tricky. I think I spent the first day or so just implementing a scrolling camera. Some stuff turned out to be much easier than I thought, however, especially save games. The pickle module pretty much did the work for me in that case, although I'm a bit aware of its drawbacks. For something like PyWeek, though, it's fine :p
Also, my collision detection code is awful and inefficient. Just take a look at this snippet of code from terrain.py:
def process_bullets(self): for bullet in self.bullets: bullet.update() bullet_rect = bullet.get_pos_rect() player_hitbox = self.player_vehicle.get_hitbox() if not bullet.friendly and player_hitbox.colliderect(bullet_rect): self.player_vehicle.on_damage(bullet.damage) bullet.hit = True elif bullet.friendly: for enemy in self.enemies: enemy_hitbox = enemy.get_hitbox() if bullet.friendly and enemy_hitbox.colliderect(bullet_rect): enemy.on_damage(bullet.damage, self.player_vehicle) bullet.hit = True self.enemy_hit_sound_play = True break # Only one enemy should be hit per bullet if bullet.hit: alert_rect = pygame.Rect(0, 0, 500, 500) alert_rect.center = bullet_rect.center for enemy in self.enemies: enemy_rect = enemy.get_pos_rect() if alert_rect.colliderect(enemy_rect): enemy.aware = True enemy.aware_timeout = 5 * FPS
This code was actually a bit problematic towards the end of the week. During the second-to-last day, I started creating the levels, and the level sizes were so big that stray bullets were inevitably everywhere, slowing the game down to as low as 40 FPS instead of the 60 that I was aiming for. As soon as I realized this, I got a bit discouraged. Reducing the level sizes did help to cloak this problem, and it also made it easier to populate the levels with enough enemies instead of having vast, empty spaces, but it was still annoying to deal with. If I ever make another game that depends heavily on collision detection, I will need to implement some more efficient techniques.
The menus were also painful to write, although remembering that functions can be assigned to variables really helped a lot. The shop system is just...bad. Please don't look at it :p
Finally, unlike the last entry, I wanted to have some graphics other than rectangles, and so working with those graphics was something that was new to me, too.
For next time...
I think I should probably try to have an idea that doesn't depend too much on level data, since I'm kinda tired of making one-off level formats. I did that during the last entry too, and it was annoying to have to write code to parse my hand-rolled level format and to make sure that the levels were actually how I intended them to be. In fact, during the hour or so I spent playtesting, I found a bug where one of the weapon blueprints didn't spawn because I typo'd the item id number.
Either that, or I should use formats that already exist. I saw that one entry used JSON(?) or something like that.
Also, as mentioned above, I definitely will have to research better methods of collision detection and practice implementing them. I can't be using the naive and inefficient method forever :p Quadtrees, anyone? (or anything else?)
And I should put some music in already...
This was a fun PyWeek, and I enjoyed creating something for it. I feel bad admitting that I only played roughly one-fourth of the other entries, but many of them were quite fantastic, and I still have no idea how some of you manage to make 3D-based games in a week!
Also, I might work more on this game and on my last entry as well, so I might announce updated versions (and hopefully Windows builds) later on. I can't promise anything though since I am a college student, after all :p
Finally, thanks goes to the PyWeek organizers and to everyone that played and gave feedback on my game. :)
(log in to comment)