Friday, 20 April 2018

How To Import FBX Into Blender3D Using Visual Studio

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:
  1. Load FBX file into Visual Studio
  2. Save as DAE (COLLADA)
  3. And that's it, loads perfectly into Blender3D

Saturday, 31 March 2018

Math Is Hard

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!

That stuff I said I was going to do next

Wednesday, 21 February 2018

New GamePlay Modes, New Weapons, New Fonts, New Stuff

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.
  1. 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!
  2. 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.
  3. 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.
  4. 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.
  5. 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 ...

Saturday, 27 January 2018

Welcome To Space Year 2018 - Now With More Catgirls And FunBalls

We are so into the future, and it is only another 2 years until the Tokyo Olympics. I can't wait.

Soon ... (ish)

And so to the New Year, which began with great productivity (once the hangover wore off) and "Dry January" commenced. More on that later.

First up was going back over some old ground and changing things ... which to be honest, appears to be 90% of what consumes my development time. I had used a small number of open source/creative commons/CC0/CC-BY images. I ended up stripping these out and replacing them with custom imagery. The most used one was of a cat, which was changed to be a tiger.


I dropped the sole icon I was using from http://game-icons.net/ (a really useful resource) and replaced it with my own custom one. This had been for the "Tough Skin" powerup, which during playtesting I had thought was underpowered for a rare item and so doubled the amount of damage it stopped from 10 to 20 percent.

 
"Tough Skin" Rare Powerup, Now With Less Gauntlet And More Catgirl 

The overall layout of the player's interface/HUD went through another iteration, and a skull was added to the kill/gore gauge which fills up and changes colour until it completes level 4 and a Momento Mori is triggered. Upon this the player becomes invincible for 60 seconds and scoring multiplies by 8  (that's the old 4/8, death/wealth for the Far East), and all attacks now deal critical damage to enemies.

 Object which mounts to the player to signify that the Momento Mori has been activated, and they are now Shinigami, God of Death.

Kinda like this guy but you have to make your own atatatatatatatata sound

I also altered the textures for the Gradius style followers which can be picked up and upgraded via powerups, giving them each a little sheen which passes over them. They are little weapon platforms which follow the player around and increase firepower. I spent a while in the depths of C++ changing their start/stop movement to make them move much smoother than they had before.

I am most proud about getting this gif to loop seamlessly :P

One thing I noticed about collecting offensive and defensive powerups is that there could be a disconnect between the information displayed to the player and what the actual effect is. This is because special attack and defend abilities are triggered using an RNG. The more abilities the player has, the greater chance of an activation. However this doesn't mean that the last powerup will trigger next, so I changed that so that it always triggers on the next attack or defence - thus giving the player a clear idea of the ability of the object which they just picked up.

Collect "Magic Bullet" offensive powerup, immediately see it used on your next attack

And so onto FUNBALLS. If the esoteric words "RoR, /v/, Git Gud and Host When?" mean anything to you, then this should give an inclining as to what comes next.

This is a FunBall. You can tell it's a FunBall due to the word "FUN" written on it and it's murderous grin 

FunBalls are fun - okay, they're not really, they're bombs which some enemies will drop. I also intend to create an unlockable challenge mode when everything will drop FunBalls upon death.

I am using a slightly basic collision and physics system (hello rigidBody) for speed and convenience. FunBalls didn't look very good as standard objects due to sudden rotation changes when they bounced. To combat this I made the object a billboard so that it always faces the camera and used a scrolling texture to give the illusion of smooth, spinning movement. I then created four variations, leaving one central and rotating the others (off-left, off-right and upside down) so that when a number of FunBalls burst from a deceased enemy, they have plenty of variation but the player can always see the grin at some angle.


FunBalls in action! Audio has since been changed.

And upon all of this, there have been numerous little tweaks and changes to how things work, as well as much planning on the data of enemy types as the levels progress (though everyone is still a placeholder cube right now).

Did I mention "Dry January"? My performance at darts really suffered so halfway through the month this kinda happened ... 


Next up, more sorting out data and attack types for enemies, and some considerable reading up on this new fangled thing called PBR.