Christian's Projects » game programming http://www.incasoftware.de/~kamm/projects Mon, 26 Jun 2017 20:29:06 +0000 en-US hourly 1 http://wordpress.org/?v=3.5.1 Game In A Day: PyDogs http://www.incasoftware.de/~kamm/projects/index.static/2008/04/12/game-in-a-day-pydogs/ http://www.incasoftware.de/~kamm/projects/index.static/2008/04/12/game-in-a-day-pydogs/#comments Sat, 12 Apr 2008 14:42:58 +0000 Christian http://www.incasoftware.de/~kamm/projects/?p=6 Creating computer games is usually envisioned as a long and intricate process, requiring years of work by dedicated teams of professionals. Even in the open source world game projects often end up unfinished and abandoned after months of work have gone into them. The Game-in-a-Day events people have reported on during the last years defy that paradigm: during these sessions the main goal is to get things done and to get them done quickly.

This refreshing change from usual development practice along with it being a challenge as well as a good time with friends have made Game-in-a-Day events appealing enough for whole communities (edit: link removed, unfortunately dead by now) to have formed around them. Last October I decided to mail all my friends and host one myself.

After the usual scheduling woes Roman Pohrt, Torsten Gellert, Felix Stürmer and Anne Pohrt (part-time) brought their computers and participated. Julian Bischof couldn’t bring his equipment but created some music for us remotely.

As our group contained no real artists, it was clear from the start that our result would not look particularly pretty. On the other hand, everyone had some programming experience, albeit evenly distributed between C++, D, Python and Java. Consequently, we figured we would try to make up for it in gameplay and features. That also meant we could skip the obligatory asteroids clone and tackle something more complicated.

The collective search for a game idea finished quickly. We were going to improve on C-Dogs by supporting multiple players on one computer. We also planned to replace its line-of-sight effect with my (then recent) soft shadows implementation, hoping to overshadow our lack of art by composing our levels from dark hallways and by using lots of special effects.

Next was the choice of programming language and libraries. Since there was no common denominator, we selected Python and pyglet. It turned out to be a very good decision. Even though half of us had not used the language before, the essentials were easy to pick up and soon everyone was able to contribute: At the end of the first day I made our previously hardcoded weapons system more modular, then went to bed. When I pulled the changes next morning, there were four different guns (and an electro zapper) and someone had added code so they could be put down and picked up.

Our source management tool, mercurial, was employed less successfully. We had one or two cases where we accidentally automerged into the wrong direction and propagated those incorrect changes through our repositories. However, I maintain that these issues could have been avoided if we had been more familiar with mercurial and that a centralized version control system would have had even more trouble with the highly concurrent nature of our development.

This is when we got started. After about 16 hours of work (spread out over the weekend) we ended up with the current feature set:

  • up to three players can play simultaneously
  • they can move, shoot and bump into walls
  • the levels are randomly generated
  • there are three kinds of monsters, all with different behaviors</li>
  • players have hitpoints and can die
  • five different types of weapons lie scattered around the levels and can be picked up
  • background music plays
  • finding the blue goal portal teleports to the next level

From the start we structured our efforts pretty well. At least one person was always working on the next logical step or an absolutely necessary subsystem. We also implemented quick placeholders for things that were to come later. For instance, it took a lot more effort to get solid random level generation working than we expected, but due to a square placeholder level it did not delay the development of other components at all.

Nevertheless, there are some things that did not get implemented or fixed in time:

  • the game is too slow
  • collision detection breaks often
  • level generation sometimes produces incorrect geometry
  • line of sight and shadows are missing
  • there is no menu

The slowness is definitely our major issue. We started profiling and sped up some parts of the code considerably, but it wouldn’t help. In the end, we even concluded that while Python had been an ideal choice from the perspective of getting everyone involved and productive quickly, it had also failed us due to its lack of speed.
In hindsight, I’m pretty sure we were wrong in our assumption that some Python code was to blame for the speed deficiency. If I comment out our level drawing, which is basically a set of OpenGL calls, my framerate increases dramatically. Thus this is probably some OpenGL usage or hardware acceleration issue. (edit: installing the new pyglet 1.1 makes the game run almost as fast as it did with the level drawing commented out; it was a library problem after all)

While the unreliable collision detection is merely an effect of the low framerate, the missing menu is excusable and the incorrect level generation is rare and only a graphical glitch, the lack of shadows and line of sight is painfully obvious. We just didn’t get around to implementing it. It seemed to not be essential for basic gameplay and hence was postponed time and again. Without it, however, our game is missing a key aspect; something that was supposed to make it unique and different.

Even with these defects, I’m amazed by what we have achieved in such a short time. Especially considering that we started from scratch with a programming language half the team was not familiar with. It was a pity we had to stop when the result was not yet what we had envisioned, but that’s the premise of these events: try to get as far as you can before the time is up, then stop and take a look at what you’ve done.

We certainly had a good time and I plan on doing this again next autumn.

Screenshots:

screenshot screenshot screenshot
]]>
http://www.incasoftware.de/~kamm/projects/index.static/2008/04/12/game-in-a-day-pydogs/feed/ 2
dynamic soft shadows in 2D http://www.incasoftware.de/~kamm/projects/index.static/2007/09/08/soft-shadows-2d/ http://www.incasoftware.de/~kamm/projects/index.static/2007/09/08/soft-shadows-2d/#comments Fri, 07 Sep 2007 22:24:40 +0000 Christian http://www.incasoftware.de/~kamm/projects/index.static/2007/09/08/soft-shadows-2d/ This implementation of dynamic shadows with soft edges in 2D using OpenGL was part of a game concept I experimented with. In the end I decided not to go ahead with the game, but as the shadowing itself was pretty fun to do and as the concepts (and possibly the code) can easily be used for other games, I will detail my work here.

I had just finished implementing hard-edged shadows for rectangles when I found a GameDev.net article by Orangy Tang, where a technique for rendering soft shadow edges is described. The article is very thorough and I ended up using most of the ideas described there. Instead of starting from scratch, I will only explain what was done differently.

But first, here’s an animation of the result in action:
Dynamic soft shadows animation

Click for a (2.5 MB) full-size version. The limited colors of the gif animation don’t do it justice, but I hope you can get a good impression of the shadow behaviour. Also notice the neat (and correct) colored lighting.

The main difference between the procedure presented in the article and the approach I chose is using a render to texture operation to accumulate the light. In the article, it is proposed to build lit and unlit areas in the alpha channel and then render the geometry modulated by the alpha value for every light.

The shadowed areas, including the ‘shadow fin’ regions, are essentially calculated in the same way and written to the alpha channel of a texture. Then, the light’s texture, modulated by the new alpha values, is rendered additively to the color channels. This is repeated for every light, until finally the color values at each pixel represent the amount of light of a given color at that location.

Now it is time to render the regular geometry. In contrast to the method from the article, any blend mode can be used. Thus it is fully possible to use the usual modes for transparency and similar. In a final step, the light color values from the texture are multiplied with the scene color values.

The advantages of the original approach are retained. In particular, it is still possible to have any shape of light simply by changing the light’s texture. Additionally, colored lighting works more intuitively and the presence of light and shadow does not affect the regular rendering of the scene at all.

It comes at the cost of requiring a render to texture type operation. On modern graphics chips, however, this feature is fast and well supported using framebuffer objects. Unfortunately, my notebook’s onboard graphics adapter does not provide the necessary extensions and so the downloadable code uses a slower copy of the light data to a texture instead.

For the implementation, I used the D programming language along with small parts of Arc 0.2 for Phobos. As said, the code was taken from a game prototype and as such was written to get things done quickly and not for extensibility or efficiency. Nevertheless, I have cleaned it and tried to add comments where they were missing, so it should be quite understandable.

There are a lot of possible enhancements: Spot lights and using the depth buffer to allow some geometry to be drawn over shadows instead of under (see the article) would be two worthwile additions. Significant improvements of the efficiency of shadow calculations are possible. Calculating shadows only for light blockers that are in the light’s radius, using the framebuffer objects extension, if available, and caching shadows for immobile lights and blockers should all improve performance significantly.

Finally, here are the sources.

]]>
http://www.incasoftware.de/~kamm/projects/index.static/2007/09/08/soft-shadows-2d/feed/ 27