Fiptubat 0.5

This release is mostly cosmetic: I added a new level, UI and models. The full list of fixed issues can be found here.

New Level(s)

The new level is an industrial complex, built using props from the Phishers’ Gauntlet project that I abandoned. I’ve also added some third-party assets:

The title scene also has some limited scenery, with other player characters crouching behind cover.

New UI

Mostly, I got rid of the smiley faces that showed the player status. My original plan there was to have images similar to Jagged Alliance 2 that become increasingly bloodied as they take damage, but I found this to be dead weight.

I also replaced the fonts. Instead of Arial, I’m using this archaic typewriter font. I’ve also used Ampad Brush in the title scene to make the buttons resemble graffiti on the walls.

Screenshots of the level

It’s still a bit empty, even after adding props, but I’m starting to get tired of this project. For something that was originally meant to be a proof of concept, it’s gone further than I expected. I’ll probably leave it for a month and come back to it, but I’m a bit stuck on what to add next.

Fiptubat 0.4

Finally, Fiptubat has reached version 0.4! The full list of fixed issues is here, but here’s the main ones.

Humanoid enemies

The big change was adding humanoid enemies that take cover. Finding cover was adapted from a very useful post on the Unity forums, which uses the following flow:

  1. Sample random (or not-so-random) positions around the unit’s current position
  2. For each sample position, find the nearest edge in the NavMesh.
  3. Obtain the normal field of the resulting NavMeshHit
  4. Remove any results that don’t point sufficiently away from the target direction
  5. Choose the closest.

It broadly works. Once they get to a cover position, they will repeatedly fire at their chosen target if they can see it, or reposition on their next turn.

Combat

Multiple fixes:

  • Turrets will pick the most exposed enemy they can find, rather than the closest. There is one slight caveat: this is based on the number of Raycasts that hit the target, which may result in things like this.
  • Suppression mechanics: dump enough ammo into the area around a target, and they lose their remaining action points. On their next turn, they’ll have half their total.
  • Turrets no longer have 2-D aim. This took me the better part of a day to fix, and was the last issue added.
  • Enemy units will try to relay the position of enemies to their comrades when spotting them.
  • Sidestepping is no longer a free action. It now works by shifting the player units a guaranteed distance forwards/backwards/sideways, with a cost of 4 action points per unit moved.

Other fixes

  • Toned down the sirens. Turrets still use this when spotting an enemy, but they have other noises. The humanoid enemies use a recording of Radio na Gaeltachta under heavy static.
  • The player unit’s current path is now visible as a solid red line. I would like to make it dotted and translucent behind objects, but that’s another issue.

The next release will probably involve character models and a larger level to play in.

Fiptubat gameplay demo

I finally have a gameplay video for Fiptubat – warts and all. It shows the player units picking their spots and moving to them, basic combat, and swapping turns with a hostile faction.

The video shows one really annoying bug that I haven’t got to the bottom of yet. Player units sometimes start jerking around when standing still, and I’ve tried quite a few things without any success. I had originally planned to fix this before filming, but decided that it didn’t break the core gameplay enough to hold back everything.

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 release 1.0.0

Finally, two years since I started working on it, Spamocalypse has reached version 1.0.0. My brother tested 0.8.1 and made some suggestions, some of which I have implemented:

  • The map and notes have an alternative method for closing. You can still close them using the “close” buttons, but pressing Escape or F/M will now do that as well
  • I finally fixed a bug in the camera rotation, which would have resulted in the player appearing to stand upside down. One of the current known issues is that on my Linux machine, camera rotation using the mouse is locked to the screen, so I didn’t realise that this could occur. I have fixed it, though he found it amusing.
  • The knife animation was too short, i.e. it didn’t travel far enough. I’ve increased the thrust length so it is a bit easier to use.
  • He also mentioned that it was hard to aim the SQLer when the spammers are moving laterally. However, that’s due to the SQLer rounds being physics-based, so the player would have to manually aim it to account for this. I haven’t implemented this, but it might come into future games.
  • I increased the Moderator’s turning speed while trying to investigate an collision issue with the spammers. I couldn’t reproduce that issue, but make the Mods turn faster will make them react faster to the player
  • .

Anyway, this is the official release of Spamocalypse. Here’s the release trailer:

Spamocalypse 0.6.1

Finally, I have a new build to show off. I originally built this on Sunday and uploaded to GameJolt, but when trying to take some screenshots, I found a few bugs that required a patch.

Bug fixes

  • I converted the colliders for line-of-sight checks to use Capsule Colliders instead of Mesh Colliders. The Museum level had almost 30 MeshColliders for this, which really screwed up performance. The other levels were okay, but Capsules covered roughly the same area as the extruded box I was using. I really should have properly tested that sooner.
  • I also fixed a long-standing bug in the line-of-sight code that caused the spammers to spot the player as soon as they came within 5 metres – regardless of how bright the player’s surroundings are.
  • I removed the directional light from the Museum level. The component I was using to calculate its effect on NPCs and the player was ignoring the colliders on the upper levels of the museum, which resulted in the player being “in the moonlight” while indoors, in a windowless room. There’s only one part that’s outdoors in that level, and there’s other lights there anyway, so I didn’t even need it!
  • There was a note in the Inner City level which wasn’t assigned – this caused the game to freeze up when the player tried to read it. Game breaker!
  • The player’s compass in the Inner City level didn’t rotate properly. I had assigned it to the UI layer in an attempt to stop it from clipping through walls, but the camera that handles UI doesn’t rotate. I may add this back in the next build – I think the idea is sound, I just didn’t do it properly

New mechanics
As if I didn’t have scope creep already, I went and added more:

  • Bushes. Yes, you can hide in bushes now. They rustle if you move into them too quickly, so no running and diving into them!
  • Light switches. I should really have added this sooner, but I didn’t think of it until I started testing it last weekend. It meant changing the lighting from baked to real-time, but that does mean I can get shadows from NPCs, so it’s good.
  • Firewall controls now include a sound effect and light to make it clearer that they’ve been used.

Known issues

  • The SQLer doesn’t quite aim where the player’s looking. I am considering adding a secondary fire mechanism that would allow the player to aim down the sights.
  • Occlusion culling might be inaccurate in one or two levels. This results in buildings “disappearing” while you’re looking at them. I think I fixed this in the original build on Sunday, but this is present just in case.
  • The museum map doesn’t include the new garden on the upper floor.

Spamocalypse 0.5.0: new level, stats, and artwork.

Finally, I have a new build, which brings Spamocalypse to 0.5.0. The changes:

  • I added the final level. This uses the same scenery as the first (non-tutorial) level, but there’s no loot to steal this time – just get to the sewers where you started!
  • I also added a credits scene (see below for a screenshot). This will display your total stats over the course of the game – number of deaths, kills, loot stolen and how often you were spotted.
  • I finally fixed that bug where you could lean over while jumping. It wasn’t a game-breaker, but it looked bloody weird.
  • Some general artwork updates. In particular, the SQLer now fires darts instead of blobs. They still use a sphere collider to handle physics, but I figure that will do.
  • Refactored the patrol points so they have a component attached to them. This component, PatrolPoints.cs, just holds their position, purely so I can filter through the scene more easily.

Here’s the credits screen. You can skip the credits and stats by pressing “Escape”
credits-scene

The next stage is to create more props for the levels, giving the player more places to hide or things to look at, then any bug or UI fixes I can think of. Nearly two years in development…I might actually finish this after all!

Building multiple platforms with one click

EDIT: this is now up on GitHub.

I finally got tired of manually changing platforms after creating builds, so I went and created a customised BuildPipeline. This creates a 64-bit Linux build, then switches to 64-bit Windows, and ends with 64-bit Mac OSX, all with one click of a button. I wish I had known how to do this earlier!

The basis of this is manually calling BuildPipeline.BuildPlayer. This requires a few parameters:

  • An array of strings with the names of the levels you want to include
  • The name and location of the executable (i.e. what the players are going to click on)
  • The target platform (in my case, 64-bit standalones for Linux, Windows and Mac).
  • The BuildOptions. This is the tricky one: according to the docs, it is possible to combine multiple values of this, but I haven’t figured out how to do this yet. It might be because I’m on 5.3.6, instead of 5.5.

And that’s it. Here’s what the code looks like:

using UnityEditor;
using UnityEngine;
using System;

public class MyBuildPipeline {

// constants for defaults
const string WINDOWS_FILENAME = "_Windows";
const string LINUX_FILENAME = "_Linux";
const string MAC_FILENAME = "_Mac";
const string SCENE_FOLDER = "Assets/_Scenes/";
const string BUILD_PATH = "Player Files/";

// TODO: find how to combine these
static BuildOptions devOptions = BuildOptions.AllowDebugging;

[MenuItem("Tools/Aceade/Build")]
public static void Build()
{
Debug.Log("Creating new builds");
var levels = new string[6]{
SCENE_FOLDER + "Preloading.Unity", SCENE_FOLDER + "Main Menu.unity", SCENE_FOLDER + "Sound Test.unity",
SCENE_FOLDER + "City Inbound.unity", SCENE_FOLDER + "Inner City.unity", SCENE_FOLDER + "Museum Model.unity"
};

// calculate the build date
DateTime date = DateTime.Now;
string buildDate = string.Format("_{0}.{1}.{2}",date.Day, date.Month, date.Year);
Debug.LogFormat("Creating new builds on {0}", buildDate);

MakeLinuxBuild(levels, buildDate, BUILD_PATH);
MakeWindowsBuild(levels, buildDate, BUILD_PATH);
MakeMacBuild(levels, buildDate, BUILD_PATH);
}

///

/// Makes a Linux build.
///

/// Levels to build.
/// Date string.
/// Path.
static void MakeLinuxBuild(string[] levelsToBuild, string dateString, string path)
{
Debug.Log("Creating Linux build");
string fileName = LINUX_FILENAME + dateString + ".x86_64";
BuildTarget target = BuildTarget.StandaloneLinux64;
BuildPipeline.BuildPlayer(levelsToBuild, path + fileName, target, devOptions);
}

///

/// Makes the Windows build.
///

/// Levels to build.
/// Date string.
/// Path.
static void MakeWindowsBuild(string[] levelsToBuild, string dateString, string path)
{
Debug.Log("Creating Windows build");
string fileName = WINDOWS_FILENAME + dateString + ".exe";
BuildTarget target = BuildTarget.StandaloneWindows64;
BuildPipeline.BuildPlayer(levelsToBuild, path + fileName, target, devOptions);
}

///

/// Makes a build for Mac devices.
///

/// Levels to build.
/// Date string.
/// Path.
static void MakeMacBuild(string[] levelsToBuild, string dateString, string path)
{
Debug.Log("Creating Mac OSX build");
string fileName = MAC_FILENAME + dateString + ".app";
BuildTarget target = BuildTarget.StandaloneOSXIntel64;
BuildPipeline.BuildPlayer(levelsToBuild, path + fileName, target, devOptions);
}
}

I’m considering adding this to GitHub, once I’ve figured out the BuildOptions.