Tracks

So the next major hurdle was the tracks. When I made the first set of track pieces, I had little idea of where I was going with it, both stylistically, and technically. With the second track set, I nailed down what I wanted the first world’s tracks to look like, but it left much to be desired in terms of performance. Where I had gone wrong, primarily, was having separate materials for different parts of each piece: The concrete bits had a concrete material, the metal bits had a metal material, etc. While that makes total sense, it’s far more efficient for the engine if you shove all of that into a single material, and have different zones on the texture maps for each different sub-material. That way, it can batch all of that in a single draw call, instead of drawing each material separately. In fact, it cut my draw calls by 6 to 8-fold. Unfortunately, that meant the end result was effectively a brand new track set, even though it looked the same as the last, and therefore I had to re-create every single level I had made prior to then, hence the reason I hadn’t made many in the first place. I knew eventually I had to replace them.

But that’s not the only optimization I did. I also wrote a script that merges the meshes of each track upon level load. So, before the merge, it’s set up as a hierarchy. The rails are children of the bumpers, and the bumpers are children of the road piece. That means that every time I made a change to the transform of the road piece or its parent, (I.E., moved or rotated anything, which is the entire point of the game) that change had to propagate up to 6 more times, which, needless to say, created an unnecessary bottleneck.

So now it’s as efficient as I can think of how to make it presently, without sacrificing the quality of the physics.

First up: environment

Wall of text incoming.

Holy crap. It took a long time but I’m done with it. So to recap, I had the original background, (the one in the trailer) totally sucked, both stylistically and functionally, so I determined I needed to replace it, but I knew it would take a while, so I made a temporary one, which was in the build at Game Wars. it was mostly functional, but utterly bland, and had entirely too much contrast, to boot.

What I ended up doing was this: In maya, I made about 20 buildings in 3 parts each: A base, a ‘floor’ and a top. I also made 2 special buildings that stand out from the others and aren’t at all copied, particularly, a government-type building and a clock tower. (in-game, the time on that clock is accurate to system time. subtle, but totally awesome) While I was doing that, I also wrote a mel script to take those buildings, and some road pieces and randomly generate from that a city, which I won’t delve into because it was actually a lengthy script. I actually had to generate it in 17 zones because not only was my script inefficient, my buildings prioritized fidelity over performance, given their end-use. Even had they been, though, the total area was about 200×200, (1 square being 1 building, road, or part of a multi-cell building) and 40,000-ish buildings is still a lot of buildings. So once I had the city, I needed to generate a cube map from that, so I rendered out the whole thing one piece at a time, so I could composite them later. Each piece needed multiple passes. Altogether there was about 150 renders that went into the final composite.

Then in Photoshop, I combined and composited all of those renders with a photographic sky, a panorama of the rocky mountains that I took from a hill close to home, and a public domain panorama of New York that I found. Most of the work there was in color correcting everything together and in masking by hand all of the lights in the windows. After all that was done, I could then export it as a cube map to Unity.

Once in Unity, I had to set it up all of the dynamic stuff. Separate from all the other renders, I had rendered a couple images of just a white cube, using the same lighting as the others. This allowed me to easily set up lighting that didn’t match, but closely resembled the background. I couldn’t entirely match it because I’m limited, in Unity, to a single directional light and an ambient term, for performance reasons, but it’s close. Then there’s the clock. Since I have the files that were rendered, I could determine precisely the position of the center of the clock relative to the camera. Since that vector is still valid post-render, I could simply make a little clock out of a couple of quads and a particle material, and place it there, and it’d appear to be on the clock.
After that, there’s the ocean. The ocean itself is just a quad with a pseudo-reflective material on it, then I took an animate tiled texture script, (just increments the offset of the texture by some vector every so often) re-tooled it to work with any given texture property, and applied it to the bump property, to simulate waves. Back when I exported the cube map, (as 6 separate .png files) I gave it an alpha, which doesn’t matter as far as the actual sky-box material is concerned, but it allowed me to make a cube that sits in front of the ocean and acts as a mask for it. A pretty neat, if totally ghetto solution.
Then I just needed to optimize the rain I had in the original environment, and I was done.

A quick update before a barrage of more

So I haven’t posted in a while. A lot of stuff has happened since then. I’ll split the progress into `smaller` dev-blog-type posts. Otherwise, though we demoed at the Indie game night this past weekend, which was great. You can read others’ write up of that night here and here. If you don’t know, Utah Indie Games is a community of local independent developers, and meet up about every other month or so.

Next up, we’re going to Salt Lake Comic Con! we’ll be there all 3 days. (September 4 – 6) Be sure to check us out there. We’ll be in the Utah Games Guild booth, along with a bunch of other local devs. We’ve got a bunch more stuff in the works to talk about in the future, but more on that later.

Friction, intros, rumble, and backgrounds, oh my

I’ve been working a lot, lately, trying to get everything ready to go for Game Wars. We’ve fixed many of the UI bugs. I added my own class to take handle the balls friction in the game, because Unity’s friction wasn’t satisfactory. Either the ball would slip and slide everywhere, or there would be no conservation of momentum around a turn at all. I tried a number of different solutions, some more accurate than others. What I settled on was completely separating friction from torque. Normally, you would apply friction at the point of contact, but here, I applied it on the center of the object, based on the “best” contact, then applied torque to make the ball roll based off the relative velocity. So now, regardless of how slippery it is, it actually can never slide.

I changed the level intro system quite a bit. It used to be, the camera just spun around the ball and zoomed in to it’s final position, which took about a second and a half. Some people at the Utah Indie Game Night last month suggested that I use the intro to somehow hint at where the player was supposed to go. What I tried first was setting up a series of markers, then interpolating between their positions and rotations. That didn’t work. It wasn’t at all smooth, and Quaternions are weird. Despite the fact that I was interpolating between two correct rotations, it would still sometimes do a weird flip to get there. Second thing I tried was setting up animation curves with those same values. That solved the smoothness issue, but not the flipping one, also it felt really arbitrary, slow, and really stupid. So what I ended up doing is placing the camera’s handle (I always have the camera parented to an empty object, essentially giving me a manipulable pivot I can rotate around and do stuff with) at the center of the level, placing the camera well outside the level, and just slowly spinning the camera around it, until the user presses a button. This allows the player to study the level for as long as he/she would like, it doesn’t feel slow or dumb, and the player can cancel it at any time, so it’s not annoying, and as an added bonus, it doesn’t take any per-level set up time.

I also tried adding rumble. A little while ago, I was showing one of the old builds to a friend, because it had the prototype levels in it, which were way too bloody hard, and that build had rumble in it, and I had forgotten how much I liked having it in the game. However, I had to update Unity a while back in order to get rid of some random crash, and apparently sometime between that update and the one I was running previously, plugins became a Unity pro-only feature. To get rumble into unity, you have to use a plugin, found at http://speps.fr/xinputdotnet. But apparently, you can’t do that with unity free now. Hopefully they totally re-vamp unity’s input class, then. I guess that gets put in the “maybe this is something we can do eventually” bucket.

Lastly, I’ve been working on a new background for the first world. It’s a city. I’ve found a backdrop that I can use, It took me a good while to actually make it a 360 degree panorama, but it should work. I’ve been having some trouble, however, doing the foreground… of the background. Cities are hard to make. It doesn’t look like I’ll be able to finish it before the 25th though. But, I do have an idea for something I can replace it with in the meantime that shouldn’t look too bad, and should address the disorientation issue.

The competition

So Grow Utah Ventures announced all but 2 of the finalists for the Game Wars competition here.
I went ahead and tried to tracked them down. Here’s what I found:

SportStocks.com by Adam Snow
SportStocks.com
facebook.com/SportStocks

Vitality Wins by Maria Richards
VitalityWins.com
facebook.com/VitalityWins

Halfling Wars by Chondrostrike LLC
HalflingWars.com
Halfling Wars Kickstarter

Magnetic By Nature by Tripleslash Studios
tripleslashstudios.com
facebook.com/TripleslashStudios
kickstarter.com/projects/tripleslash/magnetic-by-nature

Momentum by Kelly Harper
ProjectileEntertainment.com
https://www.facebook.com/MomentumGame

Zombie Hunter by Ender Labs
EnderLabs.com
facebook.com/EnderLabs

phew, that was alot of links.

The retroactive post

So at the end of last month, we took our game to the Utah Indie game night, which, this time was hosted at UVU. We got a lot of good feedback. The most common critique was the camera. (The second most common was the difficulty ramp) People were getting unnecessarily disoriented and obstructed and such.

Since then, I’ve been doing quite a bit of work on those issues. First of all, I’ve put restrictions on the camera so the horizon is always in view, which is the biggest visual cue as to where exactly “down” is. I think that, combined with re-doing the world 1 background should make that a whole lot clearer.

Regarding obstructions, I wasn’t quite sure what to do about it because, as I had explained to other attendees, the shaders I used didn’t support transparency. I can’t believe it didn’t occur to me sooner, but the obvious solution is to change the material… duh.  So the end algorithm is something like this: We have a camera, a ball, a list of track materials and a corresponding list of transparent track materials. first, do 3 raycasts from the camera to different parts of the ball (we want a certain amount of overlap before transparency occurs), then filter all the targets hit to only keep the common hits, then dump any hits that don’t use certain materials. (mostly to filter out the rails.. they caused flashing if the camera just went past them for a moment) change the material on any objects that were hit this frame, but not last frame, then add to a list of objects that haven’t been hit, but are still transparent. Then decrease the alpha on the appropriate objects, increase it on the others, swap fully faded in materials with the originals, then update the lists, and rinse and repeat.

Of course it took a while to get there and there were certainly some weird things along the way, such as the fact that querying Renderer.sharedMaterials[] returns a copy of the array, not the original. Needless to say, that caused some head-scratchin’ problems.