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”

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!

Spamocalypse Updates: Mac build, bug fixes, new GUI

Less than a week since the last build, and I’ve had some feedback from several places.

Firstly, I now have a Mac build. This is completely untested – I don’t have a Mac myself to test it on, but somebody commented on the Feedback Friday thread that they couldn’t test Spamocalypse because they were on a Mac…so, I figured why not. Just don’t blame me if it breaks! 😛

New UI
The biggest criticism I had on the thread was that my GUI was awful – it was basically white rectangles that turned orange when highlighted. It mostly worked, but the style just didn’t match the game. So, I reworked the GUI completely so that the menus look like a piece of parchment, with red wax seals representing the buttons. It’s not 100% complete – I may rework the new briefing menu so that the text is over multiple pages, since I’m using a book as the background – but here’s a pair of before-and-after screenshots:



Bug and mechanic fixes
It wouldn’t be an “Early Access” game without these! So, here’s the list of stuff I fixed.

  • I forgot to assign some buttons for the game over screens. It basically looked like the game had frozen.
  • I finally fixed an issue where you could jump while leaning. This didn’t break anything, but it looked weird to be leaning at a 30 degree angle while jumping.
  • The way ladders used to work was that they would turn the player’s Rigidbody kinematic, and convert forwards/backwards movement to up/down movement, while leaving sideways movement unaffected. I’ve changed this to make the player’s Rigidbody ignore gravity instead, so that they won’t go through an object when using it. I’ve also added a tutorial message explaining how to use it.
  • One of my workmates thought the exhaustion mechanic needed to be refined. I’ve tweaked it so you can’t run, jump, attack or climb a ladder while exhausted, but you can move…albeit at a snail’s pace. I may adjust the speed later

How NOT to calculate lighting for stealth games

My original stealth system for Spamocalypse was based around the navigation system. Each Node has a variable for illumination, which is calculated using raycasts and then baked in. For point, area and spot lights, this is inversely proportional to the distance from that light; for the sun/moon, the value of the sun’s intensity is just added without any processing. When an NPC or the player is trying to check if they can be seen at a player, they query the NavigationMesh to get the closest Node, and then check the illumination of that Node.

What’s the problem?
This is expensive! As I covered in previous post, this causes a performance impact. However, the fix I made for that causes another issue while trying to calculate the effect that street lamps would have on the lighting. They had absolutely no effect – it was possible to stand underneath one, and the NPCs would simply ignore you if there were no other lights around. I suppose I could have rewritten that as a “Refuge In Audacity” thing, where the spammers wouldn’t see you because they wouldn’t believe someone would stand under a street lamp in full view of them…but that’s another game, I think.

The street lamps I have are essentially a long, narrow box which acts as a parent for a point light. When the light was casting rays to check a line of sight to different nodes, it just hit the inside of the collider. So, the next thing I tried was disabling the parent collider for those lights, but I ended up accidentally disabling other scenery colliders. When some other point lights were casting rays around themselves, they ended up hitting points that were outside the navigation mesh, which caused the BuildNavMesh class to throw an exception.

WTF was I thinking?
I just didn’t know of any better way to do this. My first thought was to try using Unity’s LightProbes, but I started Spamocalypse the free version of Unity 4.6, and they weren’t available to free users at the time. I also don’t know if the API for LightProbes allows the intensity to be retrieved as a float, which is what I was looking for. I also had some experience at trying to generate a pathfinding system for my Master’s thesis, so I decided to give that a try, as I knew the general concept would work.

The actual solution
After looking around the Unity forums, I’ve created a physics-based solution that uses trigger colliders and raycasts. Each spot, area and point light has a trigger collider attached, which tracks instances of a CalculateLight component that are inside the collider. If the light has a “line of sight” to that CalculateLight, the light contributes to it’s total intensity. The amount contributed is the intensity of the light, divided by the distance between the light and the object it’s tracking, and at the moment is clamped to a maximum of 1.
There is only ever 1 directional light in a scene, so the Sun component handles this. It has a list of CalculateLight components, and tracks each of them using FixedUpdate. It basically casts a ray to check if the object can be seen, and toggles whether or not it “visible” to the sun/moon. If a CalculateLight component suddenly is in the sun, it’s total intensity is immediately increased by the intensity of the sun, and stays that way until the character can no longer be seen.

Does it work?
Yes, it does. I haven’t done a full test over the City Inbound level yet, but it doesn’t take as long to calculate, and it actually works in real-time – so, I could possibly use this for things like spotlights or torches in future projects. I will update this with the full test results.

New build! (Finally)

I finally have a new build. Most of these are performance fixes that I covered in my last post, but I also added a lot of extra stuff to the City Inbound level.

Using Coroutine for line-of-sight detection
While trying to improve the performance of the line-of-sight detection, I started using a Coroutine instead of OnTriggerStay. OnTriggerStay is called on the physics timestep, which by default is 0.02 milliseconds. I set my Coroutine to run every 0.25 seconds, which spreads out the relatively expensive conversion of a position to a Node. It’s not perfect, but it will do for now.

Spicrab Storage and Spicrab Square
This is a former storage warehouse. At the moment, it’s mostly empty, but there are a few notes to find inside the office. Two of the other buildings around the square are accessible, but the rest are not. One of the buildings contains a lift…which I haven’t tested yet.

A shop that sells washing machines…in a medieval city. This is a reference to a particularly obnoxious spammer that used to clog up the Unity forums with threads about fixing washing machines, fridges or air conditioning. I originally planned to add this arsehole in as a particularly persistent boss, but I ditched that early on.

You now start in the sewers, and must find your way to the sewer entrance next to the Museum. That will lead into the next part of the City, which I am hoping to finish within a month or so.

Have some screenshots! These are all from the Editor, rather than the build.
Barry's Diner/Tea Shop
Museum Square, with the firewalls casting an orange glow over the entrance.
Looking down Loam Street

New build: night vision, pathfinding fixes, tutorial messages

Another build for Spamocalypse. This has a few changes:

Night Vision effect
After some feedback from the Feedback Friday threads on the Unity3D forums (mainly about some parts being too dark to really see where they were going), I added in a night-vision effect that I found on the Unity3D wiki. This did lead to an issue where part of the UI was hidden by the scope effect, which you can see below, but I fixed that by adding a second camera which exclusively handles UI objects.

The NVG goggles effect, while the player leans around a corner. Includes a tutorial message.
The NVG goggles effect, while the player leans around a corner. Includes a tutorial message.

Tutorial messages
I am starting to lock down the mechanics, but I decided to add in a quick tutorial mechanism for the player, to show them how to move, crouch and jump. It’s pretty basic at the moment, and it’s limited to the default controls. However, this is at least a starting point for later.

Extra movement possibilities
AKA you can lean, jump, and crouch. I had originally planned to make these animation based, but animating a humanoid would have taken too long, so I resorted to scripting them. These mostly work, but the mechanism I added to recentre the player doesn’t quite work – it happens automatically, but if you look around while doing this, it doesn’t fully recentre the player. However, if you tap the key to lean in the direction that you’re tilted in (e.g. tap the Lean Right key if tilted to the right), it fixes this, so I’m not too bothered by it.

More props in both of the levels. I also fixed an issue with the light calculation where it would ignore obstacles between a light and a node, causing the illumination of a node to be inaccurate. This would have resulted in a character being visible even in shadow, which defeats the whole purpose of sticking to the shadows!

Gameplay video

I finally have a gameplay video.

Okay, I made this a few weeks ago, but I uploaded it as a private video after I noticed that my microphone is awful. I meant to record a new intro separately, but that struck me as a little too much effort, and sitting on this has caused my motivation to drop. So, here goes: my first gameplay video. Feedback is welcome!

Spamocalypse Update (1.3)

Spamocalypse is now at v 1.3!

So, what’s changed. Well, not a lot, really. I’ve included loot, which didn’t take very long, and I’ve also added difficulty multipliers which affect how quickly the enemies will detect you. At normal difficulty (the lowest and the default setting), enemy detection speed is multiplied by one. On hard difficulty, this is multiplied by 2, and expert multiplies it by 3. The values for hard and expert are temporary, and may change later.

Now that this is done, I am going to start designing a proper level. Sounds like something that needs a pint (once the pubs open 🙂 )

As usual, it’s up on Dropbox as Spamocalypse v1.3. Feedback welcome!

UPDATE 10th of August: I’ve tweaked their ability to search for you. If they can’t see you while searching for you, they will search the nearby area instead of always searching ahead of their current position. I’ve also decided to leave the amount of time they will be distracted by a sockpuppet constant, but have their alert time scale with difficulty.

Spamocalypse Update – now in alpha

After however many weeks, including moving house and my probation at work passing (yay!), the prototype for Spamocalypse is finally done. You can find it here, including the manual. I’ve removed the Mac version for now, as I don’t have one on which to test it, so there’s not really much point in developing for Mac.

What I’ve done

  • I’ve created an inventory system which allows you to cycle weapons. You have two weapons – one is ranged, and the other is melee – and two decoys.
  • Created an interaction system which highlights objects when you’re looking at them, like ammo, controls for a firewall, or books/notes/letters.
  • Increased the size of the spammers’ field-of-view models, allowing them to see you from further.
  • Increased the size of their sound detection models, so they can hear you from slightly further away.
  • Moved everything related to the spammers’ voice clips into separate components, and edited their sound effects to sound more like a zombie.

What needs to be done

  • I need some actual models for the enemies, the weapons, and anything else.
  • The AI might need some tweaks, depending on how dumb they are.
  • It needs a proper level, rather than thrown-together stock cubes.
  • Need moar loot!!1!1! More seriously, the player character is supposed to be a thief, so loot goes without saying.
  • Give the player character a voice. I’m thinking of letting the player decide if they want the character to be male or female, with a suitable voice to match.

All in all, I’m reasonably satisfied by it. Try it out, and let me know what you think.