Slow Rush Games logo,
    depicting an apprehensive-looking snail rushing forward

Slow Rush Games

◂  Socketing Signs
News index

Light and Shadows

Contents

Why, hello there! Bet you didn't see me standing here, all cloaked in shadow.

What's that? You want a flashlight? To see me better?

Wait, you want to know the whole story behind the flashlights? Well then, gather round.

Starting point

Almost a year ago to the day, (wow time flies) I added fancy lighting.

Over the next 9 months I rewrote my rendering entirely, and mildly improved the lighting, ending up at something like this:

Lighting 3 months ago, for levels set outside.

I also had the ability to set the light levels a bit lower when a level was set underground:

Lighting 3 months ago, for levels set underground.

But as time wore on, I saw the imperfections more and more:

Something had to be done.

Rewriting Lighting

So, over the last 3 months, I, err, I rewrote the rendering again, and then I (with a bit of help1) redid the lighting system entirely too.

Lighting, rewritten. It's the same, but better! Notice each bit of terrain casts a shadow below itself now, as well as inside itself.
(You can spot other new things, like more explosion and trail effects, and terrain pieces fall down now. But focus on the lighting!)

Much of game lighting boils down to maths and performance optimization, but I have a strict No Maths, No Code rule here.

So instead, let's zoom in on some of the game design problems. I had 4 goals:

Notice these conflict with each other! I could make everything well-lit, but then there are no secrets and underground areas feel the same as above-ground.

Or I could make a traditional "fog of war" hide unexplored areas, but that would obscure cool chain reactions!

Supporting Underground Areas

What makes something feel underground?

  1. It's darker (no sun underground!)
  2. The background is closer to you

I came up with a system whereby I can paint a "middleground"; any pixel painted as middleground doesn't emit sunlight:2

Painting middleground. Normally this would be done in the level editor and (when I revisit it) during procedural level generation.
I have support for painting arbitrary colours so that an eventual artist can draw nice things in future, like prettier yellow smiley faces.

The blocking of light makes nice dark areas, and also allows neat rays of sunshine to come in "from outside".

Except.. it's maybe a little too dark?

Let There Be Light

Let's give our player a flashlight, which helps a bit:

A flashlight, which automatically turns on when the player is covered by the middleground.

You can see the flashlight only lights the area directly in front of you.

Turning on bounce lighting3 (halfway through the video above) improves things a bit, but it's still kinda hard to see, ya know?

Especially if you're on a ladder.

I fixed it by putting a light on the player:4

Player with a light on their character, so that the area behind them is still lit up.

But there was one problem left: any area you weren't shining a light onto was still too dark.

That could be fun sometimes, but in general that made it too hard to use your grappling hook.5

Hey, you know what? If this seems cool, you should...

Wishlist Signs of Danger on Steam!

Anti-Fog of War

I was mulling over adding a fog of war,6 when it hit me: what if I added a reverse fog of war?

I could artificially boost the lighting, but only for explored areas of the level!

That way I could have secrets, keep the game readable, and let players see chain reactions (which usually emit light), while also giving cues to players about already explored areas - a rare quadruple win:

The Anti-Fog of War in action: once a player visits an area, that area is revealed - so it's easy to fight and navigate around underground.

Of course, it's all tunable per level.

Here's that original dark level from above, redone:

Dark level, retuned. Notice that (in between the explosions) the dark areas stay lit up once the player has explored them.

I'm pretty happy with this approach, and it's quite flexible too.

For example, here's an emulation of a Real Time Strategy-style fog of war, as suggested by @RaR in the Discord Slow Rush Discord 7

RTS fog of war: you can see terrain you've explored, but not enemies (unless there's a light source: here I made enemies glow slightly red).
This video is zoomed out just to make the effect a bit clearer.

Lighting isn't done! For example, all of the background (and middleground) is lit evenly, even though you wouldn't expect mountains (or the moons) in the background to be lit much at all.

But I figured it was well past time for a progress update, and a...

Very Updated Playable Web Build!!!‎

It has been 3 months (wow, also whoops) so many things have changed since last time - most notably there's some approximation of a Risk of Rain-style core game loop now.

But I won't spoil everything - have a play and Discord give me feedback please.

Tip: press Esc to see controls, and you can now rebind them in the Settings menu.

Press F1 for help, including to see keyboard/mouse controls. By playing you agree to our Privacy Policy and Terms of Service.

1

After being nerd-sniped by @oooks from Meatbat in the Discord Slow Rush Discord (psst, join us!), I experimented with upgrading my lighting system to EntropyLost's implementation of Holographic Radiance Cascades.

I got a prototype working and then @xzil mentioned that he was working on the same thing based on yazaraai's HRC impl for his own game. We started swapping code & techniques, and eventually joined forces to work on his prototype since he had cooler stuff overall.

In particular, the prototyping of light bouncing around corners and the sun causing shadows below terrain came from him, and I just ported the ideas & maths into my own implementation - thanks for the collaboration & help @xzil!

2

You might be thinking: wait a second, doesn't sunlight only come from the sun, not from arbitrary open pixels that might be positioned under terrain?

And you'd be right: that was actually what I had to start with, but it cast everything above the top terrain layer into shadow too strongly, and didn't play nice with the camera moving down (the blocking terrain would disappear and suddenly let in new light).

This approach is a decent tradeoff - maybe I'll add in "correct" sun lighting again in future, after I have a better solution for off-screen terrain.

3

In real life, light that hits one surface bounces off and hits another, which prevents areas around corners from becoming completely dark.

In games, it's usually very computationally expensive, so most games don't simulate it - but this game does!

The way it works under the hood is that pixels adjacent to terrain have their previous lighting result fed back in, so they become dimmer light-emitting pixels themselves.

Credit to @xzil from the Discord Slow Rush Discord for the original bounce prototyping!

4

It was harder than it sounds: if you just put a circular point light on the player, its radius is very obvious. Make the radius smaller than the player, and it can flicker at lower graphics settings. I reworked things so that every pixel of the character sprite emits even light, but then if the light intensity is too high, the player glows! So I use low intensity lights together with a hack that ray-traces a minimum-lighting circular area around the player.

5

Grappling hook is a work in progress - try it out on the playable web build below with Left Shift and let me know what you think!

6

A black fog drawn over unexplored areas of the map, sometimes combined with a light grey overlay that covers enemies.

Popular in real time strategy games, like Total Annihilation - and if you don't know that game, by god you gotta try it (better 30-odd years late than never at all!).

7

Or at least it's what I thought they were suggesting - it later turned out they were suggesting a bullet that reveals the fog of war, which is also a neat idea :)

◂  Socketing Signs
News index