Sunday, October 25, 2015

More rambling

Just a quick update to give an idea of where we are with the demo (aka, how much we've procrastinated.) Also, this blog itself is a form of procrastination in that I can avoid programming for a little bit. Despite how fun it is, it can get tiring. Anyhow, here are some of the tasks that we have been working on during the last few weeks (look, I even gave each task a header... gettin' fancy):


MOLSHA SCENE REFINEMENTS

As is often the case with uh... well, everything, a lot of refinements/visual updates are completely serendipitous. Andy and I get to looking at something in this particular scene, decide that we don't like the way something looks and then two hours later, somehow the entire scene is improved. In this particular instance (one of many), something as simple as changing the skybox (a skybox is exactly what it sounds like... a big set of pictures that wrap around the sky in a scene in a particular way) can drastically change the entire mood of a scene.

I would say something really nice about some of the 'terrain' used in Molsha (for the park areas, as well as some of the areas around the mines), but Andy somehow managed to delete a large portion of it. Then again, if I came across an asset named "New Terrain 9", I probably would've deleted the shit out of it too. So it goes.

We were wanting to have three connected 'scenes' for Molsha, but decided on settling for two after realizing that the demo will already be quite long (assuming the player is interested in fighting the different enemies scattered throughout... and finding the various things that we have hidden). This also gives us more time to focus on the way two specific scenes look/play without spending a bunch of time trying to tune three scenes. Still a two-man team, after all.

FOOTSTEPS

When people walk, sounds happen. Since our game is a 100% accurate representation of reality (with giant roots and shit), we decided that we'd need some footsteps too. There are a bunch of ways of going about adding footsteps, but really, all one needs to know are the particular moments when a given foot hits the ground.

Since this is such a small, but important task, we figured we'd spend a few bucks on a Unity asset to basically do this for us. Literally, thing cost two bucks. Anyhow, it didn't really work: couldn't handle variable speed characters (which is completely worthless), nor could it handle blend trees (again, completely worthless). For two bucks, I'm not sure what I expected.

Anyhow, we ended up doing this ourselves. For anyone interested, here is how we did it:


This graph represents the xyz coordinates of Bodom's right foot as he runs. The blue line represents the vertical position of his foot and as such, is the only thing we're really interested in here. As you can see, there is a low point and a high point. Basically, Unity (being the little darling that it is) allows you to add 'Animation Events' at particular points in an animation. What this means is that you can trigger a function to be called whenever a desired event occurs. In this case, every time the blue line is at its lowest point, we know that his right foot should be hitting the ground. We then call a 'Footstep' function that we implemented, and we can additionally pass it the foot that 'stepped on the ground'. This function then casts a ray downwards to determine what it actually hit--from there, it can play the appropriate sound depending on the surface. We do the same thing with the other foot. The best part about this method is that the graph above will effectively be scaled depending on the speed that the character is moving, ie, it doesn't matter whether he walks or runs.

The only real downsides to this method are that a.) it requires manually setting up each animation and b.) it only works for bipedal characters at the moment. Both of these can be dealt with by automatically determining the lowest points in code (contrast with having to do this by hand) and altering the function to handle an arbitrary number of feet/contact points, respectively. For now though, it works well enough.


SOUND EFFECTS

Since we're on the topic of footsteps, we additionally added a few mechanisms to allow skills/attacks/other interactable objects to trigger sound effects. This was not difficult by any means... however, finding appropriate sound effects was a different story altogether. As it turns out, there are a lot of free sounds out there. Like... a mind-boggling amount. And 99% of them are utter shit. Seriously, pretty sure people put sounds on there specifically to troll indie game developers. Then you have to wade through the licenses... and trim the songs... and change the volume... and add fade ins/outs... and sync the sounds with the animations... very tedious.

Somehow though, after searching for a few days, I managed to find decent sound effects for literally every action in the game. Admittedly, some of them are weaker than others (who knew that sound quality consistency would matter so much?) But by god, they are in there and they already add a huge amount to the overall game.


MUSIC

For the demo, we have decided on two (possibly three songs) songs that are an absolute necessity. Battle music, boss battle music, and possibly a battle victory song. For the actual background music of Molsha, we found a nice ambient loop that works insanely well without needing dedicated music, per se. Which leaves these battle themes as the sole remaining musical... uh... issues. If you know anything about me, I am one picky motherfucker when it comes to music. Unfortunately, with only a few weeks left, it's not like we have the time/money/expertise to develop/acquire the kind of music that I would want... thus, to the Unity asset store we go. Don't expect any miracles here... after a cursory glance, it looks like the offerings are brass, brass and more brass. And some percussion. Then brass. So yeah...

DEMO AVAILABILITY

After a bit of dicking around (technical term), we figured out how to build a (WINDOWS!) installer for the game. This was not exactly as easy as I expected it to be (long story short, it seems that Unity does not put assets contained in the "Resources" folder into the "sharedassets" file it generates. The solution was to manually place these ourselves... are... are you asleep?)

Since we obviously have to have the demo finished for the conference (or not, might just get drunk instead), we plan on releasing this to any who are interested as well... at some point. We'll probably have more information on this later, but if you are someone who wants to try the game out (and provide feedback, of course), please let us know via a comment/direct message. We'll try to have this available ASAP (if not before the conference, then shortly thereafter). Presently, we have only tried this demo on exactly two computers... I expect that we'll find a lot of fun shit out whenever multiple people attempt to install this thing on their various desktops/laptops/lawnmowers.


LINGERING ISSUES/BUGS

"None. Zero. No lingering issues or bugs. Application runs flawlessly and at 60 frames per second. Always."
-Said no programmer ever

There are a few notable issues--we still need to add a way to essentially 'reset' the game once a particular person has played through the demo. (ALT+F4, then re-running the application is not an acceptable solution) This will not be difficult--just tedious.

AI issues: occasionally, an enemy character will walk directly up to an ally and then proceed to do absolutely nothing. Not sure what this is about...

Interactable objects do not currently persist throughout scene loads--what this means is that if you open a chest, unlock a gate, trigger a cutscene, and then go to another scene, you can then return to the previous scene and re-trigger all of those things again. We already have this working for enemies--ie, if you kill an enemy then go to another scene, then return, that particular enemy will continue to be gone until its spawn timer resets. Thus, we have the framework in place--we just haven't implemented it for interactable objects.

Dialogue: need to spice up some of the exchanges between characters so that the player has some idea of what they are actually doing in the demo. Currently, they just look at each other and grunt. In the original game, the overt purpose of going to Molsha is to essentially survey the damage and look for survivors. (Spoiler: there aren't any) In the demo, however, the goal is to find and defeat the boss of that particular area. While this won't vary dramatically from the overall game, it would be nice to have the dialogue/cutscenes/exposition set up as similarly to the real game as possible.

UI: Multiple revisions have inevitably broken the main menu. Andy is currently whipping it back into shape, but it'll still be pretty bare-bones; the character will have access to the "Status" and "Items" subpanels but we are not sure if we'll have equipment switching implemented by the time the demo rolls around.

Framerate: Honestly, this deserves its own blog post. Maintaining a consistent framerate is probably the most fundamentally important thing that tends to get overlooked. Until it's too late. This is for good reason: because it's a bitch to figure out.

As an example, that song that one dude wrote about having 99 problems (but a bitch ain't one) is actually about maintaining a consistent frame rate for the games he develops in his spare time. If you pay close enough attention to the lyrics, it's obvious that he's talking about overclocking/vertical syncing/different shader profiles and so on. I can relate.

Saturday, October 10, 2015

Ramblings

With OGDE just a few weeks away, I am disappointed to say that we have had to resort to various amphetamines and (game) designer drugs to keep up with the cruel and unusual deadlines set by our boss, Kitler. Yes, our boss is a cat. And let's be honest here, everyone's boss is a cat, even if you do not own a cat.

That is what the update would say, anyhow, if we weren't massively ahead of schedule on pretty much everything. Seriously. Send me the cat a check for $99 and you can have a copy of the completed game. It will crash probably within the first five or so minutes, but Windows charges much more than that to crash for you, so I'd say it's a good deal overall.

All right, maybe we're not THAT close to being finished overall, but the demo is pretty solid at this point. To recap, here are the tasks we mentioned in the previous update:

-Tie up any loose ends regarding UI stuff (DONE)
-Add "Battle Finished" screen displaying EXP, benefits, et cetera (DONE)
-Fine tune Molsha cutscenes (MOSTLY DONE)
-Add final Molsha area (MOSTLY DONE)
-Populate Molsha scenes with enemy spawns/loot drops (YES)
-Add some kind of rudimentary enemy AI (OH BABY--more on this later)
-Sound effects/music (uh... hey, what's that over there??! *points and runs away*)
-Fix lingering issues with character animations/riggings/timings/et cetera (MOSTLY DONE)

And who can forget the most important task of all? (per our master task list):

-??? (DONE)

And really, there are a bunch of other things that got added and completed, but I am far too lazy to list them all out. And it would be boring as hell: "Added code to enable NavMesh agents for acting battle characters while enabling NavMesh obstacles for" See? Boring. So boring that I couldn't even finish the sentence.

Of the tasks listed above, many of them do not need any further clarification. In fact, for the first time ever, I think we can say we are confident enough in some of that shit to not even need to re-do it in the future (or so we say).

If you have read these updates consistently, you'll notice that we refer to AI quite often. For those who do not know, AI stands for artificial intelligence. In this case, it relates specifically to the artificial intelligence of enemies during battle. Up until very recently, the game was setup in such a way that the player controlled both the allies and enemies. While this is kinda cool (and EXTREMELY useful for debugging/testing/et cetera) it does not make for very compelling gameplay.

At some point, we knew that we would need to add AI for the enemies so that they would act independently in battle and ideally, one day, actually present a challenge to the player by acting intelligently. We also decided (correctly, it seems) that AI would be the most difficult task, by far, if for no other reason than the fact that there is no real metric for determining when we have finished that specific task. In other words, there are probably an infinite number of things we could do to increase the 'intelligence' of enemies. OK, it's probably not infinite, but the more mathematical term 'shitload' definitely applies here.

So, the first question is, "what do the enemies even need to do to act intelligently?" Seriously, someone help us. This is not a rhetorical question.

I guess the keyword in all of this this is 'rudimentary' and boy is it ever! The current AI system took just a few days to implement, which is all the proof one needs of its rudimentaritynessosity. It's pretty simple:

-Enemy has a turn
-Enemy finds all allies in range that it could attack
-Game assigns equal probability to all characters (except Apolith, who can modify his probability by taunting enemies)
-Enemy randomly chooses ally within range to attack
-Game assigns equal probability to all enemy skills that could be used (barring range limitations, SP costs, et cetera)
-Enemy randomly chooses skill to use on ally
-If enemy has no allies in range that it could attack, it moves somewhere towards a random ally and repeats the above steps. If there are still no targets, the enemy's turn ends.

That's pretty much it. Nice and easy. The main thing is that it does present somewhat of a challenge to the player. But it's also really bad when it comes down to it, because the challenge in this case is not because the enemies are intelligent, but because their attributes are overtuned. Seriously, there are so many improvements that could be made, it's sickening.

So why even do it this way if it's going to eventually be scrapped? Well, for starters, we don't have a whole lot of time. It would be very easy to go down a rabbit hole that results in the AI being improved in some ways and broken in others, which is not the kind of situation we would want to be in for a live demo. The last thing we want is an enemy launching itself into the ionosphere in lieu of choosing an ability (yes, this happened once. No, I don't know why. Some folks say dude is still up there...)

Another reason is that this is kind of a test drive, if you will. Some programmers (although none of the ones I know) like to intricately plan out the details of what they are about to code. And then they get in there and realize that most of the things they had assumed are not true at all and that there are all sorts of interesting things that they did not account for.

Personally, I like to just run full force at the problem until I get a concussion. After I sleep it off, I like to run at it again and again until both the problem and brain tissue disappear entirely. In this case, the problem is pretty big, but it's easy enough to tear off a chunk (which is the rudimentary part) and just beat the ever-loving shit out of it.

Mainly, it's a learning process. We figure out very quickly which things will work and which things are not worth the time. Again, it's one thing to spend a bunch of time planning out how/where to move an enemy, but if I can't even get the pathfinding to work properly, I just wasted a bunch of time for no reason. No amount of planning is going to tell me that I need to call certain functions in a certain order, only experimentation.

But this does not mean that we have not thought about the AI extensively and it doesn't mean that planning is bad. The better approach, when we get around to it, would actually be to exhaustively simulate and test all possible enemy moves and actions, which is sort of how a chess AI works, but not really at all.

This should not be hard to compute really, since there are only so many combatants in a battle and so many actions that each combatant can take. Essentially, an enemy would put all of these actions in a list and then evaluate them according to some metric. The tricky part would be figuring out these so-called metrics, or, in other words, how 'good' a particular course of action is.

As an example, one metric could be damage maximization. Another could be target vicinity. Another could be whether the ability hits multiple targets. Any of these things, if fulfilled, would add a small weighting to that particular action. Some actions would probably just be complete shit and would be able to be pruned and discarded immediately. Certain ones, however, would have higher scores than others. These scores could be probabilities themselves or they could be absolute values, ie, always perform the action with the highest score.

The truly complicated part of this would be considering the actions of other combatants as well as well as future actions. For instance, suppose an enemy moved to a particular area and decided that there were no targets there at that spot. However, in two turns, imagine that another enemy kicks the ally into range of that particular enemy. Even better if the particular ally were critically injured at that point and would only require a single attack from the acting enemy--except that the acting enemy would actually need to plan out his action based on what will happen in the next few turns. And there are a million potential situations like this.

The main takeaway though is that

a.) basic AI was much easier to implement than I thought, but is implemented nonetheless
b.) better AI is much harder to implement but will have to be put on the back-burner
c.) Kitler is a bitch

Oh yeah, those other tasks... we did manage to improve Bodom's rigging and animations quite a bit. If there is one mistake we made, it was forking over the money for Bodom's character model (we're not going to talk about how much it cost, but just know that I will require a dialysis machine for the rest of my life).

Basically, we got a little impulsive. The character model itself has a few uh... imperfections (and a face only a mother could love... if the mother was blind) and was not actually rigged. We figured, hey, we can rig this ourselves or use an online utility... but we were wrong. (Rigging is the act of actually adding a 'skeleton' to the character so that it can be animated).

Thanks to some alterations to the model, we were able to get a decent rigging as well as find animations that don't look absolutely ridiculous on this character. (I swear the dude's knees and ankles are in the same place, but hey... what can ya do).

Many new particle effects have been added as well and there are only a few skills that are still lacking them. This is pretty low-priority as there are no real 'catches' when it comes to particle systems. Just gotta sit down and randomly change shit until something good pops out.

As for the sound/music... we don't talk about that. Just know that the Bevontule soundtrack will be the first release ever in the genre of "Ethnic Ambient Beatboxing/Whistling"

Bye bye.