Search This Blog

Thursday, December 15, 2016

Technique Training: Optimizing Game Guru Levels

So I was working on my most recent project - *famous game* homage for my wife.
Something she could play for christmas.  My son and I were both going to help each other and produce a really masterfully done game for her in the vein of one her favorites.

This would be done in a 3-4 week timeline with about 3-5 nights a week of a good solid 3-4 hour runs on adding stuff.

Sourced from Seriouslyjacque.com - very accurate assessment of stress, IMO


Well we quickly discovered how unwieldy a large map would be treated by Game Guru.  So I decided to go back and optimize the map in every way I could.  Here's a bit of that process.

Before we begin...Limitations

A key understanding here is that Game-Guru is only 32-bit.  It's also using DirectX9.  These are effective, but outdated infrastructure components.

32-Bit applications are limited to 4GBof memory. But really, considering all the underlying subsystems, operating system data, etc.  It's more like 2.5 GB.  Also, for the uninitiated, memory is basically the short term, high speed data storage your computer runs applications in.

Holy crap he writes, makes games AND uses excel, incredible!
 
64-Bit on the other hand, can access something like 16 EXABYTES ... some absurdly large number that's out of reach for the time being.  So arbitrarily, we'll use a common value of 16GB for our memory example.


As you can see, your game only takes up a *FRACTION* of available memory on a 16GB system.

Bear in mind though no matter if you're running a 64-Bit version of windows (as I am) that the application itself, in this case Game-Guru, can only ACCESS 4GB of ram at any given time.  And it always considers the OS as part of that.

In real terms, this means that only 2.5 GB of memory is ever available for any given time.

Now consider that every single item you add, every texture, every object, etc - occupies a bit of that storage space.  If you are using thousands of unique objects, each one has to be stored separately.

DirectX9 adds another limitation in that it is vastly more CPU reliant than DirectX11.  So in my case, for instance, I have a quad core AMD running at 3.2GHZ for my primary system.  My video card is a GTX960, with 1gb of video ram.  While it's not top tier it's still an excellent card for any game.

Except, of course, Game-Guru games. This is because DirectX9 relies on my CPU which is at best, mediocre.

Unfortunately this is another pipe-lining bottleneck we have to work around (at least until Lee gets off his duff and codes this thing in DX11!).

Optimizing Memory

 

From this standpoint of minimizing memory usage, we need to utilize this knowledge in a ground up context.  While a lot of AAA titles these days use incredible CPU and Memory resources to produce an earth-shaking experience, many older systems and titles had to be more inventive.

Some examples of this are:
Fallout
Silent hill
Resident Evil

What we're going to do here is emulate the design by using a tried and true multi-level system with several small zones off a hub zone.  This is the main world, an area where you navigate from place to place.  However once you arrive off the world map, you open a door to a building and are transported to a new level.  This is done in such a way that the load times are minimal and it typically makes logical sense.

Example:
Outdoor zones in fallout 4 are part of the 'world' zone -
This quarry, for instance.




But when you go to a building of any measurable size, you get an 'enter' option that you can click which gives you a loading screen like this:

Side note: Probably the most interesting weapon in FO4.

Then you're loaded to the new zone.  Now we can accomplish a similar trick (albeit without the fancy loading screens) using winzones.  The winzone object in Game Guru allows you to setup a pointer to another level which is then brought along when the game is compiled.  When the player steps over the zone, it ports them to the new level.  You can also port them back to the original level, if you desire.  This is the method we'll be using.
The concept here is very simple.  If you are using one large map, it's seamless - without load times.  But it's going to be slower because it's got to load all those objects into memory.   It's also going to be less flexible because each unique model you add to your level is going to increase memory consumption. So concessions will have to made if you do that.  There's also the issue of load times.  If you run a massive level, it will cause gigantic load times for game-guru.  You also *ONLY* will ever have 2.5GB of memory to work with.  That's a huge bummer if you're using high quality textures.


Fallout 3's map - the red spots are *mostly* a level portal to a new area as discussed.



Instead we're going to launch sophisticated areas (Schools, hospitals, houses, minizones) as their own zone and thus free up the memory we would normally use for the world and pour that into each individual zone.  For the sake of load times, we don't want to go too crazy, but even if each zone is 500MB in size it quickly would add up if made as part of a massive world map.

The difference is clear, at least in terms of memory usage.

This gives us the ability to rapidly distribute the load across multiple maps and bring up our total resources used.  It also gives us access to extra goodies in Game Guru such as differing skies or settings between maps.

To further speed things along we're going to use low poly models when available, low quality UVW (UV-Wraps, aka textures), and try to reuse models.  Every time we reuse a model, it further saves memory by simply requiring a pointer in memory vs a huge reload of the object into memory. 

Ground Up Design Processes

Now that you know *WHAT* we're going to be doing - it's time to do it!


The above is a simple demonstration of how to perform a multi-level configuration in Game Guru.

The first thing we want to do, as usual, is map out our levels.  We want to keep in mind that any main areas will be sectioned off.  Even the world map can benefit from being broken up into sections.  I prefer to use major areas or quadrants.

I like to draw on paper exactly how things will flow for the player.
But this isn't paper.  This is the internet. So you get a bad MS paint drawing.

It's terrible, but you get the idea, probably.
The next thing to do is to figure out the assets we're going to be using for these zones.  Each of these areas will have it's own specific feel and layout. So make sure you create a list of each area's similar assets so you can keep track as Game-Guru's asset management is pretty abysmal.

This is, in essence, the very rudimentary beginnings of a pre-production blueprint.  You should check this link on more about that:

http://www.worldofleveldesign.com/categories/level_design_tutorials/why-i-failed-for-years-at-level-design-and-game-environments.php

Moving on.

So basically what we want to do is use similar, low cost entities when doing background pieces and higher cost/high poly models in foreground elements.  Remove anything extraneous and wherever possible duplicate items.

Picture sourced from game-guru.com's screenshot gallery by user Morphtactic

You can see above a good example of reusing elements.  The trick is primarily to use them assymetrically.  Giving an object that's visually similar the same orientation causes the brain to see it quicker.  Giving it a slight twist, say 10 degrees, can make all the difference in how two identical models are perceived.  I give more info on little tricks like that in this article: http://gamegurureport.blogspot.com/2016/06/technique-training-level-building-basic.html

So all that aside that's basically it!  Just break up the level into easily digestible chunks and it will keep things nice and low for you.  You can still have sprawling maps - just be smart and keep the load times down!

Finer Tuning

Once you've got your indoor levels fleshed out it's important to remember that indoor levels can basically be stripped of terrain and/or water using the stock script 'goindoors.lua'.  This will further help framerate on visually intensive locations.  Just make sure you account for the lack of terrain if you have transparent windows looking out into the world.

Another important element is to not load up your scenes with tons of enemies.  Unfortunately the AI right now really doesn't support group think very well so it tends to act in a very poor fashion when more than a handful of AI are active at a given time.  Done properly (use blind corners, traps, etc) you can still make the situation difficult for the player without killing their CPU in the process. 

Other things you can do are fine tune your occlusion settings, which are tricky to get functioning properly but once enabled will properly cull objects out of view to ensure that the maximum framerate is being used at a given time.  This however will be a topic for a future date, when I can devote more meaningful time to the discussion of occlusion.



After Christmas I'll put a post up showing more specifically how I used this and screenshots of the work involved so a better idea can be had about how it was utilized.

No comments: