September 29, 2009

Bamf: DevLog 4 — Advanced Lighting

Alright, so now we have lighting! At this point I went back and tweaked the physics more, and started working on enemies that look around for you and pay attention to how lit up you are and other cool stuff like that. But to make this easier to read through I'll skip ahead to where I went back and worked on the lights more.

When I first did the lights, they actually didn't look like the screenshots I show in the last post, with the nice gradual shadow that got darker the farther you got from the light. Instead each one would draw a bright circle, and then a bigger dark circle:

You could control the size of the circles though, and it actually looked alright, and divided the levels clearly into 'dark', 'dim', and 'bright'. But mainly just to see if I could, I instead had each light draw a radial gradient, ending up with the gradual falloff shown in the last post.

Then I went further. See, in these examples, the shadows are very sharp and clear, but in real life, shadows have slightly blurry edges. Sometimes. It's kind of taken for granted that shadows are blurry, but they usually are not. What causes blurry shadows is when last is being cast from an area instead of a single point. The smaller the area the light is coming from, the sharper edged the shadows will be. But when you have a large area, there's a portion of the shadow that's hit by *some* of the light. And that slice gets bigger as you get farther from the light.

In the first example, we're tracing the shadow based on where the center of the light is. We find the angles to the corners of the object (red lines), and draw the edges of the shadow (blue area) based on those angles.

If we take into account the entire light, we get this diagram:

The area between the two lines is where the light is partially blocked, and because it gets wider as you go, the shadow gets blurrier the farther away you go.

There are many ways to recreate this effect when you're drawing in a program. One way is to calculate this area where it should be partially blocked, and draw a gradient between the two lines. I didn't choose this method.

Instead, what I'm going to do is make each light act like a small collection of lights scattered around within a small area. The light from each will each cover a slightly different area, and slightly overlap with the other lights, making soft edges on the shadows.

Here's a comparison of a simple light and a so-called 'area' light:

Not only do the shadows look nice and blurry, the blur hides the jaggy edges really well, making the shadows look more like they were painted in. So I call this a win.

Now for the sun. To get outdoor lighting we don't want to just place a bunch of lights all over the place outside the buildings. The sun casts light from very far away, casting all the shadows in the same direction. So we'll make a new type of light called a directional light, and for this type of light, the edges of the shadows will just always be a given angle, instead of based on where the light is. Throw one of these in the level, tell it to make the shadows all going down and slightly to the right, and you have sunlight.


This directional light also works sort of like an area lights: It's acting like a collection of lights, each casting shadows at a slightly different angle. Even though the sun is very far away, it's also very very big, so it's still technically an area light. The effect is probably not as dramatic as it is here, but I don't know the exact measurements so I'm just eyeballing it and using what looks good. As mentioned before, the blurriness hides the jaggy edges, so it's probably fine for this to be too blurry.

But, real life doesn't have pitch black shadows like this, right?

This is for two reasons, one of which is easy to duplicate. The first reason is light bounces off things, it doesn't just stop. Hold up something white and it will reflect light back into the room. This is time consuming to accurately model in a game. Mainstream 3D games are still not doing it, instead faking it with other methods or calculating it beforehand.

The second reason is when you're outside, light isn't coming only from the sun. The sky actually catches and scatters a lot of light, sending it every which way and generally filling all the shadows with light unless they're totally blocked from the sky. There's a simple 3D rendering technique called ambient occlusion that mimics this. For every point in the scene, it measures how much of the sky is visible from that spot. The less sky it can see, the darker that spot is. You can fake this by simply placing a bunch of directional lights all over the place, all aimed at the center of your scene. I did this for a couple projects in school because real ambient occlusion takes a very long time if you want it to look nice.

So I just have a light that works sort of like an area directional light, except instead of only slightly different angles for each pass, it renders roughly 160 lights, starting from point directly right, and increasing by small amounts each time to cast light down and right, down, down and left, and finally ending up pointing directly left.

The end result of this is, light is coming from every direction except down. Here's an example of this ambient light by itself:


And here's what it looks like added to our scene (without on top, with on the bottom):

Cool, now we've got light streaming in through doorways and windows, and the outside feels very bright and outdoorsy, especially compared to the lighting inside. It also means we only have to place two lights in any level to create outdoor lighting: a directional light and the 'fake' ambient occlusion light.

Next post: Tweaking the controls and physics.

September 28, 2009

Bamf: DevLog 3 — Lighting

Alright, now that we can figure out where shadows would be, we can make lights. 2D games usually do not have lighting calculated by the game; they just have art, which is all hand crafted to look good.

Castlevania: Aria of Sorrow. The blue glow means he's a vampire.

Hand crafted art is good, but it's time consuming and it's hard for the game to figure out how much light is present at a given spot, which we'll need to do later to let the game decide whether enemies can see you or not. Analyzing images to figure out what they are is difficult for a computer. Humans are so good at it that we don't even realize how complex a task it is.

So we're going to take an approach to lighting that's more like how 3D games handle it. We'll just have all our art drawn as if it were brightly lit from every direction, and then place light objects in the level. Anywhere that's not within a certain distance of these lights, or is covered up by a shadow as calculated by our shadow system, will be drawn on the screen very dark. Or more specifically, shadows will be drawn over everything.

Quake 2, the same scene rendered without shadows, and with.  I really could have showed you an example using Bamf screenshots, now that I think about it.

So here's what we have to start with. We have all our black blocks placed around the screen to be the level itself, these are the solid objects. Then a prepainted background image is drawn on the screen. This painting is drawn as if everything were brightly lit and there are very few shadows drawn into it- just enough to show details. Now we want to tell the game we want lights at certain spots, and have it figure out what areas of the screen should be dark, based on that.

Hey, a house. Designed by a man who hated privacy.

To do this, we'll use a similar process as we did for the Line of Sight vision: Draw black shadows over the screen streaming away from each solid object. Except we only want lights to light up a certain radius, and we want more than one light, so shadows have to be able to be erased by other lights.

So we'll change our tactic slightly, and use surfaces. So far we've only been drawing things onto the screen, but you can draw things to your own images and then draw those images to the screen (or to each other, which we'll use in a minute.) Game Maker refers to these extra images as surfaces.

So we make a new image for each light. Start out filling it entirely with black, then draw a white circle centered on where the light is coming from- the light object.

A very realistic light.

Then draw black shadows for any solid objects that are close enough...

It's not a coincidence that it looks like a pie.

And now you have sort of a graph of what's lit up and what's not. In Bamf, here's what the shadow surface looks like for a typical light:

This is also an example of things I have not explained in this post. Find out what for only an extra $59.95.

Once you have one of these surfaces for each light, you can blend them together into one surface. Colored lights will even properly add together to make new colors, because of how Game Maker (and computers in general) record color information:

I could have put the two colored lights closer together to get some bright yellow instead of a slight area of brown, but what would be the fun in that?

And once you have that, you can blend it with your actual game art to darken it:

The man who lives here also hates being able to see what he's doing, I guess.

So what's the benefit of going through all this trouble instead of just painting the level with shadows like this?

First, you can draw the shadows on *top* of the graphics, so the player or enemies that are in dark areas will be covered up by the shadow; they'll be dark.

Second, it's very easy for the game to look at the shadow surface and measure how bright a certain spot is, because now it doesn't have to worry about, for example, whether it's dark because it's a black object, or whether it's actually a dark spot.

Thirdly, it makes it easy to make the game look nice. Even just some blocks on a white background can look spiffy with some good lighting placement:

Not demonstrated in this example: Good lighting placement.

Next post: Advanced lighting.

September 27, 2009

Bamf: DevLog 2 — Platforming & Line of Sight

Alright, so now I know it's going to be a platformer, it needs a platformer engine! These are fairly simple affairs.

This is partially for my family and might be of interest to those unfamiliar with programming so I'll start from the ground up.

Basically you want stuff to happen on the screen, which is a 2D grid. Each space is a pixel, and the area has a finite size. So you have objects, and each object has an X (horizontal) and Y (vertical) coordinate. Then each object just gets drawn to the screen at whatever its coordinates are. In most cases, the upper left corner is 0,0 and it counts up from there as you go right or down.


Then you can do some more complex things, like change the coordinates of an object by a small amount and repeating every split second, to get the illusion of movement (commonly known as 'animation'). You can tie changes to X to whether a button on the keyboard is pressed, and just have a constant addition to Y for gravity.

Now what if you want the character to stop if he hits something? You need to be able to see if two objects are 'colliding'; occupying the same area of the screen. Typically your objects aren't a single point on the grid, they're an area of the grid, so you can't just check their coordinates and see if they match. You need to check every coordinate within the first object's area, and compare them with all the points within the other object's area. It's easiest to do this if you just assume everything is a rectangle, and that's usually sufficient. If two objects have overlapping areas, they're colliding.

So now we can tell whether two objects are colliding. To make floors and walls, we have more objects, which we'll just call 'solids'. Whenever the player collides with one of these solids, it stop moving. But, if you just did that, the character would get stuck and never move again the first time it collided with a solid. So what you do is check for collisions at where the character would be if it moved, and stop movement beforehand.

Anyway, the collision checking and movement I'm doing is a more complex than this, but I'll talk about that later when I go over how I'm tweaking it. It still works essentially how I've described. At this point I've got a playable platformer engine. I can scatter some solids around a room, and run and jump around on them. It took me about half an hour to get to this point-- Hooray Game Maker.

Now I moved on to Line of Sight, because I really had no idea how to do it. I want any area of the screen that's blocked from the character's vision to covered up with black. This way, you won't be able to see through walls or floors as you typically can in a platformer.

My first idea is to cover the whole screen with black, then erase the black from the areas you can see by tracing lines starting at the player and going outward in incremental angles, continuing each line until it hits a solid. To get perfect shapes, I'd have to send a trace out to every pixel on the edge of the screen, covering any possible gap between lines. But, this is far too many lines to draw every 30th of a second. It slows the game down considerably because for every line, it has to check for collision at each of about a hundred or so positions on the grid to find out where it collides. There's a lot of math involved in comparing all the coordinates of every object with the given coordinates to see if they match up, and it costs time.

So I try drawing really wide lines, and only send out about 60 (or so, I don't remember the exact amount). The lines are wide enough that they cover up the gaps between them. But it's very imperfect now. It basically works; it gets across the idea that you're only seeing what the character can see, but it just looks awful, especially in motion, because it fudges so much.


So clearly this needs a different approach entirely. What if, instead of erasing the visible area, we only draw over the invisible area in the first place? For every solid object, trace out basically a shadow based on where the player is, and draw that shape.

You trace a line to each corner of the solid to find the angle (red lines), then draw shapes from the corners, to other coordinates that are far away but along that same angle (blue lines). By doing each pair of opposite corners, you don't even have to worry about figuring out which corners to draw from, as long as all the solids are rectangular. (If you want to be able to build objects out of non-rectangular shapes, that's more complex. So I'm just going into this knowing my levels will be mostly straight lines.)

Now instead of drawing a line for every pixel on the screen, we're drawing a shape (a polygon actually) for each solid object. We could probably do some checks to make sure we're not drawing shadows for the ones that are going to be covered up by other shadows anyway, but's faster just to draw them all and not worry about drawing over the same areas of the screen a bunch of times.

Plus, now it's pixel-perfect instead of having big, noticeable, weird shapes.

And as a bonus, holy crap, now we have all the math and everything already in place to calculate shadows. Time for lighting.

September 25, 2009

Bamf: DevLog 1 — Concept

So I'm making a game, and decided to keep a journal of my progress. Let's say weekly-ish. I've already been working on it for about three weeks, so this first post will cover the core ideas, the next post will cover everything I've got so far, and subsequent posts will be plain log entries.

This is actually a restart of a project I worked on for a few months last year. I ended up losing the source, and now I've started over on it with a few new ideas.

The gimmick of the game is the player can teleport without limit. Now how do you make that fun? The typical method to make a game fun is challenge. Perhaps it also has some intrinsic fun because it's so unique and powerful. But let's assume we want it to be challenging and go from there.

I've chosen to make it 2D, because mice are 2D and they're a great controller for quickly selecting a specific spot. (This also makes the DS and the Wii good choices for a platform, but it's easier to develop for PC if you're broke.) I've also chosen to make it a platformer instead of top-down or isometric to have vertical travel be more important. If we make teleporting preserve your velocity, you can teleport to midair spots but you'll fall, potentially reaching a fatal collision speed. This limits teleporting in a natural way; it's easier to move around horizontally than vertically and you have to worry more and finding spots to stand on.

Let's talk about other limits. Typical ways to limit teleporting are range and recovery time. There are many examples of a very short range teleport (a 'blink'), on the order of a few meters. And almost universally you're limited to a certain number of teleports, or teleport-per-unit-of-time. City of Heroes, for example, has a very long startup time. When you click to teleport, it takes a few seconds of your character posing before you actually teleport, and then you can't move for a few moments afterward. This makes it worthless in any fast paced situation, relegating it to travel over long distances. Because it is very long range, it's the best travel option. You can get across any zone in the game in just a few hops with an upgraded teleport.

But what if we want really fast teleporting? This is probably extremely powerful. Even if you limit the range, the character can move around large distances very quickly, if there are places to stand along the way. The traditional platformer goal of, "get to the end of this obstacle course," becomes trivial. Is there some other goal that remains challenging?

What are some other goals in video games besides "get to the end of this area"? A few generalized things come to mind: Defeat opponent(s), collect things. Defeating opponents could be a goal, or *avoiding* defeat by them could be the goal, while you work on other goals (survive a certain amount of time, collect things.)

With these other goals in mind, it's still possible to make "get to this spot" a goal, you just have to keep in mind that typical platformer level design becomes very easy with a teleport. A teleporter is going to be more challenged by things with lots of vertical travel, dangerous drops, and maybe mazes and jumps that only become safe by teleport part of the way.

Anyway, here's what's I've got so far: You have large, intricate levels. Scattered around the levels are objectives, and enemies. It's possible to avoid enemies, and it's very difficult to actually fight them (but your teleport gives you an advantage). You have to go around the level and collect things (possibly NPCs), and getting around the level will switch between slowly sneaking around when guards are present, or running, jumping and performing acrobatics that Feel Good when there is no danger. So the levels will have lots of fun, crisscrossing paths to move around the level easily once you've figured out where to go. Additionally it will have situations and puzzles which push the player's understanding of and skill with the teleport.

So there are a couple different aspects: Stealth, parkour, combat, exploration and how teleporting affects all of them.

Time to build an engine! I've prototyped this game before, about a year ago, and got a pretty good idea of how I want the controls and physics to feel, but I lost that source, so I'm starting over now with a better idea of what I want it to do. Next post: Basics of the engine, and line of sight.

September 13, 2009

Failure in Games

Why do gamers want the possibility of failure when they play a game?

I've been talking about this a lot with friends over the past few days and here's what I've come up with:

In a game, there are rewards. The win screen, the next level, new abilities, the hopefully engaging story, whatever. The player wants that reward.

It's pretty easy to get that reward by other means. Cheat, download a savegame with everything unlocked, look up the ending, watch someone else play it, or any number of methods, depending on which part you want.

Why don't people do this if they just want the reward? Well, many people do. Especially as games become more complex, presenting stories and ideas that appeal to a wide variety of people. Maybe the story stands on its own; for example watching a Let's Play of the Metal Gear Solid series could conceivably be interesting (if very long winded). Maybe the joy of running around with a fully powered up character surpasses any joy the mediocre story manages to evoke.

But, there's a second reward that persuades people to play the game: the challenge. More specifically, the feeling of triumph when you rise to that challenge. Games have a requirement from the player before the player is allowed the rewards. Figure out how to run, jump, avoid enemies, defeat bosses, complete objectives. Do these with the right timing, in the right situations. Essentially it's a puzzle. What sequence of actions results in success? It's not just that the player wants the reward, it's that she wants to work for it.

On top of this, many games add punishments. The most common punishment is the practice of sending the player back if she fails. In other words, she's actually farther from success than she was at the moment she failed.

This can go between various extremes. Nethack, for example, wipes all your progress. Period. The longer you go, the more progress you're going to lose if you die. Half Life 2 only sets you back a few minutes, due to frequent automatic checkpoints. You're never risking more than a few minutes of progress. Typically you're sent back to the beginning of "the level", which in this context is just a means of noting where you'll be sent back to if you fail.

The reason games do this is to give the player the excitement of risk. It creates tension when she comes close to failure, because failing means she's going to lose some of the effort she spent. She's actually gambling some of her progress to get more progress. She says, "I bet X amount of progress that I can complete this next section." She gets a rush of relief when she succeeds, because the gamble paid off.

But she also gets frustration when the gamble fails, or the challenge is too great. There's a balance between making it so easy it's boring, and so hard that it becomes frustrating. This balance has to do with a lot of factors and is a whole post by itself. Any designer can make a difficult game, but can they make a game where working for the rewards is fun?

One way to reduce potential frustration is to minimize punishments. Remove them entirely; then it's back to just being a puzzle. Figure out and execute the correct sequence of moves, and the player wins. 

Braid is a good example, failing doesn't actually cost anything, it only means you're not moving closer to winning. 

This doesn't make Braid easy, you still have to work for the rewards, but it does make it pretty mellow. You're never losing progress; at worst you're just not gaining any. It takes away the frustration of failure by making failure not cost anything. But you also lose the excitement of risk, because you're never risking anything.

Does this make Braid (or any other game with very low cost failure) a game not worth playing?

It depends on whether you want that excitement of risk.