Thursday, December 2, 2010

Not So Unreal After All

Visually, Monkey Morris is minimalistic and uses very light, desaturated tones. There are a few reasons behind the decision approach the design in this way and I'll give a run down of them.
One contributing factor was that I had a desire to create a game using the Unreal engine that didn't look like it was using said engine. Unity was very nearly used for Monkey Morris, however it would have meant a lot of heavy lifting in terms of coding the vehicle (it's arguable that more time was spent extending and getting Unreal Script to work for me, but nevermind... I'm here now), and other aspects of the game.
Two notable things within Unreal powered games are heavy use of normal mapping and lots of shiny objects. And lens flares. And space marines of variations thereof. I also wanted to avoid falling into the trap of cel-shading, so after taking a few pages from the books of hand-drawn animation and watercolour painting Monkey Morris ended up with a bright, colourful character in the car itself, but toned down background detail to emphasise the watercolour look.
I've had a few comments that it doesn't look like an Unreal game, so I guess I win!

I will make a game that looks like this.
A second factor that played a part my visual inspiration was in a development blog post for Jonathon Blow's upcoming game, The Witness.
In the post it talked about how a textured mesh can often less visually interesting than viewing just the geometry with lighting. After taking a cue from this, and agreeing with it to a certain degree, (I'll often look at a map using an in-game lighting only mode and be stunned by it's simplistic beauty. If the lighting is decent anyway.), I began to experiment by building a few houses using simple, chunky geometry and textures that consisted of little more than baked ambient occlusion. The method worked fantastically.

Another reason for using this method was partly instigated by the time constraints placed on the project.  Working in this way enabled me to save a lot of time in texturing and devote more time into modelling, gameplay and placing the assets themselves, which has been invaluable.
To compliment the time-saving texturing, I also devised a method to rapidly produce colour variation in the buildings utilising instanced materials.  This is the shader set-up for the master material used by all of the buildings:
Building Shader Setup, click to enlarge
Building Shader Parameters

Basically, it uses a set of one-bit alpha images to mask out different areas of the UV map, then some simple math to combine them into the final texture.  Each of the colours is adjustable within the material instance.  The mask used for the windows is conveniently used as a mask for the specular channel as well.
The ambient occlusion texture is also set up as a parameter, so that can be altered depending on the mesh the material is used for.

This system of colour altering was initially developed for the Morris, and is further used by a few other gameplay assets, which I'll go into in a separate post that tackles the various scripting tasks and issues of Monkey Morris.

Eight o'Clock... Day One!

No Cartographers Necessary.
The initial plan to build the track out of modular assets. After playing around with this method, creating a few basic parts and piecing them together I quickly came to the conclusion that building the track this way wouldn't really fit my vision of a twisty, turny countryside road. There would have been an awful lot of individual parts, largely negating the use of modular assets at all.
Besides that, I was only going to producing one track, therefore there wasn't really a need to be able to speed up the building process of building additional tracks.

With that in mind, the decision to use terrain as a base was made.

In order to ensure that the track fit the brief in terms of the average total gameplay time of three minutes, a quick draught terrain was created and the track simply painted on. The length of the track was adjusted until the time for each lap came was close to one minute.  With this accomplished the track was then tweaked to become more interesting to drive around.

Unfortunately at this time I didn't actually have a car to test with, since the Morris was non-functional and the Scorpion was broken, possibly beyond repair (or at the very least a lot of time-consuming fixing). This is where the less-than-ideal Manta stepped up to the challenge of testing. So “driving” at this point of development was actually “hovering”.

The track was now the right size and shape, but was yet to have any depth. The first terrain features to make it in were those planned in the initial vision of the track;
  • One side of the track higher than the other to allow for vertical gameplay,
  • A river running through, splitting the world in two,
  • A largely flat area where a village would be built
  • Two different roads to get to the top of the elevated area; a shallow, fast curve and an s-bend that would either have to be taken slowly or jumped.

After these features were put in place, and the road area made as smooth as possible and roughly textured it became apparent that this method of building the track was not as effective as I had hoped for a number of reasons. The main reason being the resolution of the terrain and corresponding painted terrain layers. The geometry was far too coarse to be effective as a road. It worked well for off-road areas, but given the nature of the vehicle I was using and it's stiff and shallow suspension, it required an area with a smoother surface to minimise the constant bumping and grinding with the ground (not to mention constantly getting stuck in almost every gap).
Original blending and density
Additionally, the blended areas where the road was painted on was unacceptably blurred, and without greatly increasing the resolution of the terrain (which was already fairly high) wasn't going to change. Eventually, the terrain did end up with double the resolution in order to fix the majority of texture/geometry coarseness issues, however a different approach to the road itself was taken.
The plan was to create the road as a static mesh utilising per-poly collision, and it worked perfectly.
Given that the terrain was largely sculpted already, and I had little want to go and re-sculpt it all over again (even though I ended up doing that anyway... More on that later) I needed a plan to minimise the amount of work in creating the static meshes.
Yes it was easy. Far too easy.

Retopolising the terrain in Topogun
I was incredibly grateful that UDK allows you to export the terrain as an OBJ, and also the corresponding texture painted onto it.
This allowed me to simply import the terrain and texture into Topogun and roughly creating the geometry of the track. A few minutes later and it was done.
After that it was simply a case of bringing the track geometry into Maya, levelling out some of the areas where the track was sloped laterally, smoothing by two subdivisions to get it to a level where the drive was smooth then breaking it into a few separate chunks and exporting to UDK. Doing this also allowed a quick extrude operation around some areas to create the pavement in the village.
Pavement in the village
Given that the the track had the same origin and scaling as the terrain, the position of every piece could be set to the world origin. Then all that was needed was to sculpt the terrain to neatly follow the track.
During this process I realised two things; One, the terrain really needed more fidelity, as getting the terrain to smoothly follow the road was difficult, off-road handling was far too bumpy and blended areas between terrain materials was still too blurred. And two, more terrain was needed outside of the playable area for both visual and gameplay reasons.
Due to these two factors, the terrain needed to be tweaked. After a process of attempting to add more subdivisions without resculpting (much later I found a button that does this. Urgh.), then a vain attempt to export the heightmap and using combination of enlarging the texture with Photoshop, importing/exprorting and trying to use the heightmap in Maya create a new one then... Well you get the idea. Needless to say it didn't work. The easiest option by far here was to recreate the terrain at the appropriate resolution and size.
In the end this wasn't as difficult as I thought it would be, as the road was already in place to give me a guide for the sculpting. Soon after, it was finished.

Terrain Layer Setup
While researching in an attempt to find a solution to my terrain enlarging problem, I came across the automatic terrain texturing features. Which are awesome and made my life a lot easier. Rather than paint by hand areas where dirt/rock/river bed are exposed beneath the grass, all that needed to be done was punch in some numbers defining where the changes take place. So, anything below -128 units would use the riverbed material, terrain at an between around 45-80 degrees was dirt (I'm not sure of the exact numbers, the values you punch into the Terrain Setup Layer seem to be normalised in some fashion, where 0 = 0 degrees, 1 = 45 degrees and anything over 2 is everything else), anything steeper than the dirt would be rock, which required the mapping to be changed to a side-on plane to avoid stretching.

Short of some minor tweaks here and there, building up of the terrain around the outside of the map and fixing areas where it was too easy to get the Morris stuck, that's pretty much it for the terrain.
Further work will include setting up deco layers for foliage and any debris on the ground, and possibly another material layer to add some variety to the world.

Thursday, November 25, 2010

A Belated Beginning

So, naturally I start writing a development diary two thirds the way through a project.
Rather than ramble on about this and provide such uninteresting things like "reasons" and "excuses" I'll cut to the chase and start recapping the last few weeks of work.

So here's that chase I was talking about.

The Grand Idea
There's not a whole lot to explain here, the whole theme of monkeys and Morris Minors was born out a need to come up with an idea within a self-imposed time frame of roughly five seconds.  Regardless of the irresponsible choice to not think things through, it gave me a neatly formed sandpit to start playing around in.  A sandpit containing monkeys and toy cars.

So far any gameplay mechanics haven't been worked out, but my reasoning is sound.  Firstly, the project is centred around the visuals and intelligent use of assets.  Secondly I wanted to get a vehicle working first.  Then test out it's capabilities and see how far I could tune the control of said vehicle without too much heavy lifting (scripting).

As for that vehicle...
That Vehicle
Urgh.  This was an absolute nightmare.  The sort of nightmare that involves starting at UnrealScript for hours on end.

However it all started off with nothing more than a bunch of pretty pictures of Morris Minors in various configurations, a bit like this:

Yes, they're all very lovely and some even verge on awesome... However I wanted to start off with just your bog-standard Morris Minor and work from there.
(Note...  Looking at this again has reminded me that I completely forgot to place a grill on the from of my Morris.  Crap.)

After finding some decent reference material I entered a fairly painless modelling process and came up with this resulting model that's lacking a grill:
Rather conveniently some of the shapes of the Morris were close enough to those of a vehicle modelled for an earlier project, namely the front wheel arches, wheels, wing mirrors and the bumpers.  The inside parts were also scavenged from a set of reusable pieces of geometry made for the same project.  Helpfully, I had already UVd them so this saved me a considerably small amount of time for which I am grateful.
This has given me cause to create a larger gallery of reusable assets like this, maybe even a MEL script to access them.  Headaches are on the horizon!

Texturing was a simple job consisting of an AO bake, flat body colours and a specular map, however this gets considerably (debatable) more exciting a bit further on into the UDK side of things.  Promise.

Now, this is where the painful stories begin.  So if you're afflicted with a weak heart, short attention span or apathy you should probably stop reading now and jump forward to a part that has pretty pictures. 

The next stage here is the whole rig n' import process.  My initial way of going about this was to replace the material and mesh assets for the existing Scorpion vehicle.  It seemed to work for a couple of others on my course...  So it must work for me, right?

In a word, no.

Rigging the Morris with an identical skeleton to the Scorpion with all bones and names present, then overwriting the existing skeletal mesh should have worked, but it didn't.  It may have had something to do with the fact that I renamed the Scorpion's assets to back them up, and UDK kindly changes all the internal references to that object for you.
So no matter what I called the Morris mesh, it still used the Scorpion mesh.
There was some small "success" in importing the Morris' blend shapes.  Success in the fact that that they worked.  Failure in the fact that I completely broke the Scorpion's Morph Targets.  However I did end up creating a Mighty Morphing Morris Minor.
After an awful lot of back and forward between UDK and Maya I came to the conclusion that what I probably should be doing is creating the Morris as it's own vehicle.

After scouring the internet for tutorials and information, the creation of the Morris Minor as it's very own being began.

The first port of call was to reduce the skeleton to just the bones and joints needed then reskin it.
The joints used are the root (obviously), four wheel joints, four axle joints and a joint for the boot.
Then import mesh, Morph Targets, textures back into UDK into a shiny new VH_MorrisMinor package, put them together and you have yourself a lovely skeletal mesh that functions perfectly as a skeletal mesh that does nothing else.

Before I move onto UnrealScript hell, here's those Morph Targets in action.  Well, not really in action as that would require video.  Expect that at a later point.

After carefully reading through tutorials on how to create a custom vehicle, and coming across some UnrealScript based on the Scorpion, but with all Scorpion-specific funtionality removed, work commenced.

Modifying the scripts to work with the Morris was relatively simple, mostly a case of renaming any references to the Humvee from the tutorial script to VH_MorrisMinor, then making sure the script VH_MorrisMinor_Content was pointing to the vehicle assets:

A couple of changes to the SkeletalMesh reference in a couple of other scripts and class path updates and everything looked set to go, aside from a small snag with a couple of lines of code causing the compile to fail.  Props to this guy for running into the problem before me and finding a solution.

Everything worked, the code compiled without, I could place the vehicle in the editor, I could hit Play from Here and.... Crash.


Try again...  Crash.
Back I go to the script, check over everything... All the naming, references, classes I renamed...  Compared it to both the Humvee script and the unedited Scorpion script.  Adjusted and experimenting with anything that seemed off and still no success.  
After two hours of this I decided to give up and go back to building the map itself and test with the Scorpion instead.  Only in the process of attempting to alter the Scorpion assets it had become completely broken and wouldn't spawn at all.  Eventually the Manta hover-vehicle had to come in as a less than ideal solution for testing.

A couple of days later I deemed it time to have another stab at getting the Morris to work again.  After an optimistic attempt at putting it in the map and hoping everything had fixed itself... Nothing.  Crash.  Not in the spectacular vehicular way.

A sudden thought came across me...  Crash logs!  After digging them out, a clue was found:
There would have been a picture of the crashlog here, but it's since been overwritten.  However the clue was along the lines of this: 
Function Engine.SVehicle:PostInitAnimTree:0075
The internet failed to find me a solution, as all I came across was a lot of people having the problem, but no-one giving any answers.  So I took it upon myself to investigate.  First by scrutinising the AnimTree for the Morris, comparing the naming to the script, but everything was fine there.  Then by analysing the SVehicle script and finding out about PostInitAnimTree...  Not a lot of useful information.  The best answer I came across was that the script couldn't find the Morris' wheels because they weren't named properly.  Yet they were.
After several hours over several days attempting to fix the problem and failing I decided to leave it until I could consult ARU's resident UDK expert Hywel.
It took us an hour.  Hywel eventually noticed that that the scripts were from different UDK versions, which led to us both sitting there comparing my Morris code to the up-to-date Scorpion code for any differences.

And there it was.

One line right at the top of UTVehicle_MorrisMinorWheel.  An 18-line piece of script:
class UTVehicle_MorrisMinorWheel extends UTVehicleWheel;
Which should have read:
class UTVehicle_MorrisMinorWheel extends UDKVehicleWheel;
Changing that one line fixed (almost) everything.  The vehicle spawned but wouldn't drive.  fixing it was simply a case of changing the UTVehicleSimCar class to UDKVehicleSimCar and hey presto!

That's a lot for one post.  I'll write about the approach to the visual design, material set ups and modelling other assets and tuning the Morris in future posts.
For now, rest assured the somewhere right now a virtual Morris Minor is crashing into bad geometry.