New game project: FIPTUBAT

About a year ago, I screwed up the boot loader on my computer, which put a crimp in my development work. While trying to fix that, I spent a lot of time watching Christoper Odd’s XCOM 2 playthroughs, and it eventually lead to a new game project. I’ve been working on this since May.

The idea I had was to try doing a turn-based tactics game (such as XCOM, Jagged Alliance or Silent Storm) from a first-person perspective, i.e. from the perspective of the units themselves. This has lead to a few interesting design implications around player units in particular:

  • Should player units be allowed to look around without costing action points?
  • How should aiming work? Should it be freeform like in a first-person shooter, or should the player choose from a list of existing targets?
  • Should player units be allowed to move at all without costing action points (e.g. stepping in/out of cover)?

It’s currently a WebGL prototype, available here. There’s no screenshots yet, but the general turn-based mechanism, combat and objectives are functional.

New project: The Phisher’s Gauntlet

I’ve decided to do a spinoff version of Spamocalypse for my next project. It’s based around an enemy I wanted to add, but had no time for beyond an off-hand joke: Phishers.

Summary

For anyone who doesn’t known, phishing involves misrepresentating a site or other trusted entity to steal personal information (login details, financial information – anything!). OWASP have a definition and examples here. Generally, if you get an email asking you to sign into your account…delete it.

Now I have that out of the way, the game I have in mind is currently titled “The Phishers’ Gauntlet”. The idea is that the player is cut off when a city is evacuated in the face of a invasion by the Word of Turscar, and forced to make their way through the Phisher-infested alleyways to a ROFLcopter that is waiting. The Phishers, an offshoot of the Turscarites, will either lurk on top of rooftops and wait for something to hit their Phishing Rods, or stalk the player on the ground.

Comparison with Spamocalypse

A lot of this will be taken from Spamocalypse, but there will be a few differences:

  • More player characters (see below)
  • Combat will be more of an option
  • No loot, though I may bring in notes again
  • Time limits. If you don’t get to the ROLFcopter in time, you will be left behind

Player Characters

In Spamocalypse, I had only one player character – an expy of Garrett from the Thief games. This time, I have at least three in mind. Two of these are parodies of some IT security people I tend to read.

  • Roy Thunt, the combat expert. A parody of security researcher Troy Hunt, portrayed as a Crocodile Dundee-style hunter.
  • Bryan Krabs, the stealth expert. Spoofing Brian Krebs, an investigative journalist who specialises in IT security.
  • Ardino Enube, a random person in over their head. I’ll probably do them first

I heartily recommend reading the people I’m spoofing. Troy is a security researcher who runs the database breach notification site HaveIBeenPwned, and does a lot of security training for developers. He has a fair amount of information about data breaches, password management, and general web security. I’ve developed an interest in that in my day job, but he’s quite readable, so worth reading even if you aren’t very technical.
Brian is a journalist who, among other things like reporting on malware like Stuxnet and Mirai and investigating spam networks, once managed to foil a plot to frame him for possessing heroin…by lurking on the forums where the plot was being hatched. It reminds me of a certain level in the original Thief, where you rob a crime lord who just ordered a (failed) hit on Garrett…

I’m planning to give myself a year to develop this, starting from next Saturday. I have a very rough game design document done (available here).

New projects

I haven’t worked on anything major since I finished Spamocalypse – I just needed a break, and work has been burning me out a little in the meantime. However, I’ve started working on two new projects, trying to decide which I like more. One is best described as a smaller-scale version of Hearts of Iron, and the other is a real-time tactics game. Both are set in a fictional world I’ve had kicking around my head for a few years now.

The world
The original premise of this world is that some hills in my part of Ireland were once inhabited by dwarves, or humans who started living underground during the Iron Age. However, during the mid 19th Century, something goes wrong, and the whole area turns into a S.T.A.L.K.E.R.-style forbidden zone. Among the many, many things that have changed is that humans in the affected area have turned into orcs (AKA Fomorians…or trolls).
Galway is controlled by the Anglo-French Empire, the result of the British and French forming a military, then political alliance in the face of the Habsburgs of Spain/Austria forming a superpower. The Firtollán League, the alliance of the dwarven city states of Ireland, has been forced to ask them for help in keeping the Fomorians locked up in the peninsula.

HOI-style
The first one (Governor) player is the recently appointed governor of Galway, some time around the turn of the 19th/20th century. After a long, distinguished career in the Anglo-French colonial administration, Galway is your final posting before retirement. But can you last that long? All you have to do is approve various budget decisions, and try to avoid being sacked.
This would be based on managing several different factors: your popularity with the locals, the opinion of the press outside Galway, what the dwarves/Firtollan League thinks of you, your budget and your troops. The first three influence what your superiors think of you; if that becomes too low, you will be sacked, forced to resign or…forced to face a Full Independent Inquiry!

Tactics game
I was originally going to do a turn-based tactics game in the style of Jagged Alliance 2 or XCOM, but I’ve changed this to a real-time version. The only definite part is that it will build on what I learned from Spamocalypse – in particular, planning out systems so I can test more efficiently, using mock components. However, it will probably focus on hunting various monsters, including the Fomorians. I’m leaning more towards this one, purely because I can recycle some of my previous AI code.

So, it’s taken me three months to write this. I should probably decide on one of these and get on with it 🙂

Spamocalypse Postmortem

So, I finally released Spamocalypse last week, after two years of working at it in my free time. Now is as good a time as any to look back and see what went well, what didn’t, and what I would do differently.

Original plan
There were three goals I set myself when I started. The first (LOS) was to figure out how to make the bots see the player, while taking lighting into account. The second (Sound) was to figure out how to make them hear the player, and the third (Brain) was to find a way to make different NPC types react differently to specific stimuli. All of these have actually been achieved, though not without some work.

LOS
My original method for determining if the bots could see the player was to use an extruded box for their vision range, and storing the lighting inside a customised pathfinding system. It worked at first, but there were two problems: twenty or more MeshColliders in a scene for line-of-sight checks is expensive, and converting the player’s position into a Node consistently took about four milliseconds, which slowed the main thread down enough to be noticeable.
My fixes for these were to use capsule colliders for the humanoid NPCs, and to create a physics-based light calculation mechanism. Capsule colliders involve only two distance checks (one for the radius and one for the height), as opposed to the eight required by the extruded box (one for each vertex). The physics-based LightRadius mechanism is based mainly off trigger colliders and raycasting, which is considerably faster.
This did require ripping out my pathfinding code and converting the AI to use Unity’s builtin NavMesh. However, that works a lot better, so I probably should have done that from the start.

Sound
The sound detection originally used an octagonal mesh to manage their hearing range. I made their ability to detect the player be inversely proportional to distance, giving the player a chance to avoid them at longer distances. That part has not changed. I also originally made them only react to Sockpuppets, but when I started adding other alert sounds, I realised that a ScriptableObject was the ideal way to store these. From that alone, I’ve learned how to use Unity’s ScriptableObjects for holding common data.
The one major performance change I made was to not use OnTriggerStay for processing sound events. OnTriggerStay runs on the physics timestep, which by default is every 50th of a second. However, I found it ran much better if I ran it on a Coroutine every 5th of a second.

Brain
Originally, I used a C# delegate to distinguish between the different AI responses. Delegates in C# are a way to call a different implementation of a method at run time; in this case, each NPC type had a different search and attack method. However, this became a bit too convoluted when I started adding different effects: the bots were supposed to play smoke when moving, the spammers are supposed to vomit when attacking, and so on.
Currently, moderators and bots are subclasses of the main SpammerFSM class. The only difference here is that their search and attack methods override the search and attack methods in the SpammerFSM, allowing me to subtly change how they react to a sockpuppet, or when they start attacking. However, it’s still a bit clunky. I think that for my next project, I’ll use interfaces instead, which should allow me to customise the NPC types more effectively.

What worked
So, apart from the three goals I set myself, what worked? Well, I found a more efficient way to calculate light intensity. I figured out a basic way of doing player objectives, and I found some basic mechanisms for making it clear that the player can interact with something. All of these are going to be useful in future projects.

What didn’t
The biggest problem is that I had too much scope creep. I kept thinking of new ideas to add in, each of which added their own bugs. The project just became too damn complicated for me to test by myself. Which leads me into the next problem: I have a problem getting people to try it. I hate nagging people, so I tend to just announce projects and see if anyone plays it. I still don’t know if the Mac build works! (That said, the analytics on GameJolt tell me that I’ve had 3 downloads out of 23, with no complaints…)

What can I do about this
The first thing I could try is to scope things better, i.e. decide what I’m actually going to do. That’s something that will probably come with practice. I deliberately refused to give myself any deadlines, mainly because my day job has some pretty unrealistic tight ones, but I may have to consider this.
Another, more concrete thing would be to try decoupling the systems. For example, the SpammerFSM class and its subclasses rely on the LevelManager class – but that has to include objectives for a level, which makes testing the AI in isolation tricky. A way around this would be do what I did for the light calculation: create an interface that defines what methods the class will have. The key thing here is that any class that implements it will include those methods, but the exact details will vary.
I’m also thinking of setting up my own Git server for source control. Source control is basically a way of keeping track of who changed which line of code, and when. In particular, that would have been very handy for figuring out when and how I made the NPCs deaf for over a month! I do have some stuff on GitHub, but I’d prefer to keep my full projects private for now.

So, there’s some things I can improve, but I’d say this was pretty successful overall. Not least because I actually finished it!

Spamocalypse 0.7.2: NPCs aren’t deaf any more

I am an eejit. While trying to fix the performance issues a month ago, I think I broke the spammers’ sound detection. However, I didn’t realise this until I tried making them go on alert if they heard a SQL round miss. I’m not even sure if that’s when it happened!

The root cause of this bug is that I had converted their sound detection to use a Coroutine with a 0.2-second interval, rather than OnTriggerStay. OnTriggerStay runs on the physics timestmp, which by default is 50 times a second – which is a bit more intensive than I wanted. However, when converting it, I forgot to actually make it run more than once! So, the spammers were effectively deaf, which pretty much defeated the point of the game.

Another thing that was broken was their Sockpuppet detection. This was a physics issue – I had set the Spammer layer to ignore collisions with the Decoy layer. However, that’s the layer which is supposed to contain the Sockpuppets!

There are two things that would have helped with this:

  • Automated testing. I might have noticed this if I had a dedicated scene where I can set some bots to detect and attack things in a controlled setting. This
  • Source control. Why should I try remembering what I changed last week when the computer has a record of that for me? I have some familiarity with Git in my day job.

Optimising Unity

For the last three or four weeks, I’ve been trying to fix several performance issues I found while testing. Some of these are graphics issues, which I can’t really fix myself, but the scripting ones are things I can work on. Some of these come from an interesting thread on the Unity forums – which is definitely worth a read. Anyway, here’s the changes.

Removing concave colliders
Concave colliders in Unity are Mesh Colliders that don’t have the “Convex” button checked, and they’re discouraged because they’re quite expensive. In quite a few cases, it is possible to decompose the mesh into primitives, and Unity themselves recommend using compound colliders where possible. I admit, I’ve been guilty of doing this for Spamocalypse – a lot of the scenery is built using Mesh Colliders, though I have been careful to mark these as static to try and offset this, and I’ve been breaking some of them down into separate parts. As it stands, I had to replace the octagonal sound detection meshes with capsule colliders to get the physics cost down when I had at least ten active NPCs in the scene.

Splitting the second level
I ran into a massive problem building the lighting with the second level, mainly due to Unity’s global illumination having a problem with large scenes. There is a way around that, which is to temporarily scale the level down to about 1% of its original size, but I also had a problem with generating the navigation mesh. So, I’ve split part of the second level into a third, which the player will enter via a sewer pipe. This means I’ve had to add more scenery and things to find…which I had planned anyway! So, win-win.

Profiling the build
Normally, you’d test the game in the Editor. The problem is, testing in the Editor includes some extra overhead, so the profiler won’t necessarily be accurate. So, the best thing to do is to profile the final build. The documentation is a great starting point, especially the part about manually profiling segments of code using “Profiler.BeginSample” and “Profiler.EndSample”. Here’s a quick example:


float calculateDistance(Vector3 firstPosition, Vector3 secondPosition)
{
Profiler.BeginSample("getSum");
float distance = Vector3.Distance(firstPosition, secondPosition);
Profiler.EndSample();
return distance;
}

Doing so has uncovered several time sinks in my pathfinding code: the method to translate a position into a node was taking about 5 milliseconds. This is due to my (over-)reliance on Linq to search for nodes: using an Aggregate query on a nav mesh of about 10000 nodes is going to impact performance! So, what I did was change the following:

Node theNode;
if (nodes.ContainsKey(requestPos))
{
theNode = nodes[requestPos];
}
else
{
theNode = nodes.Values.Aggregate((d, n) => Vector3.Distance(d.position, requestPos) <
Vector3.Distance(n.position, requestPos) ? d : n );
}

to round the position to one decimal place before checking if the position exists. If not, it retrieves a limited list of nodes that are less than e.g. 1 metre from the specified position, and then finds whichever fits closest. This alone cut the request time from about 5 ms to 3ms.

Node theNode;

// Round to 1 decimal place
requestPos.x = Mathf.Round(requestPos.x * 10) / 10;
requestPos.y = Mathf.Round(requestPos.y * 10) / 10;
requestPos.z = Mathf.Round(requestPos.z * 10) / 10;

if (nodes.ContainsKey(requestPos))
{
theNode = nodes[requestPos];
}
else
{
// first, prune any nodes that are too far away
// then find whichever is closest to the requested position
List tmpNodes = nodes.Values.Where(d=> Vector3.Distance(d.position, requestPos) Vector3.Distance(d.position, requestPos) <
Vector3.Distance(n.position, requestPos) ? d : n );
}

However, this is still slower than I’d like. I really need to find a better way to calculate light intensity; baking it into the navigation mesh wasn’t as good as I thought!

Static Analysis in Unity

I work as a software engineer in my day job, but I graduated in November last year. I hadn’t heard of static analysis until just under three months ago, and now I wonder why I didn’t.

For those who don’t know what static analysis is, it involves looking at code to find errors without running it. This can be done manually, but humans are useless fallible, so it’s the sort of thing computers can do instead. At work, I’ve got used to using JSHint for linting JavaScript via Grunt, as well as using SonarQube for JavaScript and Java. These allow you to specify individual files to check for errors, with specific rules – such as unused variables, methods with too many if/else statements, or duplicated code – and I thought it would be useful for me.

I’m using MonoDevelop to write my code, so obviously I’ve looked for anything that will work with that. So far, I’ve found some Gendarme Rules for Unity. Gendarme is a .NET assembly analysis programme, so instead of scanning individual files, it scans an entire library. For Unity projects, select the Assembly-CSharp.dll (or, depending on your language or choice, Assembly-Boo.dll/Assembly-UnityScript.dll) file for analysis. The location of any of these is project_root\Library\ScriptAssemblies, e.g. on Windows it might be in C:\Users\{me}\Documents\Unity\{MyProject}\Library\ScriptAssemblies, depending on where you put your project folder. After you set the rules, it examines the library and produces a HTML report that you can view in your browser, listing which rules were violated by which line of code.

I do have one minor problem with Gendarme: it examines libraries, not individual files, so the report will include defects in any third-party assets. However, it does pick up things like empty Update and Start methods, recurrent calls to GetComponent, or unused methods and parameters (that latter one is something the compiler will notice, but it won’t notice unused methods). While I find that the extra defects make it a little harder to pinpoint problems in my code, it does indicate how severe those defects are and what can be done to fix them. Overall, I like it, and I’ve started to build it into my workflow.

Path-finding for stealth

One of the problems I have with Spamocalypse is how to build light intensity into the player’s ability to hide. Most of the stealth-based games I’ve played include a mechanism like this, and I think it’s worth adding. My problem is how to do that, especially given that I’m using Unity Free and don’t have access to things like Light Probes.

The solution I’ve come up with is to add illumination to the pathfinding system. However, for that I’ll need to build one. This is something I did for my M.Sc. (see the Completed Projects page), but it had a few problems. Firstly, the mesh for each level was generated from scratch upon runtime, and the nodes were essentially limited to a two-dimensional array. Due to the level design, I also had a lot of unreachable nodes that were simply wasted space. While premature optimisation is a bad idea, I still hate the idea of useless data.

So far, I’ve managed to create a mechanism for serialising and deserialising the navigation meshes to the disc, allowing me to save and load navmeshes at runtime. I also have a template for adding nodes underneath obstacles, although it doesn’t quite work yet. Finally, I have managed to add an illumination variable to nodes, so that part of the system is done. At the moment, what I have left to do is to finish an A* implementation, and I should be fine.

I’ve decided to put this up as a GitHub repository, partly for storage, partly to track my changes, and partly so other people can use it, and it can be found here. When it’s finished, I will also add it to Dropbox as a Unity Package.

Breakable weapons in video games

I haven’t posted anything lately. Part of this is that I now work full-time as a software engineer, so I don’t have as much time for anything, and my day job involves being wound up by computers. Part of it is that I’ve just about finished Valentine’s Day Escape, and don’t feel like actually making anything. So, here’s something completely different: what I think of breakable weapons in games.

Continue reading “Breakable weapons in video games”