TACStrike: weeks of May 25th - June 14th

Published on Monday, 15 June 2015 11:10
Written by snake5

Bullet hit effects, icon fonts, AI - the direction of work in these three weeks. Well, not exactly three weeks, some side projects just had to bump into my schedule and I didn't feel like posting half a blog post in the previous week. To try and make up for this gap, here's a video:

Now, moving on to the details.


Bullet hit effects

So I was working on particles a few months ago and decals/bullets about a month ago, and it was time to put it together.


It's still missing some smoke and stuff flying around but it's nothing that couldn't be fixed in an hour with the particle system editor. Main goal now was to just put the whole thing together so that it would look somewhat nice. I think that's already achieved.


Icon fonts

For when you want cheap & easy scalable graphics and a way to edit those.



  • the quite awesome Nano SVG library
  • a bit of refactoring to support multiple types of fonts

The reason for using the font system instead of being more generic and more low-level is quite simply the need to put icons between words. It's not that hard to do it yourself but... you still have to do it. This way, I don't, which makes it easier to communicate with the player.

It's also a great way to avoid the issues I had with my last 3rd person action/adventure demo where people couldn't see that "[Button 1]" didn't read "Button 11" (because in a certain distance that is >0.5m away from the screen it's actually very hard to see that). So basically, some solid rules for UX:

  • less (data to read) is more (effective communication)
  • prefer colors and basic shapes to text and symbols and especially avoid text with symbols mixed in

Anyway, the new icon rendering system is missing a couple of tweaks but is generally readable, which is just the most important thing.


AI - coroutines

One of the few core libraries I've written, SGScript, was missing this feature that I found rather important after reading an article on behavior trees.

It dawned on me that it was actually very possible to model behavior trees with just lots of boolean-returning functions running in another thread. For example, a sequence (runs each child node in order and returns if either fails) - is simply a sequence of functions with "&&" (logical AND operator) used as a separator. Selector - "||" (logical OR operator). Inverter would be the equivalent of "!" (logical NOT operator). Needless to say, this makes data-driving the implementation very easy, given proper tools.

By the way, the proper tools are coroutines - a lightweight replacement for threads. Since we don't require true parallellism and are fine with poking them regularly to get results, this appears to be a rather good choice.

At that point I did not have coroutines. But for three reasons I decided to implement them:

  • I've always wanted SGScript to be competitive and that meant having coroutines eventually
  • I finally understood the need and usage for coroutines and was determined enough to figure out a plan for implementing them
  • I quite simply needed them to be there and using another library was out of the question (because they suck just that much)

In a few days, the implementation was done and there was much rejoicing. A few days ago I had found and fixed two bugs and everything seems to work fine now.

Except just one thing - serialization. I'm not quite sure how to approach that issue yet but there's no reason not to be able to create a solution that works at least for this one project.


AI - navigation mesh

a.k.a. "Walkable Space: Redefined"


Looks a bit strange but it's still great. Using Recast/Detour is easier than writing a library from scratch, even if I've done something similar before. The Y-up axis thing was a bit disconcerting but it's nothing I couldn't handle with some wrapper functions.

But, of course, navigation mesh is quite useless without pathfinding itself so that was implemented as well (the red line shows a test path):


A little side-story: the lighting was changed as a test after one bugfix. That darkening towards the upper edge of walls - that's a bug and it's actually darkening towards light height. The normals on the level mesh were miscalculated, which led to this awkward darkening and general lack of proper lighting.

Since there's not much else to say about navigation, let's move on.



The beginning of an enemy agent.


I've taught it to run in circles. You can see it in the video. Not much but it's a start. What's more, I've developed the framework upon which to build further behaviors. The framework's not big and that's kind of the point. It needn't be big to allow me to do big things.

Also, I think I understand what to put at the core of AI behaviors - a loop that contains just two functions - "patrol" and "attack". Under "patrol", there would be following a predefined path as well as investigation for possible threats. And "attack" could include firefights and pursuits.

There's a few subsystems that need to be done before getting into detail here but you can rest assured that AI is my next and most important goal at this point.



Moving towards aiming direction for a better view...


...and not only that, there is a need for a bit of cinematic effects and camera is one of the basic elements of cinematic. I'm probably going to make this effect smoother, smaller by default and more configurable but I generally like it. It creates a hint of chaos, the inexact and uncertain nature of the world at any point in time, and that you have the power to control it, to use it for your benefit.


All in all, these three weeks have been full of distractions and full of very important work. I do hope though that this month is one full of small victories, and a bigger one in the end. The core gameplay is my next goal.


Latest images