Okay, this series has fallen way behind. I basically spent an entire week writing about one day of work, so to get caught up I need to cover a week of work in one day. Let’s get started.
But before we begin: IGNORE THE SILHOUETTE GUY HE IS PLACEHOLDER ART. ANYONE CAUGHT CRITIQUING PLACEHOLDER ART WILL BE BEATEN WITH A 1987 VINTAGE MONOCHROME MONITOR. THANK YOU.
Day / Night Cycle
The sky has become significantly more complicated since I wrote about it back in part six.
We still have the original cone, which is used to create the fade. Then we have a canopy that I use for the star texture. Imagine you and a friend have a bedsheet by the corners, and you quickly lower it to the floor. The corners are flat, but there is still a bit of air trapped in the middle. That’s the shape of my sky, which has a star texture painted onto it. This shape is sub-optimal, because you can see the foreshortening on the stars. In the distance, they are tiny dots. Overhead, they are big blurry messy dots. In between, you’re looking at them at an angle and they end up looking disk-shaped. On the horizon they are numerous and tiny. Overhead they are large and sparse. It still looks nice, but it could look better.
I seriously considered using a scattering of square panels floating in the sky, as Michael Goodfellow discussed way back in part 4 of his project. His is a superior method, since none of the stars end up being stretched out.
As it gets dark, this star canopy gradually fades in. There is a huge billboard on the western and eastern side of the sky. At sunrise / sunset, the appropriate billboard fades in. The texture on the billboard is just a big fuzzy blob of light – bright in the center, dark at the edges. I render it so that half of the billboard falls below the horizon. In the morning it’s tinted yellow, in the evening it ends up being more red. It’s laughably simple from a simulation point of view, but it sells the sunset / sunrise idea nicely.
There are two aspects to the sun itself: Where the sun appears in the sky, and where the light is actually coming from. See, when the sun is overhead the world looks very boring. There’s no shading to the world in the middle of the day and so everything looks kind of flat. That’s fine for a short period of time, but in a twenty-minute day/night cycle I don’t want five whole minutes of dull lighting. (Yes, shadows would help, you relentlessly demanding taskmasters. One thing at a time.) So I have the sun move overhead at a steady pace, while the light origin stops at the 45 degree position and lingers there all morning. (Since the sun is now overhead, it’s very, very hard to get both the sun and the landscape into view at the same time, so nobody is going to notice this discrepancy.) After midday the light origin hurries across the sky to catch up with the sun.
At sun rise / set, I have to pull this trick again. Once the sun touches the horizon, the lighting would normally come in perfectly horizontal. As it lowers, the light would actually come up from below. This looks really, really bad, and would actually wreck most shadowing systems. So what I do is have the light source stop about ten degrees above the horizon and let the sun move away on its own. The light goes from yellow / red to pale blue. Once the sun itself is gone, the light sneaks back to the eastern side of the sky, to be ready for when the sun appears the next morning.
No, I don’t have a moon yet.
I finally break down and add some shaders to my program, taking me from 1998-level technology to 2004-level technology. Now I can do all of these crazy per-frame calculations to the world. First up, I curve the points away as they near the horizon, making it appear as if we were on a spherical planet.
(This is a bit of an optical illusion. I’m not 200 meters tall, I’m just flying way up in the air.)
Now I don’t need some fancy-pants system of fading in blocks of terrain. (It’s pretty hard to sneak something that huge into view, no matter how you handle it.) The new terrains will just appear over the horizon. We will still have pop-in problems with things like mountains, but screw that. You can’t make everything perfect and if you try you’ll go broke before you’re ready for alpha testing. The pop-in isn’t that bad, and it’s rare. It’s trivial compared to the pop-in you see in Minecraft (Donk! Suddenly there is a mountain!) and nobody complains that the Minecraft pop-in is this immersion-shattering annoyance. Artistic myopia can kill a budget faster than anything else. (Not that I have a budget.) My pop-in should be less intrusive because the pieces it drops in are smaller, and the draw distance is further. So the things that are popping in are very small, from the player’s perspective.
Speaking of pop-in, way back in week 3 you could see obvious pop-in when blocks of grass would appear. These were very close, filled a lot of the player’s view, and so looked bad. (The fact that they were great big squares didn’t help.) So I add a vertex shader to make grass fade in gradually.
I take the grass system and make another similar system for undergrowth.
As others have predicted, this makes an immense difference. The world feels much richer and more varied. The undergrowth actually shares the same texture as the grass, so I can draw all of them in a single pass. Like this:
The first row is flowers. The second is grass. The last row is undergrowth. Again, I’m not much of a pixel artist, but I did what I could. I experimented with the bushes a bit, seeing what looked good and what didn’t. Amazingly, bush #3 – which to my eye looks the best – doesn’t look significantly better than the others in-game. Bush #4, which looks stupid and horrible on the texture, doesn’t look half bad within the game. Bush #1 is actually the best of the bunch.
It takes a great deal of effort to pry myself away from this. I could blow two days fussing with pixel art and texture maps and figuring out why some things look better than others, but I’m on a push to hammer out the technology. For now, this is good enough and I can see that it works.
What else can we do with vertex shaders? Hm. You know, let’s try making the trees blow in the wind. If you remember, tree textures look like this:
I can isolate any vertex that uses texture values from inside of that second panel. I’ll check it’s distance from the center of that panel. The further away it is, the more it moves. I apply a rolling sine wave over the whole world and use it to push the points around. The result?
Uh. Yeah. I guess you can’t see those moving in the screenshot. Well too bad. I don’t have time to make a video of it, but take my unbiased word for it: This looks awesome. You are totally missing out by not being able to see it in action. Really. You poor thing.
I try the same trick on grass, and it is also awesome.
End of Week 7
We’re getting near the end now. I’m planning on finishing up as much of the technology as I can in the next week, and I’ll do another video for the wrap-up. At that point I’ll have the core technology done, and I’ll be in a position to decide what I want to do with my time.
While using this to make a game would be nice, the important thing has been to prove that procedural development is a woefully under-developed area of study. Yes, there’s a procedural game now and again every few years, but that’s less than 1% of all games. We haven’t even mapped out all of the things that are possible, much less harvested all of the low-hanging fruit.
The point I want to make is that procedural techniques can allow one guy to accomplish in two months what a large team can accomplish in half a year. Hopefully I’ve made my case. We’ll see once the video is out.
Skyrim Thieves Guild
The Thieves Guild quest in Skyrim is a vortex of disjointed plot-holes, contrivances, and nonsense.
Dead or Alive 5 Last Round
I'm not surprised a fighting game has an absurd story. I just can't figure out why they bothered with the story at all.
C++ is a wonderful language for making horrible code.
The No Politics Rule
Here are 6 reasons why I forbid political discussions on this site. #4 will amaze you. Or not.
Starcraft 2: Rush Analysis
I write a program to simulate different strategies in Starcraft 2, to see how they compare.