Runtime Colour Variation

One fairly common practice to increase visual variety in video games is to re-colour sprites or textures, but runtime colour variation can also be used as a means of allowing players to further customize their game characters or equipment. For our next project, we need to make use of colour variation for both of these purposes and set out to compare some of the different methods for achieving this goal.

Sword - Full Colour

Original Colour

We want to be able to take this image and apply new colour variations in-game to allow players to dye their character’s equipment to fit their desired colour scheme.

NOTE: The code shown below is HLSL.

 

Tinting

float3 newColour = initialColour * tintColour;
Tinted Result

Tinted

This is the quickest and easiest method of changing a texture’s colour, but it doesn’t produce very good results. The old colours are partially showing through and the whole sword has to be tinted a single colour.

To remove the effect of the old colours showing through, we can desaturate the original image first, but this still leaves us with the issue of only being able to provide a single colour; and in addition, the sword now looks even more monochrome.

float3 Desaturate(float3 colour, float desaturationAmount)
{
	float intensity = 0.3 * colour.r + 0.59 * colour.g + 0.11 * colour.b;
	return lerp(colour, intensity.rrr, desaturationAmount);
}
float3 newColour = Desaturate(initialColour, 1.0) * tintColour;
Sword Result - Desaturated then Tinted

Desaturated then Tinted

 

 

 

 

 

Pros:
– Very easy to do
– Could produce decent results for items that don’t vary greatly in colour

Cons:
– Separate parts of the texture can’t have different colours applied
– Monochrome results aren’t very visually appealing

 

Masking

This requires a little more set up than tinting. Instead of saving colour information in our sprites, we can save what is effectively a “colour ID”.

Sword - Masks

Colour Masks

In this image, each channel represents a separate colour ID which we will swap out with the desired colour in our shader.

 

 

 

float3 newColour = initialColour.r * ColourR + initialColour.g * ColourG + initialColour.b * ColourB;

NOTE: ColourA, ColourB and ColourC are parameters passed to the shader that represent the colours we’d like to use in place of the IDs in the mask.

 

Masked

Masked

The results produced by masking are a marked improvement over tinting, but there are still some issues.

We can’t easily apply more than three different colours to our sprite; and if we wanted a sprite with a different number of colours, we’d need to make a new shader – not an ideal situation.

Pros:
– Not much more complicated than tinting
– Produces good results with a low (and consistent) number of colours

Cons:
– No way to elegantly handle a variable number of colours
– Only allows block colours
– Requires a special workflow for creating sprites

Hue Shifting

This method involves converting your standard RGB sprites into another colour space (in this case, HSV: Hue-Saturation-Value), adjusting the hue, and then converting back to RGB to be displayed on the screen. This is both the most complicated and most expensive method on this list.

float3 newColour = RGBtoHSV(initialColour);
newColour.r = (newColour.r + HueShiftAmount) % 1.0;
newColour = HSVtoRGB(newColour);

NOTE: Colour space conversion functions are fairly long and have been omitted. It’s easy enough to find them through Google.

 

Hue Shifted

Hue Shifted

The results look pretty good – we’ve managed to keep all five of our distinct colours, but shifted the hue to give ourselves a different result from the original sprite.

Pros:
– Good looking results
– No need for special set up or change in workflow

Cons:
– We can’t individually tweak the colours
– Converting between colour spaces is a relatively costly operation

 

Gradient Mapping

Gradient mapping is often used in visual effects, but rarely finds use outside of that narrow topic. Basically, gradient mapping involves creating a grayscale image and mapping each value to a colour in a separate gradient texture.

Gradient Colours

Gradient Colours

Gradient Values

Gradient Values

Black values in the image to the left correspond the leftmost colours in the gradient, whereas white values map to the rightmost colours.

In our shader we use the values taken from our encoded sprite (left) and use them as the U coordinate to sample into our gradient.

float gradientValue = tex2D(GradientIDs, UV).r;
float3 newColour = tex2D(Gradient, float2(gradientValue, 0)).rgb;
Gradient Mapped

Gradient Mapped

This allows us to specify as many colours as we like, which can be swapped out by replacing the gradient texture (which itself is simple enough to generate at runtime).

One other benefit to this method is that we aren’t restricted to a set number of colours. Although I haven’t done this in the example, we could make use of the “inbetween values” to allow for a smooth falloff from one colour to the next.

Pros:
– Allows for a much greater variety of colours. The number is limited only by the width of the gradient texture used
– An arbitrary number of colours can be used (varying by sprite) without needing to make any modifications to the shader
– Not restricted to block colours like many of the other options
– A single channel can be used to store all of your colour information (in addition to a small 256×1 texture – which can be shared between many sprites), freeing up two extra channels for other things and saving memory in the process.

Cons:
– Requires a special workflow. All sprites must now be made as what is effectively a lookup table into a gradient

Conclusion

In the end, we chose to use gradient mapping for our project. The ability for us to have a different number of colours for each sprite is invaluable. We can let players dye their equipment simply by allowing them to change the colours of the “key frames” in the gradient (while optionally allowing more advanced users to play around with the gradient itself, adding/moving/deleting colours).

The one big downside to gradient mapping is that it requires a completely different workflow from what most artists are used to (which becomes even more of an issue when allowing players to create their own sprites – we can’t expect modders to be familiar with uncommon workflows like this). We intend to combat this issue by implementing a comprehensive set of tools inside the editor itself for easily creating these gradient mapped sprites, though that still makes it difficult for players to use image-editing software that they are familiar with.

Ultimately, the choice of how to handle colour variation differs from project-to-project and it’s definitely worth the effort to look into existing solutions to see which is the best fit for your game. Personally, I find gradient mapping to be a really useful but under-used technique and hope to see it used more often in the future.

Project Forge DevLog – Week #1

Starting today, we’ll be keeping a public log of what’s happing on our newest project, a yet-unnamed 2D sandbox game (codenamed Project Forge) with elements taken from action RPGs and dungeon crawlers.

First, I’d like to warn you that this post is going to be fairly dry. We’re far too early in development to show any actual gameplay, so this will mostly be me talking about what we’re doing and our motivations for doing things the way we are. I’m hoping that future devlogs will have some tutorial-style articles for the more technically inclined as well as some peeks into the art/gameplay as the game begins to take shape. I don’t expect future updates to be as long as this one.

 

Didn’t you just post about another game you were working on?

Yes and no. We posted a quick video of a simple “roguelite” we were working on in Unreal Engine; it was to be a very cut down version of a game we’ve been wanting to make since the very beginning. Our ideal game is going to take a lot more time and money to realise, but in the end, we decided we really didn’t want to settle for a watered down version if we could help it. So here we are, after the first week (and a half) of development, showing what’s been done so far.

 

What is Project Forge then?

We’re making a 2D tile-based sandbox game from a side-on perspective. The game will be all about building, crafting and combat. The most obvious comparison is Terraria, although we’re hoping to have a more complex (and possibly class-based) combat system in addition to a strong world-building element in our game. We’re hoping to have a lot of unique spells & items to keep the combat side of the game interesting. We’re also aiming to incorporate randomly generated dungeons separate from the overworld that can be entered through a central hub in the world itself.

So, what are the challenges? How is a 2D game such a monumental task? Well, on top of the base game that I (very) briefly explained, we want to build a strong cooperative (and possibly competitive) multiplayer experience. The real complexity though, comes with the fact that we want to make the game as mod-friendly as possible. We’d like players to be able to make their own items & structures in the game world itself and share their creations with other players. Beyond that, we’d like more experienced modders to be able to pick up some simple, yet powerful modding tools, and adjust any part of the game; adding new classes, additional game modes, unique spell effects, you name it. We’d love to make a game that we can expand over time ourselves, but also one that grows organically with the community. For all this, we really need to write a custom engine from scratch.

 

Why a custom game engine?

With so many game engines available now, it rarely makes sense to write a game from scratch. But there are some situations in which rolling your own engine is the best/only choice, this is one such situation.

Flexibility & Optimization
Firstly, commercial game engines are made with flexibility in mind. They’re made to work reasonably well with a wide variety of games. Tile-based worlds with complete creation/destruction capabilities really don’t fit well with the more general algorithms used in these engines; there are many specific optimizations that need to be done that obviously don’t come as standard in most game engines. There is the option in some engines (such as Unreal) to modify the source code to get the desired effect, but I’d rather purpose-build an engine than try to hammer an existing one into shape. There’s also a lot of overhead for all of the functionality you don’t need.

Physics
The next big issue is with physics. Building a platformer on top of a physics engine is already a painful process, but with the introduction of tilemaps, things get even uglier. There are so many hacks that would be needed in order to make an engine’s physics work for our game that by the time we’re done, the physics engine wouldn’t even slightly resemble what it used to be. We’ve made our own “physics” engine which allows for efficient collision detection & response against tile maps, as well as different physical properties (friction, restitution, etc) on a tile-by-tile basis. We’ve also made it easy to hook into the physics engine itself to customize behaviour from the gameplay code. This allows us to have all of the non-physics interactions for the character (movement speed not being limited by ground friction, wall gripping, stepping up onto tiles, etc).

Modding
This is a big one. We want the game to be easily moddable, and so far we haven’t come across a suitable engine with proper support for the kinds of things we want to do in the game. With our own engine, we can support arbitrary loading/unloading of content packages, visual scripting, and the loading of code plugins. In addition to this, most engines with proper source code access are programmed in C++; while fast, C++ isn’t exactly a very productive way to work, and it certainly isn’t something I’d want to subject potential modders to. I chose to write the engine in C# as it’s still extremely fast, but is also very productive to work with and is well used thanks to things like XNA/MonoGame and Unity.

 

So, what have you got so far?

With all that said, what have we actually got to show for our first week of development? Mostly engine stuff so far. It’s just me working on it for now since there’s only programming work to be done for the moment.

  • Basic engine subsystems (input, logging, core data types)
  • Beginnings of game & world structure (classes for World, Actor, Component, Controller, etc)
  • Tilemap class with a wide array of manipulation methods (set/get, flip, extract, blit, rotate, resize, and flood-fill)
  • Custom physics engine with support for efficient tilemap collisions and per-tile physical properties
    • Optional callback & “hook” functions into the physics engine
      • Override friction calculations (used to prevent characters sticking to walls)
      • Optionally reject new contacts before resolving collisions (used to allow characters to “step up” onto one-tile-high areas, rather than getting stuck)
  • Beginnings of world generation. Noise-based an multi-threaded (about 40 seconds to generate a large world: 4km x 1km [8000×2000 tiles])
  • Some tile rendering optimizations (culling, chunk batching)
  • Beginnings of CharacterMovement component. Handles platformer controls (reactive direction changing, air control, multi-jump, variable jump height, late/early jump tolerance)
  • Profiler that calculates framerate and allows for tracking of time spent in arbitrary blocks of code

Hours of Work: 75.5
Lines of Code: 3,125

Astray release date, and what’s happening post-release

As of about an hour ago, Astray has been released as “coming soon” on Steam, with a release date set for 3rd February 2015. The game will be available for £6.99 ($9.99 USD).

With this announcement comes an updated release trailer and a brand-new gameplay trailer.

 

Post-Release Plan

With that out of the way, I’d like to talk about what we’re planning for after the game is released, starting with the VR situation.

 

Virtual Reality

Back in October, we tweeted saying that it looked like Astray would have full VR support at launch, but unfortunately that won’t be the case due to Unreal Engine not duplicating the UI in stereo mode yet. Astray can still be played with the Oculus Rift; most of the VR-specific functionality is in-place, but the menus and HUD (including in-game notes) don’t work in stereo mode and thus are impossible to read. Playing Astray with the Rift right now means missing out on the story and having to mentally track battery usage.

Localization

We do still want to release Astray in multiple languages and will likely be rolling out some language packs in the coming months. Currently, the languages we’re likely to localize to include:

  • French
  • German
  • Spanish
  • Russian

Other Platforms

At the moment, Astray only has a Windows build. Since neither of us have any real experience with operating systems outside of windows (and since this is our first major release), we decided to stick to the one platform for launch. We’ll be working on other platforms including Linux and possible console release – hopefully shortly after our Windows release on Steam.

Astray Greenlit!

It’s been 25 days since we launched our Steam Greenlight campaign for Astray and honestly, we didn’t think we’d make it without some sort of additional marketing push. But as of two hours ago, Astray is officially greenlit! Thanks to everyone who voted.

Now we’re hard at work finishing the game. Also of note: our Oculus DK2 is expected to be shipped in the next few days so we should soon have a concrete answer to whether or not Astray will support Oculus VR at launch.

Expect more news in the coming weeks.

Nameless no longer

Well, it’s finally time to drop the codename. As of yesterday, Project Erebus is now known as “Astray”. This follows the launch of our gameplay trailer and greenlight campaign for the game.

We’ve amassed a healthy number of yes votes so far and the comments have been overwhelmingly positive. Thanks to everyone who’s voted on our greenlight page so far. As of the time of writing this (approximately 17 hours into our campaign), we’re 12% of the way towards achieving a spot in the top 100, so we still have a long way to go.

If you haven’t already, please vote on our greenlight page using the link below and tell your friends about it. We need your help to get Astray on Steam.

 

Thanks for all the support! We’ll be posting updates on Astray as well as some tutorial-style posts in the coming weeks. Any news is usually posted to Twitter first and new blog posts are tweeted about, so if you’d like to keep up-to-date with the news regarding Astray, please follow us on Twitter.


Project Erebus MiniBlog – Art Complete

We missed our blog post and Screenshot Saturday last week because I was feverishly trying to get all of the art assets finished. Well, as of yesterday afternoon, the art milestones for Project Erebus are complete! – two months ahead of schedule no-less.

This is going to be another short post as we’ll be transitioning to making the actual environments for the game starting today.

And here’s a full set of screenshots for the zones that we’ve built test scenes for, featuring a zone we haven’t shown before: the caverns beneath the museum. Some of the art for the Egypt exhibit has been re-done to bring it more in-line with the other art.

Remember, these are just art test-beds, not actual zones for the game – some are less fleshed-out than others.

Unreal Engine Tips & Tricks

So it’s time for another post; this time we’ll be looking at a few features of the Unreal Engine 4 editor that you may not know about that could increase your productivity. We use most of these features on a daily basis and can’t imagine working without them.

 

  1. While in simulation mode (Alt + S), you can keep the changes made to any actor by selecting it/them and pressing ‘K’ (alternatively, Right-click > Keep Simulation Changes). Usually, in simulate mode, any changes made are lost when you drop back out; but this lets you keep them for specific actors. Combined with physics, this means you can easily stack/scatter objects in a realistic way by enabling ‘Simulate Physics’ on a group of actors, let them fall in simulate mode, and then keep their new positions.

  2. Press ‘End’ to snap an actor to the surface below it.

  3. Ctrl + End snaps actors back to the grid.

  4. Ctrl + Number keys (not numpad) bookmarks a camera position, pressing the number keys (without holding Ctrl) moves the camera to the corresponding bookmarked position.

  5. Pressing ‘F’ frames a selected actor to your viewport.

  6. Ctrl + P opens an asset menu where you can search for assets and drag them into the scene without going through the content browser.

  7. Holding Alt while moving (or rotating) an actor will duplicate it. Holding Shift while moving an actor will make the editor camera follow along.

  8. Right-clicking a vertex of a brush will snap it to the grid (only if positional grid snapping is enabled).

  9. Using the ‘[‘ and ‘]’ keys will increment/decrement the positional snapping grid size.

  10. Copying an object to the clipboard will copy it in a readable text format, allowing you to copy between levels/projects, share actor settings with other people, and make changes by hand before pasting back into the level.

 

Project Erebus MiniBlog – Demonology Exhibit Art

Just a small update today: the art to be used in the demonology exhibit is just about done, this brings us to around 77% of the art complete (although we expect more art to be needed that we haven’t accounted for).

Now that the level whiteboxing is done and the art is almost complete, we should be able to build the actual levels for the game starting next week.

Here’s a quick demo scene we put together in an hour or two to showcase the art that will be going into the demonology exhibit:

Demonology_001 Demonology_002

As a side note: the sigil in the center of this room comes from the Arcane Runes Photoshop & GIMP Brushes pack by obsidiandawn. They have some amazing brushes, patterns, and other images.

Project Erebus DevBlog #2 – Art Preview (Forest, Egypt, Norse & Atlantis)

It’s been a long time since our last post. We had to stop working on the game for a little while but now we’re back with an art preview for four of the zones in erebus (the first 3 exhibits + an outdoor area).

In total there are 10 visually distinct zones in the game (6 of which are exhibit areas). We wanted to make each area interesting and obviously different from the others and decided that making each exhibit themed to match what was on display was the best way to achieve that. Each zone had to be eerie in its own way.

There’s a lot of artwork involved in this game, I’d say the art assets easily take up most of the development time. In hindsight, developing a heavily-art-based game might not have been the greatest idea we (as a two-man team, with no artist) have had.

Anyway, this post is a little short on information, so here’s a couple of screenshots and a video showcasing the first three exhibits of the museum.

Norse_03 Norse_02
Norse_01 Forest_02
Forest_01 Egypt_01
Atlantis_03 Atlantis_02
Atlantis_01 Norse_04

Project Erebus DevBlog #1 – Character Controls & Art Style

It’s time for our first ever dev-blog! I’m afraid it’s nothing too interesting, in future posts we’ll be going into more detail and probably talk about the development process. For today though, we’re just going to be showing the very beginnings of our currently-in-development horror game codenamed Project Erebus. The most important part of a horror game in our eyes is the ambience and “feel” of the game so we made it our first goal to set up the character controls and a simple test scene for prototyping to make sure the way the character and camera moved felt just right. We didn’t want the character to just float around the environment, which meant the camera had to move around to try and simulate (or exaggerate) a person walking. The majority of the development time so far has been tweaking values to get just the right amount of head-bob and camera sway and we think it turned out pretty well – it’s mostly been a case of trial-and-error. As for modes of travel: we wanted the default walk speed to be fairly slow as it helps to build tension. At the same time, we wanted the ability to run for short bursts in situations where the player feels safe to do so. And last but not least, the ability to crouch we think is vital to this game – there will be moments where you’ll need to duck into small (and not so inviting) areas to traverse the environment. So far, the character has the following capabilities:

  • Sprint short distances
  • Crouch into confined places
  • Peek around corners to survey the environment before progressing into a potentially dangerous room
  • Pick up physics objects and move them around (think Amnesia: The Dark Descent)
  • Pull out a flashlight to illuminate particularly dark rooms
  • Footstep sounds – combined with the near-silence in the environment really help to build tension and leave the player wondering if they just heard a noise or not

The flashlight is going to be key in building tension in the game. It lights up the environment just enough to see what’s directly in front of the player but doesn’t reveal too much and has a really creepy feel to it. Here’s a video showing the character in action:

And here’s a few screenshots showing the visual style we’re going for. We only have a few environment pieces right now but hopefully we’ll be able to pick up the pace a little now that the base functionality is in place.

ErebusEnvironment_01 ErebusEnvironment_02
ErebusEnvironment_03 ErebusEnvironment_04
ErebusEnvironment_05