Friday, 31 May 2019

Level Design And Level Redesign And Level Redux

Environmental level creation continues in earnest.

Level 4 is a grassland, inspired by the Asian Steppe. Originally the grass was going to be green, but the previous level was predominately green, so for variation I changed it to a more prairie yellowish-brown.

 The Steppe, home to deer-monster, Wendigo-type, thingies ...

Grasslands, by their very nature are somewhat ... well, bland. There's a lot of grass and low rolling hills with more grass and not very much else. The level is mostly wide and flat open spaces, with high, dark, rock walls to limit the playable environments outer reaches. I added a few extra rock outcrops to break up the vast expanse and created a central "hub" mountain which dominates the centre of the map to create a vaguely circular map with a lot of open space. To disrupt the near constant flow of grass I threw in a few autumn coloured bushes which help add variance to the monotony, and clumps of violet flowers for a colour deviation. The violet flowers are all clumped around the central mountain, whilst the red and yellow bushes tend to crowd towards the outer edges of the map. This helps the player orientate themselves a little to their position in the wide expanses.

Whilst planning level design I realised that as the game progressed, the levels were getting too big too quickly. I do a lot of heavy playtesting - because, well, no one else is, so it's the only way to spot issues with things. By level 3 I was getting lost quite easily in the various narrow alleyways of the canyon level.

Whilst developing the gameplay and enemies for each level, I had been using my test level with grid textures for each of the consecutive level maps. This meant that I had always been testing in the same space. When I started to create the actual individual levels I had multiplied the size.

I went back and redesigned the first three levels, first cropping them into a more square shape that would fit inside a 512 pixel heightmap rather than a long thin shape that spilled into a 1024 pixel one but didn't use up much of the available space. This saved on the amount of terrain that the engine had to render and precompile collision for, which in turn saved on the number of polygons that had to be drawn.

The original test level had later become the basis for the first level. This map has a traversable area of twelve percent. Originally I had started by doubling the size for progressive levels but this now obviously far too much. Going back, I redesigned the second and third levels with a formula to increase level size based on around 50%-70% of level 1 size. Thus level 2 now has a traversable area of >150% the size of level 1 at ~20% of the 512 pixel heightmap, and level 3 is >200% larger than level 1 with a traversable area of ~26%. By contrast level 3 has an area of  ~33% that the player can traverse.

Smaller heightmap sizes obviously reduce the amount of renderable terrain triangles and collision calls. For the first time I also used the "remove terrain tool", creating holes in the terrain in areas which the player would certainly never be able to see on-screen. This helped reduce the renderable area further.

Thick foliage.
Thinned foliage -50% polygons. Textures with less leaves show more transparency.

In the spirit of creating complex but also lean environments to reduce overhead I had another look at all my foliage. Whilst grass clearly needs all of it's polygons, I thought that I might be able to save a few on the bushes as the leaves near the undersides are not all going to be visible, obscured by those on top. I selected all the polygons that could be seen from directly above and deleted the rest. Depending on how thick the textures are with leaves, this thinned the viewable foliage somewhat, but for a saving of a whopping 50% polygons. Bushes are there to add movement in the wind and prevent the levels from looking barren, they're not there to hide the terrain beneath them so being more see-through is not a problem.

I tried the same idea with trees but the saving were so small - around 10% - that it didn't seem worth bothering with, so I left them as is.

And that, has been the month of May, 2019. Also the local internet exchange blew up and I was reduced to living a stoneage existence, devoid of memes, waifus, and all the important work related sites and indie game and engine development discord channel I rely on for day-to-day information about work.

In the meantime I rewrote various bits of code related to spawning the player in more open areas, reworked some effects and did manage to have a little play around with the (PBR) Physical Based Rendering package due for release with the next update of the engine.

PBR coming soon ... ish ...

Not entirely sure which bit of the development cycle I will tackle next. I might continue with level building as I am now 40% complete, or I might go back into 3D character modelling and finally replace that yellow placeholder cube with an actual player character.

In the meantime, have a look at some gameplay testing for level 4, The Steppe.

Tune in for next month's exciting instalment of the game development that never ends!

Monday, 29 April 2019

Placeholder Game Level Finally Replaced With The Real Thing

Well, it's been long enough, and in fact seems like forever, that my blank, grid box test level has been on show - but no more! We now have actual game play in actual game play levels!

We also still have Placeholder Player Cube ... but, one thing at a time ...

Starting with level 1 the environment is a dark and rather neglected graveyard, where the dead sleep peacefully ... at least until the player turns up and annoys the hell out of them all (DEEPEST LORE).

And here is a rather long video of the whole thing in action, save for the obviously missing parts of an actual player character and level boss, both of which are currently still placeholder cubes.

But now that we are actually into level design, I am moving quite fast and this month have managed to produce a whole 3 finalised levels.

Behold level 2, The Primordial Forest at dawn, home to ancient plants and even more ancient and decidedly angry velociraptors ... so angry some of them shoot fricken laser beams out of their fricken heads.

And here's a slightly shorter 7 minute video of the level in action. I noticed afterwards that my dinosaurs where not exploding properly and should have been throwing more splatters about. However I had a wrongly named datablock and so the extra gore was not showing up. This has since been fixed.

And finally we have level 3; which I based loosely off pictures of Wulingyuan canyon in China, where the canyon has steep sides of light coloured rock with darker, green vegetation hanging on to every conceivable flat area.

And here is a slightly more reasonable 2 and a half minutes of game play.

In the more cramped confines of the canyon level, I noticed that the enemy spawning often grouped up together at one end of the screen. To create a more even distribution of enemy starting points, I wrote a little algorithm to target the player with the least nearby enemies and then find which cardinal direction (north, east, south, west) had the least enemies and spawn new ones there. This helps to prevent the enemy all starting to one side of the player and spreads the distribution of new enemies out more evenly.

So, their we go. Indie game development is painfully slow, especially for the One Man Army, but once ready to start on creating the actual environments, I have managed to complete 3 levels in one month. That's 30% of the levels done.

Next up, more environments to complete before seeing about replacing the placeholder cubes of the player and boss characters.

Sunday, 31 March 2019

Goodbye Green Grid, Hello Darkness My Old Friend

I took a break from worrying about the minutiae of cat ears to do some level building. It's been a while - in fact around 4 years - of having a basic and rather blank grid for level 1. This has now been replaced with an actual level 1, containing ... you know, level 1 stuff.

 Old And Busted: Not Exactly Grey Box as Green Grid Box

New Hotness: Actual Art Assets 
This required actual models and textures and stuff, so I opened the long dormant folder of 3D models and 2D texture images which I have collected over the last nth years. One thing which I did get years and years ago was Forester Pro - a procedural tree and plant creator. Not only can you create a ton of different types of trees but create variations with a single click of a button. It automatically adds vertex paint which is then used in-game to add the shader effect for the wind. You can also add or remove elements like branches and leaves, though I did find that the save file dies horribly if you go too much off template. Never mind, just export out as DAE format that the Torque3D MIT Open Source Game Engine that I use, and of course can also be imported into Blender3D for making changes to the model more easily. Here I used the normal editor so that the foliage planes face upwards to avoid bad shadowing artifacts. I added an empty high above and had the normals aim for it using Directional mode, that way each plane gets a unified but still individual shadowing.

Wind Effect

Also good for grass 

 I have 10 levels planned, and the enemies all modelled and animated, though not the bosses. So I figured that I would need a few trees. One thing that I found was that the standard black alpha on textures didn't look very good. There is a free demasking tool which writes in colour information but instead I tried using different colours of the image to see what effect they had.

It transpires that alpha colour is important ... even though you can't see it ...

I also had a plant pack for Forester Pro and after exporting a few plants I amalgamated the textures into an Atlas texture to save on drawcalls, and created multiple plant objects to save on instancing.
Not seen here, mixed plant meshes

My next issue was lag. The first reason was some terrible maths which I had written and my code was attempting to spawn 1700 enemies all at once when it really only want 7. Yeah, that sort of thing is going to bring the computer core down to a shuddering halt. Next up was collision. I had set the size of terrain squares down to 0.25m which created a rather high 1568 collision calls per player, Ai and dynamic object. I played around with different settings and finally settled on a square size of 1, which seemed to give good definition visually to the terrain and only cost 128 collision calls which was a rather saner amount. SquareSize 2 would have only cost 32 calls but I preferred the look of 1 square per metre.
When you attempt to use ALL THE COLLISION CALLS

One thing which I had not previously thought about was the lighting and shadowing. Normally the camera looks through the environment and the shadows fade and lose clarity the further away they get. However using a top-down/isometric(ish) view meant that I could see shadow splits drawing across each other. A lot of fiddling with shadow settings later I finally got something that looked decent and transitions between shadow map splits were not really noticeable.
The joys of trial and error shadowMap creation with the helpful PSSM Cascade Visualizor debugging tool

As my first level is a graveyard featuring a very lazy mouse who is supposed to be the caretaker but rather neglects her duties in keeping the place tidy for her customers - level 1 enemy, the dead (DEEPEST LORE!) I opened up the old graveyard art pack which I bought years ago. Some of the model seem to have been rather hurriedly put together with a lot of opening faces - which is the sort of thing my OCD really doesn't like, so I spent a fair bit of time fixing them and amalgamating the textures into single Atlas textures for those big savings on drawcalls.

Blender3D's decimation tool got into the spirit of spookiness

I had noticed an issue with the terrain becoming washed out when the level reloaded. After much hunting around for bugs in the code I discovered that I had accidentally changed the file format for saving the terrain main texture to a low definition jpeg of only 90Kb. The default is a high quality DDS image so I must have been playing around, not noticed the difference in texture because it only updates on reloading the level, and then just forgot about it. Whoopsie!

Adding grass meshes that sway in the wind make the flat texture look a lot better

So, next up is furnishing and finalising the rest of the level and making it playable. The either on to the other levels or back to modelling catgirls.
Head pats!