And so all good things come to an end ... and so do all bad and indifferent things too.
For December I spent most of my time starting early on that festive gorging ...
Me, one week into December
Me, December 31st
However it's not all been shoveling cheese, pate, chocolates, nuts, unidentifiable high fat stuff and booze down my cakehole as fast as possible. It's just that it's been mostly that ...
I've spent the dev time this month mainly on balancing my still untitled top-down, twin-stick, mecha-musume, nekomimi, Swag 'Em Up. This has led to a fair bit of tweaking and minor/major adjustments as I test full playthroughs to make sure things don't become overly difficult - if the creator cannot escape a level how on earth will a player?
I've only 2 more levels of enemies to model and animate. One of these enemy types are tentacles which I had been dreading from the animation point of view. However I managed to find a good monster model with plenty of tentacles and animations which could serve as a basis for my own work. This model had a whopping 170+ animated bones which exceeds the engine capacity for a single armature. Happily I only wanted the tentacle bones and so could delete the rest, but this still came in at a rather whopping 18 bones per tentacle for 6 tentacles. Now whilst only the level boss monster will have all the tentacles with the standard level enemies ranging from 1 to 3, I felt that this number of bones could still be halved with a bit of merging weight painting and manually repositioning animation keys to make up for the reduced transforms.
Tentacles, the scourge of cat-eared, cartoon schoolgirls everywhere ...
I also found another boss style monster that had some great animations for special attacks and the sort, so added that to my ever growing library of commercially licensed animations.
The cunning plan for 2019 ...
Finish off the last 2 level monsters, something I had hoped to have completed by now but meh ...
Create the boss models and animations. Each level has a cat/fox/etc eared defender, often accompanyed by a larger monster to do all the dirty work whilst said fluffy eared guardian shout abuse at the player from an animated GUI box.
Sort out the remaining special item models and animations.
Both of the above points feature around the player models. (Hopefully) 2019 will be the year when the yellow placeholder cube is retired in favour of (multiple) player characters. I am planning on having around 8 playable characters with differing abilities and special attacks, and so far have 2 of them fully coded.
Anyhow, roll on January so this festive excess can finally end ...
He is one of two Knight models which I customized into my Unstable Dimensional Knight enemies all the way back in summer (summer now a distant memory as I hundle under a blankie whilst freezing rain peppers the external windows). Dimensional Knights suffer from "instability", something most RPG and fantasy wargamers know affects inter-dimensional beings, and that's why parts of them kinda of warp in and out of existence. Whilst the models were good quality and rather (too) detailed - way more polygons than I need - I found that their animations were a bit lacklustre having not been based from motion capture footage. Not particularly seeing any mocap which I liked for a reasonable price commercially, to get some decent custom animations I decided to amalgamate their stock animations with some free mocap and rotoscoping - the latter being a horrbily time consuming animation but more exact than "best guess manual animation", at least for positioning large items like limbs.
And this is where total chaos ensued.
It didn't help that was now using three seperate armature rigs (skeletons and bones), what with the bvh format mocap files being different structure from the models' source files which were different from my generic animation rig. Now it's not too difficult to rename bones, animations and mesh vertex groups, except at some point quite early on, I changed the basic non-animated root pose - thus throwing all the rotations for animations off. Annoyingly I only realised my mistake towards the end, and with four variants of two models, ended up having to manually repose all eight enemy models individually by a mixture of copying coordinates and using the judgement of the old fashioned Mark 1 Eyeball. Between this and manually merging different animations together along with rotoscoping over other animated meshes and video stills created a huge gravity well which sucked in vast amounts of time and effort.
Eventually I had a two spawning animations were our Demonic Knight salutes or issues a challenge to the player, two idle animations with some weapon flexing, three attack animations, one leaping overhead special attack animation and various jump, fall, land and other animations.
2 models, 2 idle animation poses, 4 colours
Then there was the slight issue of how to get this enemy type to move. If you are an "Inter-Dimensional Being" then walking seems like a rather mundane method of traversing the game world. Having them just ski along in their root animation made it look like I couldn't be bothered doing a movement animation so instead I created a floating animation. This also looked a bit unexciting at first, initially because the animation resembled the "T-Pose" that many models revert to when they are not animated. I changed this to create two seperate movement animations, one were the enemy holds their weapon in front of them a little like the holy pose that sculptures on the stone coffins of dead knights have, and the other were they are reaching out towards their target with one hand and raising their sword as a sort of challenge in the other.
To the models I added some extra effects to give them more of an other-worldly feel and an intimidating presence of power. One of these is a simple translucent cloud which looks like a particle effect but is actually just three rotating textures of differing intensity and colour. The other is an aura of power on the ground which is connected to the enemy's animations. This gently pulses when they are not moving, spreads and rises during their attacks, and shoots up to envelop the model when they move, making for a much more interesting floating animation. They model also elongates slightly when they move which makes them more intimidating. To the Knight's textures I added a bright animated outline to help with a shimmering glow around the edges and dropped the actual glow shader I had been using on the materials. This reduced drawcalls by a couple whilst reducing the need to draw an extra 27K mesh triangles. As one of the models was a 16K triangles, I decimated it automatically down to a more manageable 12K with no visual impact.
I created a new special attack for this enemy type which involves them teleporting close to a clear area near the player. They start their special attack animation of a jumping overhead axe swing and particle effects surround them and the position that they will teleport into to complete their attack. This gives the player 1 second of warning to get out of the way. Initially I also created an invisble collision shape into the area to block the player and other enemies from occupying that space but realized that it would interfere with how decals are positioned, so I swapped the collision mesh for a physics zone which keeps other enemies out of the area but can slow the player down if they enter it. This seemed to work rather nicely. Originally all of the Dimensional Knights had this special attack but as I based it off the movement phase rather than just the attack phase I realized that would cancel out directly hunting the player as an option to the enemy AI's thought cycle. Now only half the Knights have this teleportation attack whilst the others move as normal, either heading for the player's last position or following directly as a hunter.
Here's an early look at the Dimensional Knights in action before I had finalized their animations.
So that was the Unstable Dimensional Knights of level 7 completed. A tough slog which took far more time than I wanted ... but I say that every month when I write these blogs ...
So, what left? There are a few more enemy types I want to make. Going back to the old Monstrous Morris Men Wendigo style enemies, I want to add a nymph-liek character with a special attack that includes a dash through the player, however as they will share various animation characteristics with player characters, that is something to leave until the more monstrous monsters are done (rather than constantly going back and forth between things). So next up on the list of over nine thousand things to tick off are those of a more Cosmic Horror motif. Cue tentacles and Lovecraftian madness ... and Lovecraftian madness seems to be a good description of indie game development ...
Whilst agonizing over golem design followed by golem re-design, I had a mangled LOD mesh which resulted in a crash. Making a slight change to the mesh and re-exporting fixed the crash, but I also noticed a curious error warning in the console (which probably wasn't related).
bind_shape_matrix in mesh# controller is not invertible (may cause problems with skinning)
Wut?
A little bit of digging around the codebase led to these most useful code comments.
// Some exporters (AutoDesk) generate invalid bind_shape matrices. Warn if
// the bind_shape_matrix is not invertible.
Wut?
Okay that wasn't very helpful. What would the skinning problem be (I had not noticed any) and how do I fix it for export from Blender3D? Alas, the interwebz were not particularly useful in determining how to do this, so I started a process of elimination, based on the logic available. Deducing that many of my models were rotated and vastly resized soley using the armature, I eventually found that uncoupling the mesh from the skeleton, and manually editing the mesh to resizing, rotate and align it to the bones cleaned up this error message.
The downside turned out to be how many instances of this error there was. I have so far created a variety of characters which weighed in at ~110 seperate meshes, and 85 of them needed resizing and manually aligning - and as it was the meshes which required directly editing, I couldn't just snap one object to another - which is actually part of what caused the problem in the first place. At least it was an error caught before I got to the end of character creation, but it would have been much less hassle to have found this out at the beginning, possibly with some huge flashing warning than a few red lines in hidden amongst the jumble of text in the console soley during first importation.
Golems, golems a plenty
So this brings us to golems, and the constant redesign of the little blighters. Who would have thought that creating a vaguely humanoid shape out of clay/rock/earth would have been so complicated. The problem was, I didn't really like any of the designs which I came up with, thus creating a whole array of slightly different clay men ensued. Eventaully I went back to my first design and added glowing cracks. Initially I had these cracks animated, first with a pulsing effect which didn't seem to be very obvious, so I changed that to an animated one. This looked quite cool when they were not moving but became rather busy and not particularly obvious with them running about, so in the end I decided to keep the glowing cracks static.
I made a rather interesting spawn animation from which the golems are created from animated rocks gathering together and then fall away to reveal the monster within. It looked quite fancy having it happen over time but this is an action game so the whole thing had to be compressed into one second. Likewise when a golem is slain it collapses into it's constituent parts of rock.
Golems Spawing, pre-glowing cracks
In game, the golem is a small and heavy enemy, best suited to swarming the player. As they are made from earth/rock/stone/etc they are very heavy and cannot be pushed out of the way (at least not by the physically weak gun wielding, range-based default player character). Golem has death in Hebrew written on it's face - not that you can see this at the scale and angle, but hey it does.
I also changed the overall colour scheme of the game, getting rid of the greenish colour and replacing all of the HUD elements and user interface with an old blue colour I liked.
Green out, blue in
And here's the golem level in action.
So far I have around 70% of enemies for levels done - not including level bosses, and of course there are a number of player characters to yet create and replace that yellow cube. I am leaving those until last as they are all a variation on a theme and will share the same skeletal structure for animation.
Next up is organizing animations and data for attacks for my old "Dimensional Knights".
Scorching heatwaves have faded into Autumn and the oversized fan I went to so much trouble to get hold of is now packed badly into it's box. At one point I was swarmed by the "Idea Fairy" for other game ideas.
Actually footage of me defending myself from new game ideas
Back on the gamedev front, I added GUI markers to the interface for when the player gets a temporary boost or decline. Previously such events were heralded with an informative element saying what had just happened and how long it would last for, but there was no actual timed element to let the player know whether it was still on-going or had stopped. I decided to change that with a simple "up arrow" icon for boosts next to Experience, Health, Energy and a "running man up/down arrow" for temporary speed changes. Once the temporary change is over, the icon vanishes. Having a speed boost also now protects the player from slowing attacks.
Boosts!
I also gorified the decapitations. Not only do head explode and blood splatter but now jugular veins spurt and throw extra splatter on to the ground near the neck when the corpse finally comes to a halt.
Boom! Headshot!
A long time ago in a galaxy far, far away I had coded some custom homing missiles. However they would cause a crash if their target was deleted - even though I had told them to reset and lose height if there was no target.The hacky workaround was simply not to have any deceased target permenantly delete faster than the lifespan of a missile. Recently I realized that I had failed to add a "isProperlyRemoved" for the target deletion check, and this fixed the crash.
Getting on with modeling and coding new enemies, I eventually found that Blender 3D has a csg style tool called "Boolean Modifier". This can slice, delete and merge two different meshes. Annoyingly I found all of this information out after I had been doing the whole thing manually ... (insert autistic screeching here).
Nobody Cared Who I Was Until I Put On The Mask ... and then beat the player to death ...
Previously I had modeled a plasma-rifle wielding alien based on the old Manits Man character, and named it the "Kralmok Warrior" after the name of the weapon it carried. This enemy has now been renamed again as the "Hive Warriror" - which is a little easier to say, never mind spell as I found "Kramlok" appearing in my code quite often. The Hive Warrior is a level 5 enemy and is now accompanied by an Engineered Brute.
Brutes with a Hive Warrior and a human sized zombie for scale
The "Engineered Brute" is a genetically engineered ... er ... brute. A large and relentless enemy with a melee attack which whilst slow, recovers quickly. They are the sort of solid enemy which the player will find difficult to push out the way, especially the default ranged weapon (gun) based player character. It spawns by teleporting in just like the Hive Warrior and gives out a gutteral snarl to announce it's entrance in overly dramatic style.
Dramatic Entrance Is Dramatic
Now that I am at testing level 5 enemies all together I realised that I had not created an easy function for this and instead would have to play through the other levels first. Which is fine apart from the time taken - unless I get chomped on by giant spiders in level 3 and it's all game over and start again. To rememdy this I coded a little function which starts the game at the desired level with the player upgraded through typical experience leveling and powerup collections from previous levels.
My Face When I Didn't Do This Earlier ...
10 whole minutes of testing combat against Level 5 enemies. I got pwned in the 10th minute and never escaped the level.
So, that was the month that was. I fixed and tweaked loads of stuff, got level 5's enemies modeled, animated and working, and found a whole new and easier workflow inside Blender for modeling.
Spiderpig, Spiderpig, does whatever a Spiderpig does ...
Placeholder Cube under attack from (not very hairy) spiders ...
Variety is the spice of life ... allegedly ... anyhow, I am trying to have a varied and interesting range of enemies. As an easy introduction for the player I have started out with ye dull olde zombies before venturing into more interesting adversities such as velociraptors, strange deer headed Wendigo creatures and insectoid aliens. However they are all rather ... two legged. So I decided to get away from bipedal creatures and into more ... well, legs. Thus, spiders! Now as we all know spiders are complete bro's, and anyone who says otherwise is probably a fly or mosquito or something.
I wanted hairy spiders, but quickly found that sticking hairs all over them did not really show up very well, what with the distance of the camera, so instead ended up making the spiders more shaggy. The larger the spider, the shaggier. Making shaggy spiders ended up taking way longer than expected, just like everything gamedev related ... :/
Testing various levels of spider shagginess, before I added hairs to the legs
Having a spider level, I wanted a variation in spiders themselves, and chose 3 types with obvious visual differences to help the player understand what each type does. These are, rather unsurprisingly, small, medium and large.
Small spiders are thin, smooth and spindly, without addition hairs. Small and fast, they charge at the player with a toxic bite.
Medium spiders have hairy bodies. In addition to the standard bite attack, which is less toxic than the small, charging spiders, they have a spitting attack for use at range.
Large spiders are the hairiest and serve as damage absorbing tanks. They are also the heaviest, so trying to push them aside is difficult, especially for player characters with long range weapons who are the physically weakest - eg: default gun player character. Whilst I have coded a shotgun player character I have yet to design the data for melee based ones.
A range of spiders (and some test ones at the bottom)
Here is a good 13 minutes of testing the spider level in combat. I accidentally used the wrong model for the smallest spiders, and later also changed how the hairs cast shadow as they made the largest spiders look too dark from certain angles.
Action Spiders!
I also spent sometime thinking about general combat. First I created a "miss" effect for melee attacks which do not hit the player. For standard melee attacks this is a small distortion flash and some sparks, whilst for larger monsters there is an accompanying puff of dust. Attacks which do hit the player trigger an on-screen damage effect so there is no reason for additional effects.
I enhanced the blood decal effects too. Previously these had been a single, randomized decal. Now there is a splatter effect of blood going outwards. Standard deaths have a single additional splatter, whilst decapitations and full body explosions have considerably more.
New splattering effects before I honed and increased their randomization
All this and various additional and general gameplay tweaking - and some sun bathing because there was a heatwave - took up the whole of August.
So, what's up next. Good question. I've been rethinking my list of levels and extending it. Deer monsters level needs an additional enemy which are likely to be fast moving spritegirls with a ranged special attack. Insectoid/Mantis aliens need a melee based tank/brute. Interdimensional Shadow Knights have been modeled but are still in need of animations. There are a couple of planned levels with no modeled enemies, and all the level bosses and player characters are currently placeholder cubes. Several special attacks still require fancy models and of course all the actual levels are just the single test environment. Originally I was planning on creating whole levels out of meshes and lightmapping it all to save CPU/GPU load but now I am not so sure and might use the more "traditional" methods of creating the environments.
There's been a heatwave ... and I have got "The Dreaded Lurgy". It's not been a great combination. However, though only tenuously attached to this mortal coil with sickness, I have risen from my death bed to write this blog, and show the work I've been doing whilst on death's door ...
I was going to do some spiders as enemies for the player, but instead ended up grappling with some sort of Wendigo/Beast of the Wilds/Herne the Hunter sort of thingy-majig. I have bought a number of models, mostly for the animations, and have decided to retro-fit and modify them for my purposes. So I amalgamated a number of models in creating "The Deer Hunter", a sort of archetypal monster of the wilderness which I intend the player to come across in a rather desolate and windy steppe-like grassland.
The Deer Hunter, available in four earthy flavours
I was umming-and-ahhing a bit about how to spawn them in the level as it seems almost everything comes out of the ground. One it's convenient and two it sort of fits that creatures emerge from their own lands. To give a bit of variation, and to avoid everything clawing it's way out of the ground like a zombie, I decided that the Deer Hunter would rise up as though propelled on a lift (that's an elevator to our former colonial cousins), holding it's skull in it's hands, and then fit it's head into place. I thought it was a rather amusing effect.
Over here son, on my head!
I also thought that this might be a good time to introduce the player to invisible enemies. They come in two types based on the shader effect I used. One is a slightly wavy Predator style optical camouflage effect which produces near invisibility whilst the other has an internal shadow which makes the distortion more noticeable. I still fondly remember playing Doom against a horde of pink Demons when suddenly I realised I was getting bitten by an invisible one. Learning that some enemies are (semi)invisible is always a nice shock for the player.
Another variant on this stag monster was the "Monstrous Morris Man". This is basically the Deer Hunter with different antlers, wearing a Morris Dancer style rag coat (a coat covered in strips of rags). That's the bit inspired by Morris Dancers and thus there is a lot less drinking ale and prancing about waving a sticks, and no guy called "The Fool" with black smeared on his face. Why has he got black smeared on his face? Because he's covered in shit and doesn't know it. Why doesn't he know he's covered in shit? Because he's "The Fool".
Monstrous Morris Men in colourful rag coats
The rags themselves were looking a bit flat, so I created a second UV channel and unwrapped it using Blender 3D's automated lightmap unwrapping, so that none of the polygons overlapped and that they were all clustered nicely side by side. I then baked ambient occlusion to this channel. Once exported and in-game, I added the new ambient occlusion image (with alpha inverted of course!) into the Overlay channel of the material file.
Ambient Occlusion from the additional UV channel helping add depth
The Monstrous Morris Man comes with a long range special attack, and is able to throw some sort of energy bomb over distance. Other than that, all these creatures are melee based. Below is a video showcasing various spawning, deaths and finally special attack.
Another month, and more progress ... and a being ill in a heatwave, which is a real annoyance. So next month ... maybe get those spiders working.
Apparently the UK is under a LEVEL 2 HEATWAVE WARNING ... not that I'd know about such things as I am covered in a blanket of fog with a chill wind coming from Svalbard, to the extent that I am expecting angry undead lepers to start banging on the windows demanding their stolen gold back. But as this is not the Weather Channel, on with the show ...
Not the heatwave you are looking for ...
I am currently at the stage of development were I am replacing the beloved placeholder cubes with actual models, thus creating unique enemies per level with their own abilities and statistics. So far I had wanted to introduce the player with some familiar enemies for level 1 in the shape of 3 different types of zombies (it appears I am the only person on Earth who has never really been into zombies, Day Of The Dead being the only zombie movie I ever had any interest in). After this I had some rather spiffing Velociraptors and even gave one type the ability to shoot "frickin laser beams" out of their mouths as a long range special attack.
Everyone loves dinosaurs ... until they're eating you ...
For some later levels I had thought about going for a riff on the classic black knight look. I came up with the idea of interdimensional knights who suffer instability, constantly being dragged in and out of their own dimension. To this purpose I used an animated texture with various changes to alpha and a patterned diffuse with the edges of the various elements of the model picked out in colour.
There are 2 types of Shadow Knight, Axeman model shown here
The Warp takes me! It's feels slightly off putting ...
Spawning, pre audio effect
These still need animating. Whilst the models were of good quality (though needed a fair bit of work to make them useable through Blender) their stock animations were a bit ... average, so I intend to go through my huge library of mocap BVH files to find something more exciting. As interdimensional entities I'm thinking that they might just float around rather than run.
Noting that most of my game enemies are melee based, I came up with a plasma rifle toting "Mantisman" alien. This is an actual Torque model by GarageGames back when they still made game engines so you'd think that it would be set up the same as the other stock stuff. Alas no, as it was plagued with various inconsistencies such as strange bone settings whilst used the animation files to fix the baffling rotational default offsets. Needless to say this really made it not just a pain in the arse to modify the base mesh but also meant that it's animation were not compatible with the other GG models. In the end I scrapped trying to retrofit the multiple death animations and came up with a simple solution - just make the damn thing explode on death. Problem solved. Another major issue was that the stnadard aiming animation method just did not work at all. Flcuk knows why but I ended up having to use the old Mark 1 Eyeball with trial and error adjustments which ended up with around a 20% offset from -85 degrees (which is the stock downwards aiming constraint). The alien rifle needed a good remodelling too.
Mantisman in action, and now renamed "Kralmok Warrior" after the gun
Initially I just used a variation of the zombie explosion death, using the engine automated "blowUp" function. With MantismanKralmok Warriro being a larger model than the zombies and thus splaying further forwards so that it's not centralized to it's origin (another inconstitency that made me wonder what were they thinking) it ends up looking a bit obvious when the mesh disappears and goo rains down. To get around this annoyance I made a custom explosion debris featuring various recognisable body parts of the main model.
Boom Splat!
The plasma rifle got a remodel and some custom projectiles. I also gave it a long range special attack that features a barrage of bullets with long tails, whilst the standard shot it an energy ball.
So, next up, more modelling. The Shadown Knight's need animations and the Kralmok Warrior needs a bit of tweaking and multiple skins/textures for some variation. Next enemy on the list - Spiders! Cos everyone loves spiders!
The last month has been entirely dedicated to the long and winding road which is replacing placeholder cubes with actual art assets. This has required me to finally upgrade my 2007 version of the free/open source Blender3D modeling app, to the all new, all singing, all dancing 2018 version. Thankfully, very little has changed in hotkeys, but boy has a lot changed elsewhere - especially animation - all of it for the good.
Last month I discovered - completely by accident - that I could convert FBX models to a more useable DAE/COLLADA format through Visual Studio. The lastest version of Blender (2.78c) also has an FBX importer, though I found it doesn't always import correctly, especially with animations. This seems to be down to the specific type/build/version which the model was exported with in FBX. Some work fine, such as the GarageGames Zombies and Solder content packs at https://github.com/GarageGames/ContentPacks whilst others require saving out as DAE through Visual Studio. Either way, it seems that I have a solution for compatibility.
Original on the left, Blender export on the Right - are you boys related?
Talking of GG's content packs on Github, I got them working with Blender and then exported with animation et al quite nicely. Whilst the basic rigging of the armature/skeleton is similar, there are some differences in the arms between zombies and soldier models, which meant that to get the extra death animations working with the zombie armature required a bit of manual rejigging in Blender's animation system. A quick read through the online manual was enough to bring me up to speed on how modern Blender differs from the 11 year old version I am more accustomed to. Turns out the Animation Action Key Editor was hidden under something called Dope Sheet Editor ... whatever one of those are ...
I decided on 3 types of zombie models, each with 4 different coloured outfits for variation. I also exported my models with seperate head meshes and scripted a decapitation system, as well as a body exploding system to add some extra gore and variation to destroyed enemies. There are 3 different animations for spawning, all of which are crawling out of the ground with 4 different effects for particles and audio. There are differing animations for root, run, sprints and various attacks, all helping to make things visually more interesting.
Testing zombies spawning from underground
So then came dinosaurs .... with frickin' laser beams attached to their heads.
You got dinosaurs instead
I found a rather nice Velociraptor which had full animations to license. It required a bit tweeking for what I wanted. Rather like the GG zombies on github it was highly detailed in bones and my isometric/top-down Swag 'Em Up does not really require all these fingers and knuckles to be clearly visible in animations. I cut down the tail, real velociraptors might have found a massively long tail great for balancing but I thought it just got the way when they turned around in game - halved the tail bones and merged all toes and fingers into single bone per hand/foot whilst reparenting all of the required vertex groups (or else they would be a hell of a mess when the mesh deformed and found it had no parent bone). This removed nearly half the armature and would thus save on overhead in game - something which you should always thing about if you are likely to have "a lot of stuff on screen" - and player's like "stuff".
Dino a-cute!
Like the zombies, I reworked animations to create new spawning and root animations, randomized attack animations and created various different coloured skins (all of which are a bit brighter than the original) to keep everything looking different. Velociraptors are also exported with a seperate head mesh allowing for decapiations and they can completely explode too. One extra thing which I wanted was for the some raptors to have a rather unexpected range attack - literally frickin laser beams. I modified the roar animation to be used to fire an energy beam with a randomized colour from their mouth.
Fricken Laser Beams!
So ... that was a very productive month with plenty of things that are more interesting to show than just me saying "I did some code". Next up I want to make a couple more death animations from scratch for the raptors, and add more obvious magus/liche type character for the zombies with the magic projectile attack, possibly with a Hadouken style attack animation. After that we are on to more enemies of varied and different types ... anyone got a fear of spiders? [cue evil laughter]
FBX is a popular format, mostly because Autodesk have spent the last 100 years ruthlessly (look at how many companies they've bought out over the years) pushing 3DS Max as the industry standard for 3D modeling. This means that a lot of 3D artists use it, which in turn means that a lot commercially licensable models are FBX. Autodesk are well known for jealously guarding the source code of the format like some ancient sacred text - which to be honest, it probably is, as it's made them a fortune and cemented them as the standard format/app for the whole video game industry. This completes the circle of life where they become king of the hill, are anointed with their gold crown, and have peasants throw money at them to use not just their 3D modeling app, but also their propriety format (which they bought off someone else in 2006).
How I imagine Autodesk
This means that they don't let any Tom, Dick or Heinrich have access to import/export code of the format, especially free software like the plebs over at Blender3D (though recently they have partnered with Epic for UE4 integration. Epic wanting UE4 to be the game engine equivelant of 3DS Max - cue KA-CHING sound!). Blender has a lot of things going for it. It's free, it has on going development, it's free, it has a somewhat strange and awkward interface compare to commercial modeling apps, it's free. People can and do write their own import/export scripts in Python (hello whitespace!).
Blender does have an FBX importer on the Blender Wiki, but it mangles the hell out of bone transforms. There is a custom amde importer created by a Blender user which brings through everything correctly ... everything except animations. Not too useful if you've got a shop bought character model and want more than just a static mesh. Autodesk do have a free FBX Viewer and Converter. This sounds great, right up until you export as a COLLADA DAE format (something Blender3D likes) and the resulting file comes out empty. (T-thanks Autodesk). This leaves OBJ format, which again, is just a static mesh, leaving all weight painting, armature, animations, etc behind. And then I discovered a new way which actually works ---- completely by accident. Whilst making a list of enemies for my current Twin Stick Swag 'Em Up, I started going through the models which I already have to see which matched the descriptions of enemies in the list I was making. Now I had previously licensed some shop bought FBX format characters. Having forgotten what they looked like I wanted a quick glance at them in Autodesk Viewer/Converter. So I double clicked the FBX file and was rather annoyed when Visual Studio 2013 booted up instead. As I hovered my mouse in the screen corner ready to close VS, I was somewhat surprised to see the model displaying. I had no idea Visual Studio had a 3D viewer. I checked export options and was intrigued to see "export as DAE" available - so I did, then booted up Blender3D 2.78b and imported the DAE file leaving all import options set to the default off.
And there it was, sitting with correct transforms and rotations, parented correctly via weight paint to the armature skeleton. I pressed right cursor key to cycle through key frames and was ecstatic to see the animation play correctly. The one thing to note is that diffuse and specular for the material default to black rather than white, but that's easy enough to change.
FBX to DAE (via Visual Studio) to Blender3D and Torque3D
So I imported it into Torque3D as a static mesh to see what it looked like in-game, and set up the engine material file. Lo-and-behold it even played the ambient animation correctly. After a bit more quick and dirty testing, I got an AiPlayer character set up - note: the jerky animations are because I didn't bother blending or movement settings for this quick and especially dirty test.
Quick and dirty test - accidentally recorded SpaceX launch audio in background :P
After this success I went off searching for other models to try this FBX-VS-DAE conversion with. There are plenty of free (and usually quite poor quality) models available on the interwebz, but I found this rather nice one at TurboSquid(though it was made of like 20 meshes, each with their own material when surely just 1 or 2 would have sufficed, but hey it's free and looks great).
There you go. Maybe someone else knew that you could get Visual Studio to convert FBX into a Blender3D useable DAE format with correct rotations and full animations, but I haven't found it on the internet - so here it is now! To recap:
Apparently ... as our Western cousins like to say ...
Math Is Hard
And sometimes, it actually is.
I was attempting to redo ... reimagine ... resomethingerother ... my current game's difficulty curve. This proved harder than I was expecting, and resulted in much flagrant use of Post-It Notes(™?).
Here is the issue.
Cash dropped by defeated enemies increases by enemy lifeforce (not to be confused with Lifeforce, the 1980s UK/US collaboration which featured this hot bird with massive ... tracks of land ...
(insert own joke, image or reference here)
This film is severley underrated ... for scifi reasons ... also boobz ...
And back to math ... or as us colonial imperialistic types call it ... MATHS.
I had previously devised (with help of arcane magick, alchemy and winged goblins) a perfectly good manner for AI enemies to have less cash as the player progressed. Here is the CRUX of the issue (somewhat appropriate as it is Easter weekend). The player score points on ANYTHING - especially cash transactions. So limiting the available cash to buy SWAG (powerups) in later levels was good ... but also decreased points which were available to be added to the player score.
So obviously I wanted to reverse the points reduction by letting the AI enemy have a fully score ... whilst increasing the cost of buying SWAG by points x levels x f***knowswot. And f***knowswot became an issue. Much mathematics was done - insert your own doge meme here - nah have this one:
Now you'd kinda expect this to be a simple mathematical reversal ... but that didn't happen. Much toil and even more trouble and three times as much bubble occured (note the reference to prove that I am a psuedo-intellectual). Anyhow, eventually, and after using half the world's supply of Post-It Notes I managed a solution
Like this but way more vacant in the eyes ... also more crying
And so I emerged victorious, after destroying all the world's rainforests in little yellow, sticky papers.
Cost of opening SWAG parcels increased in line with AI enemy's strength. And all was well in the kingdom of ... er ... game dev.
Tune in next month for all that stuff which I promised I would be doing months ago but have still not got round to!
Whilst contemplating unlockables, the obvious ones being the powerups which have to be unlocked, I turned my attention to differing gameplay modes. These things are sometimes called modifiers or mutagens and change an aspect of how the gameplay works. I came up with five ideas which I considered to be a good balance. I thought I might name them along the lines of "Trial By Whatever", as each one is an additional form of challenge. I also thought that it might be a good idea to add a bonus score modifier to each one in use, that way if the player unlocked and chose to enable all five challenges, their score would double - thus giving an added incentive for the player to actual use them. Cue bullet point list! Note, gameplay modifier names are works in progress.
Trial By Fun: Everybody drops FunBalls on death. Previously only bosses and certain enemies would drop FunBalls, but with this modifier every deceased enemy does and the original enemies drop double the amount. Expect more dodging!
Trial By Strength: All attacks, whether by the player or the enemy, do critical damage. This is basically a x3 modifier to damage which makes gameplay much faster and increases the player's own vulnerability.
Trial By Chance: Swag parcels full of powerups no longer spawn, instead there is a small percentage chance (based on the actual game difficulty chosen by the player at the main menu) of an enemy dropping a powerup when they are directly attacked by the player. In the proposed multiplayer co-op mode, this could create a rather amusing situation when everyone suddenly dives in to try and grab the swag for themselves.
Trial By Judgement. All enemies spawn as elites. This means that not only do they have a higher capacity to take damage (somewhat negated if Trial By Strength is also enabled) but also carry a special attack of some sort, which are: radiation attack, player seeking missiles, extra health and damage, speed bonus, electical attack and slow player on touch attack.
Trail By Ordeal. Every 9 minutes or so (not certain of the acutal timings yet) some sort of enemy champion or enemy horde teleport in to harrass the player.
As stated above, unlocking and then enabling each of these challenges adds 20% to the player's score. Enabling them also makes for a much faster and more hectic game as escaping the level becomes much more urgent.
Collecting a swag powerup dropped by an enemy
Speaking of unlockables, characters came to mind. Characters will come with their own statistics and are auto-equipped with their own weapon and evasion ability. Currently I only have one character, running around as placeholder yellow cube with a pistol and fast but short sprint for their evasion ability. Their standard attack is a single light bullet (damage 10) which has a long range (20m+), and their heavy attack (which uses energy the same as their evasion does, so the player has to wait for the recharge before being able to use either again) is a burst of four heavy bullets (damage 20 x4). Whilst tidying the finite state machines which control weapon states up, I noticed an error which had been around since the time the dinosaurs ruled the earth. Heavy attacks use onAltFire as a function call, but I had them set to the standard stateFire rather than stateAlternateFire, which meant that they were inheriting data from the standard attack. This meant that heavy attack was using particles and audio set for light attack rather than their own. Now heavy attack has a deeper, bassier gunshot and a wider spray of gunbarrel particles. I should have noticed this error much sooner.
Creating a new character I decided on "shotgun" as the weapon. This has a standard attack of solid slug (damage 50) which is much slower than the pistol in firing as it has to be cocked with a nice pump-action sound and also has a shorter range (12m). To compensate the damage is much higher. The heavy attack is a close range (5m) scatter shot, which hits all targets within a 90 degree angle (damage 20). The special evade for Shotgun is what I have called a "Ghost Run" - the ability to run through enemies for a few seconds to escape.
"Ghost Run" took some doing, as I had never had cause to go hunting around the collision code which was spread through numerous files of the engine. So what I wanted was to find out where I could extract the collision object's type (eg: AI enemies are derived from Player Class so I only wanted playerObjects) and then make a test against the class on whether this object should be ignored.
Of course it was not that simple ...
A few days and according to Windows Event Viewer, 80 crashes later, I realized that the whole thing was a lot simpler than I had originally envisioned. I created a new customCollisionMask for the Player class which emitted PlayerObjects and then made the test under the Player class's own workingCollisionList. If "Ghost Run" was enabled via a bool flag, and the object was derived from Player class then it used the customCollisionMask to ignore new playerObjects. Another bool flag issued when the state of Ghost Run changed which then renewed the workingCollisionList to remove that playerObject if it had already been added to the list, or readd it to the list if it was the last collision ignored before Ghost Run was deactivated. I felt like a coding god, regardless of having spent the previous week looking in entirely the wrong files.
I should probably read this, but to be honest my style is to make it up as I go ...
So now I had a working second character. Apart from obvious difference such as attacks and abilities I decided that characters should also have a unique strength attribute when colliding with enemies (or other players). This would be useful for barging their way past opponents. Strength should be relative to their own suited range, thus long range based characters would have a low value whilst short ranged, melee based characters would be high.
Shotgun is a medium ranged character so can push similar sized enemies around by banging into them. Pistol is a long range based character so now finds it difficult to physcially move enemies and is much more vulnerable to get swarmed at close range. However Pistol has a sprint evasion which quadruples speed and triples the force of pushing enemies, though this only lasts for a couple of seconds as energy drains away.
Shotgun in action, with Gradius Style Option/Follower trailing behind
I also started thinking more about the overall look of the player's screen and HUD, and how to display information best with text. Thus began the GREAT FONT HUNT! If there is one thing which can be equated to slogging through an parched wasteland of spikey rocks, it's trying to find fonts for your game. I have a preference for condensed fonts, I think they look elegant, but elegant and easily readable with a quick glance are not always the same thing.
This looked great until I added it the actual HUD ...
There's thin and difficult to read and then there is this ...
Yeah, but no but really no ...
Argh my eyes ...
One of the great problems with staring at millions of fonts is that they all end up looking the same. Currently I have this below, but found that the numbers are a little too close together. Using a font editor I managed to give them a little bit more spacing. Cue the first image in this blog being reused.
Hello it's the first image in this blog again
So that's progress. Next up are to make more characters with various abilities and give them a thorough testing for balance. After that come up with a definitive list of enemies and environments for levels, and then hopefully finally start on some model designs to chip away at all these placeholder cubes. Also somewhere on the horizon is ditching DirectX 9.0c and updating to Physical Based Rendering ... whatever the hell that is ...