Guest piece: In game development, it’s all about details

Guest piece: In game development, it’s all about details

Olaf Morelewsk is an architect by trade who spent years as an art director in the advertising industry. Olaf loved the creativity of the game industry and, seven months ago, founded a one-man game studio in Warsaw, Poland.

Olaf is responsible for all of the coding, graphics, sound, and music for his games. Olaf’s latest release, OmNomster, was recognized as a Corona App of the Week in September 2013. In today’s guest piece, Olaf writes about his approach to the visual effects in OmNomster.


Olaf Morelewsk headshotFor those of you who have played OmNomster, it’s likely that you haven’t noticed some of the small, subtle details that I’ve added to the game. That’s fine, since these effects shouldn’t be exaggerated to overwhelm the game. You actually shouldn’t notice them consciously, but they should give you an overall impression that the scene is real and alive. It’s similar to a bass in a jazz band — most people don’t pay attention to it, but everyone notices that something is missing when it is silent during parts of a song. Details in game design work the same way: while you may not notice them right away, you’ll miss them when they’re lacking.

In this article I’d like to share my approach to creating visual effects in OmNomster.

Depth and Dynamic Lights

First, let’s talk about depth. Depth perception is based mainly on a couple of aspects including obscuring objects, our vision of light, shadows and focus. When I built OmNomster, Corona’s Graphics 2.0 engine was not yet live, so I had to figure out other solutions for features such as blur, shadows, anda 2.5D effects.

For the lighting and shadows, I picked a light destination point (let’s call it an LD point) that I decided to be the end of my light axis. The lower-right area of the screen seemed logical to me, but it could be any point you desire. Next – and this is the tricky part – I made the source of light “dynamic.” So, it’s not a static source of light like the sun or a lamp, but more like several individual torches that actually follow the movement of each object. When the particular object is further from the LD point, the cast shadow is accordingly further from the object than when the object is closer to the point. This makes the shadows look more natural, although they don’t actually behave perfectly natural. I experimented with the static light source as well, but for my game, the dynamic light source approach worked much better and seemed more lively.

Here’s a simple formula I came up with, placed in an “enterFrame” Runtime listener:

Here are some object position examples:

Shadows Scheme screenshot

Obviously, the formula can be modified with a multiplier variable to increase or decrease the distance between the object and the shadow. This is just one way to achieve the 2.5D shadow effect. While it doesn’t mimic the “natural” static source of light, it does provide more depth.

Tiny Details Matter

When I design game elements, I try to fill them with “life.” This means that the elements should behave as if they could exist in reality. In OmNomster, the monster I created is not only breathing (his body is constantly pulsing via scaling effects) but he also reacts to force when you push him. When he’s tired, he breathes faster and the scale pulsing method runs faster as well.

Another small detail I implemented is a cartoon stretch and squeeze effect. When OmNomster hits the wall, he squeezes (scales in one axis only) just a little before he bounces back and inflates to his regular round shape. He also scales up a little when he catches a piece of trash. Since the trash items fly above him and they cast shadows on him, he has to approach the screen surface to reach them. This results in a little scale-up effect that mimics a closer distance. In addition, there are particles that spice up all the scene, for example, “saliva splashes” when the monster eats a piece of trash.

Elsewhere in the scene, there are some “rock” particle shapes that fall off the walls when OmNomster hits them. Additionally, on higher caliber devices, a subtle smoke emerges after every hit. I also filled the background of the game with lots of tiny dust particles to give an impression of space in OmNomster’s room. Finally, there’s a constantly “vignette” effect on the screen corners — a very subtle movement which adds more life to the scene.

And Gameplay Too!

All this being said, the gameplay remains the most important part of the game, so good visuals without addictive gameplay won’t cut it in the competitive game market. Assuming you have great gameplay already, I encourage you to spend some time on implementing stellar visual details as well — they may not seem as crucial at a glance, but the overall effect will matter to the player and speak volumes toward the overall quality of the game.

inna
6 Comments
  • Mikhail
    Posted at 03:11h, 11 October

    Hi Inna!

    Great post, but I have only question about the lighting formula, because:

    shadow.x = lightDestinationPoint.x + (object.x – lightDestinationPoint.x)

    is equal to:

    shadow.x = object.x

    And this formula doesn’t work for the purpose. Please answer.

    Thank you,
    Mikhail

  • ChunkyApps
    Posted at 08:11h, 11 October

    Nice post… I downloaded your game and it’s great! The attention to detail is obvious and really pushes it to the next level. Good luck with it!

  • Olaf
    Posted at 12:53h, 11 October

    @Mikhail,

    Good point, that seems like a basic math mistake of mine 🙂
    But actually I tried to simplify the formula for the tutorial and apparently I lost some important parameters. Here’s the original code so you could follow it:

    monsterShadow.x = _W*0.59 + (monsterBody.x – _W*0.6)*0.5,
    monsterShadow.y = _H*0.59 + (monsterBody.y – _H*0.6)*0.5

    Where _W, _H are width and height of the screen. So I guess the thing is that I forgot to mention the 0.5 multiplier of the second part that makes an offset of the shadow from the body.
    So sorry for that! My bad 🙂 I’ll ask Inna to correct the formula in the article

    Thanks,

    • Mikhail
      Posted at 02:15h, 14 October

      Thank you Olaf!

      Now formula works fine, thank for your support! 😉

  • Olaf
    Posted at 12:58h, 11 October

    @ChunkyApps, thanks a lot!

    • Inna Treyger
      Posted at 15:47h, 11 October

      Hi all – The code snippet has been updated above.

      Thanks,
      Inna