Wednesday, 31 July 2019

Relearning Everything I Did Not Know About Blender3D

Whilst I wistfully gaze at my still unopened Tax Return, with it's passive-aggressive "PLEASE OPEN IMMEDIATELY" and not so passively aggressive bright red stamp of "31ST OCTOBER IS THE PAPER FILING DEADLINE", my mind turns back to the problems of character modelling, drifting past the bottle of SA Chenin Blanc, into the mysteries of rigging shoulders correctly so they don't deform into some sort of monstrous mockery of Quasimodo, and other general 3D shenanigans.

 Me, trying to get a mesh friendly to weight painting ...

Now I have done all of this before - in very low poly - on the version of Blender3D which I am used to using. That version is 2.44 which came with it's own custom plugin for the DYNAMIX THREE SPACE file format exporter 0.964. You remember Dynamix? They were that video game company founded in 1984. They made Rise Of The Dragon in 1990, a futuristic detective, adventure game which ripped off Bladerunner and I never understood what the hell I was supposed to be doing whilst playing it ...

Anyway, that version of Blender3D dates back to around 2007, which is at least 100 years ago... so there's probably been some improvements and changes since then. And it turns out there has been. In fact I already knew that there had been as I've been tentatively using version 2.78c for a while, ever since they created the normal editing modifier to stop foliage and especially grass, from looking like complete shizen.

Turns out it was February 2016 and still no finished game fml ...

So first up, how do I into character modelling? I can not even into character modelling!

Hello makeHuman! makeHuman is a 3D character/human body generator which I played with years ago and never got back to. However it has one important thing going for it - it exports with a various skeletal armatures and comes pre-weight painted for bones nodes.

After quite a bit of fiddling around, I had previously managed to make a fairly accurate rendition of Toobz in makeHuman (though the fatassed robut needed more ass fattening and the legs slider was never going to be long enough) (and I added extra oppai) and exported it into Blender3D with a rigged skeleton and then slapped some cat ears on it.

makeHuman created a near perfect replica of Nier: Automata's 2B but the butt slider maxed out ...

So next up ... I need said model with cat ears slapping into a harness which would ultimately be attached to some sort of steampunk propeller pack. Cue searching for tutorial videos on all the other changes to Blender3D's modifiers. One of these I have already found out by testing - is that the decimate modifier, which turns your overly high poly mesh into something more video game and Level Of Detail (LOD) distance friendly, now keeps the weight painting data for bones in the armature. Ye olde 2.44 version used to just kill the vertex information, leaving you with an unanimatable (that's not a word is it?) model, so I used to have to do my LODs for Airship Dragoon by hand/eye manually ... which was a real pain in the Shizener. So this improvement was another major reason to finally upgrade to a newer version of Blender3D.

 How character modelling usually turns out without using a proven work flow ...

The model I have been working with is somewhat overly high-poly for in-game. It is also overly rigged, with many bones that I do not require for gameplay. However I am hoping to do a few high poly "cut scenes", so I am currently concentrating on making an intermediate model I can both "poly up and down" later as needs be.

So, this harness then ... I mooched around the internet (as usually but this time trying to be useful) and found a load of video tutorials from 2011 about making a static character model - which is still a lot newer than my 2007 knowledge. And it had this amazing thing called the "shrink wrap modifier"!. Basically I make clothing too big, and then "shrink to fit". And it works pretty good.

Shrink to fit, just like that baggy T-Shirt and a hot bucket of water

So that wasn't too bad, I made horribly baggy mesh around the model for tight fitting clothing, and got it to reduce to the model's topography with an offset with the push of a button (after much experimenting). Next up was building various straps over the new harness mesh manually.

Extra strappiness to stop overly excited catgirls from falling out

And this is when I hit (another problem). I had previously been using the mirror modifier so I only needed to create half the harness, then apply it and shrink wrap. But now I noticed that the buckles/clasps above the waist were not perfectly symmetrical. makeHuman exported the pose with a slight kink in the spine, so everything above the waist is slightly to one side. Straightening the pose manually was easy enough in Blender3D, but it didn't make the mesh perfectly straight, and it was still off. Note to self; check this sort of thing before you start working on it.

Bravely/stubbornly/being past caring* (delete as applicable) I continued, ad libbing (which turns out to be 2 words) as I went and continued. Now the whole idea of the character is that they ski around the level with a propeller driven backpack - hence the strappy harness. The rotors/propellers themselves are going to be flat, animated textures - so that saves some polygons and drawcalls.

Propeller area in dark grey, green is a gauge

 Next up I needed some sort of under clothing, rather like a skin suit or leotard or boobtube (which was a thing in the 1980s). I attempted some sort of vague modelling by hand/eye co-ordination, which is not that great at the best of times, and then went off to find some more video tutorials on Blender3D to see if they would help. This is when I discovered physics. Now I studied physics at school, by which I meant the teacher didn't care if anyone learnt anything or not as he got paid all the same, and thus let me sleep in class (this was the 1980s, the greatest decade in history). I got an E grade which was surprisingly better than I thought I would get for doing nothing.

Anyway, back to the physics inside Blender3D. With a bit of jiggery-pokery it can be used to create clothing that falls into place with gravity (note: T-pose is best for this or it slips down the arms and falls off). I made a whole series of tests, but only screenshotted the final result. This was a bit "flappy" so I ended up tying down the bottom manually. This looked rubbish, so I ended up extending the character mesh out to meet the material which didn't look so great either so I ended up faffing until I had some sort of boobtube, carved a few dints into the middle and called it quits.

Physics in action! Meaning the one physic of gravity

By this time I had decided I did not like the propeller casings being so high and had dropped them into the mainframe of the jetpack - or should that be proppack?

And now to merge the two meshes into one - whilst also deleting all geometry hidden behind the harness in one fell swoop! First up duplicate the original character model, because if everything goes horribly wrong we might need the original again later (wise, wise words). I sealed all the open sections of the harness, thus cutting into the character model and then used the boolean modifier (named after George Boole, tricorn hats off to you, sir) to remove all the unnecessary bits of character mesh that was hiding behind the brown harness mesh.

This created abject chaos.

Firstly, it severs straight through the target mesh, which is exactly what you want ... kind of. It creates F-Gons (a plane with more than 4 vertices)- which are nasty planes surrounded in loose vertexes everywhere. Hunting all of these down to manually fix them to the edge of the source mesh is a nightmare. And it will have to be manually, because the automated remove doubles is distance based and will just eat up random geometry. Secondly the target mesh seals itself where it's cut, creating lots more elongated planes which have to be deleted. After much faffing around with the first problem I decided to try a different tack.

I selected all the visible planes of the source model around the harness and deleted the rest. Merging both objects I manually merged vertices when close enough and built new planes so elsewhere so the source mesh and harness mesh became one. Whilst this was somewhat labour intensive, it was easier and faster than dealing with over nine thousand F-Gons.

So, finally I have a single mesh, at least of the character body and the harness. Next up, data transfer to get the original makeHuman bone weights into my new Frankenmodel. Playing around with the system I found that using "Nearest Face Interpolated" filled out the weight painting to the entire model, whilst some of the others left the buckles of the straps unfilled with weight data.

Great success! Glad I didn't have to do that manually!

So, that's about it for this month. We had a heatwave and I got a great tan. Next up, hair, because what I have been using in all of these pictures is a placeholder, and then to start on UV mapping and textures. I also need to rig that backpack.

There is a new version of Blender3D out, it's 2.80! As it's taken me ~15 years to upgrade to 2.78c ... I might wait a bit ...

Sunday, 30 June 2019

Assimp Does Magic Stuff And I Get Distracted

This was a bit of a surprise.

 That says Blend file that does

Whilst playing around and looking for bugs in the latest beta of open sourced Torque3D game engine, I accidentally imported a BLEND file from free open source(ish) Blender3D modelling program. Obviously this by accident, because I would never have thought that it would work.

I had found some ripped game models and other sculpts (see Tifa above) and was looking at them in Blender3D for modelling reference. I had experimented with various export options and was loading them into the engine when I accidentally double clicked the Blend file rather than the exported DAE file. Et voila, it actually loaded with all materials correctly mapped.

This is due to the new Assimp importer which appears to be able to read pretty much anything and import it because magic.

Literally my understand of how Assimp works ...

Assimp also comes with a metric ton of options - none of which I really understand so I just kept using the defaults except for maybe rotating the up axis to Z when needed - and it kept importing models fine as long as I had multiple mesh objects set to be read as a single sized LOD.

When the Beat-Em Up waifus are extra thicc

I had tried various other model formats and found FBX and BLEND to be the easiest at automagically loading the corrects textures into the material slots. Amusingly - or not as the case may be - the original DAE importer was the worst and created the most hassle. Not all the models I had found on the internets had their textures setup for a standard PBR material, hence the rather off colour Chunners.

DAE->OBJ->FBX->BLEND

I had also seen someone using the normals editing tool in Blender in a way that I had not thought of before. For foliage and tree leaves they had placed the mesh inside of a huge sphere object and then targeted it. This made the leaf faces orient outwards to the nearest sphere point. For my current project all leaf and foliage mesh faces are orientated nearly vertically upwards, targeting a node high above, because that's pretty much where the player's camera is for a top-down perspective.

No normal editing target->Vertical target->Spherical target

Did I mention distraction? Yes I did. I had been harassed by "The Idea Fairy" and suddenly had the urge to make a Dieselpunk Ace Combat style game. I ended up writing up a design document and fairly in depth statistics of how the whole thing would play, utilising real world 1930s and 1940s aircraft. I imagined it would play rather like the old Freespace space combat simulator, only in high altitude clouds rather than space. Aircraft would ... well, aircraft, and airships would make up an equivalent of a real world navy. I also ended up playing through Freespace 2 and the original Freespace mod for it. For the first time ever, I have a state of the art gaming PC and use it for playing 20 year old games.

This thing needs keeping on a short leash ...

So that was the distraction that stymied this month's progress. I did however get some work done on the current project, the one that I am supposed to be working on, by transferring some heavily used scripts for targeting to C++ code to take a bit of weight off the processor when they are called so often. I also added went mad for statistics and added rankings for player performance on to the already percentaged data. I went for the Japanese obsession with S which may or may not mean SPECIAL, so the highest rank is SSS, SS, S before getting into a more standard alphabetical descent, and it goes down all the way to F for FAILED MISERABLY.

Yo Dawg I heard you like Statistics ...

Of course the real reason I did all of this stuff was simply to avoid having to model 3D hair because it's boring. Yep, that was it. An entire month of obfuscation to not doing something that is time consuming and dull. I also got poisoned with a chemical gas leak for two weeks having had an engineer out to investigate a gas leak, then getting a methane detector thinking that it was a gas buildup in the drains before eventually finding the source leaking out of a vat, and I was also immobilised with a back injury for another week, which was caused by just bending over the sink. So not a great month in general.

Next month, getting back to what I should have been doing this month ... allegedly ...

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!

Thursday, 28 February 2019

Lurgy, Ninja Type Dudes, Parallax, Fat Assed Robots and Cat Ears

Last month was all about tentacles. A swarm of tentacles is a fairly big thing, that acts as a movable barrier which can corner an unwary player and slap the hell out of them. One thing that I noticed was that they can turn on a dime, effortless switching direction, which for a big unit looks rather odd. See video below:

Testing Terrifying Tentacles!

So I went off hunting through the movement and aiming code to make the AI use a system similar to the player for rotations. Initially I spent all my time looking in completely the wrong place ... something which seems to happen a lot ... before finding the correct file class and adding a delay that could be set via the objects datablock. This way, small, nimble enemies can turn faster, and hulking great things like tentacles a lot slower.

 Turn Speed; fast, medium and slow

Of course things couldn't just be simple and I quickly realized that my entire AI attack routine was designed around the length of each enemies attack animation - and very few enemies share that data. So an enemy would turn to face the player head on, then start their attack animation and then ... well the player was miles away and out of range. To prevent this obvious pause in starting their attacks I had to write a little snippet of code that took each AI types turn speed, angle required to turn and time to swing at the player into account to make sure that when they landed their blow, it would be at the optimum moment to actually hit their target.

All whilst I was attempting all of this fancy maths malarkey, I was riddled with the vile pox of the lurgy, with puss and ooze coming out of all corners because it's winter and stuff.
 

Being ill really hampers your ability to into 3D vector math ...

This brings me on to modelling the last standard enemy for the game. I still have all the bosses to do (cries into hanky), but the game's rank and file enemies are not complete. Having come up with a rather interesting shader of floaty goo a bit like a lava lamp, I settled on a spear wielding opponent that looked a bit Ninja-ish and called, for want of a better description, the Shadow Sprite. I added that triple eye motif that I see in a lot of Japanese stuff as a signifier of Buddhist mysticism - like that guy with the flour bag on his head with the triple eye motif on it for ... I don't know ... reasons I guess. Having a spear gives a longer than usual range melee attack but also has a narrower angle. Cue me having to go back create new code dealing with attack radius ... radiuses? radius's? radii?

Shadow Sprite surprise!
With the final mob enemy for level 10 completed I set about testing "extended play" aka "endless mode" and found that the difficulty level ramp up quite nicely so didn't really have to tweak my challenge code. I also added a visual effect for deceased radioactive enemies to make it more obvious to the player that there is danger. Some of the enemies spawn as "elites" of various kinds and radiation is one of these. Now when I radioactive enemy is killed they leave a warning sign that that area will cause damage if the player enters it. This only lasts for three seconds.

"Ra-di-a-tion. Yes, indeed. You hear the most outrageous lies about it. Half-baked goggle-box do-gooders telling everybody it's bad for you. Pernicious nonsense! Everybody could stand a hundred chest X-rays a year! They oughta have 'em, too." - Repo Man, dir. Alex Cox, 1984

Having a break from modelling I had a look at how the PBR branch on github was doing. Rendering really isn't my thing and material systems probably even less, so I just nodded a lot ...

No idea what's going on but debugging does look pretty

Having spent rather a long time on animation and characters and the like, I went back to trying to remember the work-flow for materials and in particular parallax. I found that a rather enormous 12.7mb 2K normal map texture with a heightmap in the alpha channel didn't seem to have much better quality over half the size which only weighed in at 2.4mb, which is quite the saving for VRAM.

2048px 12.7mb top, 1024px 2.4mb bottom. I can live with that.



Finally I got round to thinking about the yellow placeholder cube, who has represented the player for nth years of development. Filled with horror at the thought of actually having to paint armature weights and rig a character from scratch I booted up the medically resourced makeHuman with the intention of exporting a basic mesh character to work on in Blender. I quickly found that COLLADA export is not that friendly to bone angles with everything defaulting to just one direction rather than following the skeleton, but FBX preserved the bones correctly.

As a test, I had a play about with the sliders to see if I could make a physical match for the 2B model from Nier Automata. Surprisingly only the pinched waist being beyond the standard sliders from the model silhouette I was working from, and the only maxed out sliders were the butt ... which is kinda understandable, considering this is the robot with the highest polygon count arse in gaming.

 All the polys ...

 When you spend all the VRAM on polygons for the robots butt, and can't afford HD textures on the scenery ...

Anyhow, I gave the proportions I wanted to my base mesh, learnt a bit about exporting and then started customising it in Blender. I've started off with a fairly high poly mesh until I decide on what I actually want so that the high and low poly versions will (hopefully) look the same.

I seem to have spent an inordinate amount of time tweaking cat ears into just the right angle even though I am fairly sure it doesn't matter, but hey OCD and all that ...

So, that's a start on a base model for the player. The idea is to have a high poly model for intro and cut scenes, as well as an animated "Doom" style bust view in the GUI where placeholder banana currently is. However I do kind of think that it might be a bit small for an animated character to be pulling faces from. Once I finalise what the character needs to look like from the rather hazy description I have in my head and multiple character types required, I'll start on the low poly version that will actually be in the centre of the screen, under the player's control.

February has ended and it is officially Meteorological Spring.

Thursday, 31 January 2019

Terrible Tentacle Terror!

So, I managed about 3/4 of Dry January before falling off the wagon. Not a record by any stretch of the imagination but there was a solid few weeks without any booze in there.

Back to gamedev ...

In the last month of the last year I left on the nail-biting cliffhanger of ... modeling yet another enemy. So yeah, 3 years in, and the player is still a placeholder cube ... anyhow, back to that enemy character.

 Tentacles, in gloriously awkward to animate 3D

Tentacles. The scourge of cartoon schoolgirls everywhere (okay, only in Japan - literally nowhere else in the world, it's just Japan).

Cthulhu moves to Japan ...

It turn out that one thing a big bundle of psuedopods has trouble with is avoiding clipping into and colliding with each other when you use the minimum amount of keyframes in an animation. Tentacles turned out to be not that difficult to animate, pose into a nice, organic tentacle shape one way, then n frames later and another keyframe the other way. Let Blender 3D do the "tweening" (which is an animation term apparently for automated process of animating between keyframes) and then tweak the middle frame if it looks funny. Unfortunately there was a lot more frames which ended up needing "tweaking" to stop the writhing mass of extremities becoming a jumble of clashing appendages.

Did I ever mention that everything in game dev takes way longer than it would first appear to? Oh, every blog post? Yep, right ...

Placeholder cube getting snug cuddles from tentacles

Anyhoo, eventually said tentacles where animated, calibrated, datablocked into actually enemy AI and unleashed into a game level for tweaking - and boy did they need some tweaking. Player ended up squished rather quickly, then it was a case of tweaking data from too easy to too hard until it met in the middle somewhere.

Big tentacle, little tentacle

During testing I noticed an issue. Every so often a tentacle would fall from the sky past the camera to where it was supposed to be in the XYZ of the game world. I've seen this happen with other models  before and each time I fixed it and then forgotten what the cause was. The last time I fixed it I remember thinking that next time I will know the cause adn solution ... except for I have forgotten it again ...

I went back and checked through my written notes on exporting animations and then through all my "how to" forum posts ... and it looks like I didn't record the reasons anywhere. It's got something to do with animation or COLLADA format export - but that's as good as my memory is helping right now ... so a bit more testing and tweaking of the model and exporter is required,

Tentacle surprise!

I also made a whole load of really cool effects, like spawning and fleeing and attacking - but in actual playtesting there was so much going on that a lot of it is easily missed and the constant rattle of tentacles bursting through the ground gets rather annoying, so I plan on simplifying the audio and also some of the particle effects.

So, that's pretty much January covered. There was some other maths related stuff concerning getting player evasion to trigger the way the player is moving when it's different from the way they are facing - which ended up being more difficult than expected because I forgot to take randomized camera rotation into account on spawning and also forgot about normalizing vectors in 3D space - but it was mostly tentacle animating.

To be continued ... possibly indefinately at this rate ... naw I'm just kidding, I'll ship before Half Life 3.