Honeycomb Engine: Devblog #5 ~ A Component-Based Architecture

The backbone of a game engine is its architecture. When and how you update the game state can have massive performance implications; as such, a large chunk of the time taken while writing your main loop will be spent making trade-offs that make the engine more complicated but ensure maximum performance. The main loop is something you absolutely need to get right if your game engine stands any chance of running smoothly. Prepare yourself for a particularly wordy post all about Honeycomb’s inner workings!

Many game engines opt for an architecture in which every conceptual object that can go into a game – the player, a chair, an explosion – is modelled by a GameObject. By itself, a GameObject doesn’t do a great deal except hold a list of all the useful snippets of behaviour that actually define what the object does – those are usually called Components. It’s probably the most straightforward way of reasoning about the objects in your game, and that’s part of the reason this programming pattern, aptly called the Component design pattern, is used – GameObjects and Components are intuitive.

If you think of a person in real life, you can easily think up a whole host of behaviours they have and how those behaviours interact with each other – they use their legs to move, their eyes to see and their brain to work out a path from point A to point B. In a virtual environment in which the person were an NPC, the legs would be a movement component and the brain and eyes make up the AI component. But the person also has to interact with a physics component to make sure it doesn’t clip through walls, which would require a collider component to define the physical shape of the person. The movement component modifies the transform component (I’ll talk about those later), then the player’s orientation gets fed to the renderer component so that the game knows how to display them. The person also probably has to deal with an animation component that details exactly how it walks and maybe a sound component if it needs to speak. It’s easy to see how the number of components on a GameObject can snowball!

Usually, the only component that is actually required is called the Transform component. The Transform defines the position, rotation and scaling of an object, which is all data passed to the renderer each frame to calculate part of what’s known as the model-view-projection matrix. Without going into much detail, that matrix is responsible for taking a model as defined relative to itself (how you’d see a model in your modelling package) and transforming its vertices onto your screen. You can see why it’s important – everything has a position and orientation! You could theoretically merge the Transform component into the base GameObject class, although later on in this post I’ll go into a reason you might not want to.

Imagine a world without components. Instead, we just throw all of the ideas I just mentioned into one monolithic class called Player. You can probably already see a couple problems with that, such as:

  • You end up with a lot of code to trundle through if you want to modify any of the person’s behaviour, since all of the person’s behaviour is clumped together.
  • Every single piece of behaviour is coupled to every other piece of behaviour. Physics engine code relies on audio code, which relies on the renderer code, and so on. If you want to change how the renderer works, you might need to think about how the change affects the audio engine, which is obviously counter-intuitive.
  • If you want two different types of person that differ only in one small aspect, for example they use different AI components but the rest of their behaviour is the same, you’d have to copy and paste almost all of the code and change the tiny bit that differs. You’re not exploiting the features of object-oriented programming very well.
  • It’s really difficult for a different object to hold references to some part of Player. For example, if we have an Enemy class too, the enemy probably needs to know where the player is. With components, we’d just hold a reference to the Transform component, which holds all data related to the position and orientation of the Player. But without components, all we can do is hold a reference to the entire Player and hope there’s a sensible way hidden in the tangled mess to find just the position data.

By using components, we eliminate these problems. We can use the object-oriented principle of inheritance to make two components that are mostly similar and differ only slightly, then we can use polymorphism to interact with the common portions of instances of those objects as if they were one of the same. We can hold a reference to just the AI component of a Player GameObject and be reasonably sure it has the relevant functions you’d hope to find in an AI. And best of all, you don’t need to think about the audio engine while you’re writing rendering code, since they’re nicely encapsulated in separate components.

It’s worth noting that organising your game this way may incur a performance hit; however, it’s a reasonable trade-off to ensure that your game is easy to program and extensible later on. This is just one of the many instances of needing to make compromises in programming. And like any programming, there are ways to minimise the performance cost or even leverage features of your hardware to your advantage.

One way in which the hardware can actively make your program more efficient when using a component-based system is by utilising the processor cache. I won’t go into a great amount of detail here, but whenever you access some address in memory, the processor will grab not only the memory it needs, but a bunch of memory adjacent to it too, and it gets put in the cache. The cache is essentially ultra-fast memory – it is built directly onto the processor chip – so as you can imagine, anything in the cache gets processed blindingly quickly.

If your components are organised in memory contiguously, when you access one component’s memory, a bunch of other components stored next to it will get pulled into the cache too; hence, by storing all of one type of component together, we can process them all super-fast when we iterate over them serially. That’s much better than having all of our behaviour lumped into monolithic classes, because in that case we’d have to pull a lot of redundant data into the cache every time we call update() on a component and we’d get a cache miss when we try to access the next component. This is also a reason you’d want to separate out the Transform component from the base GameObject class, because you might want to do something with all of the GameObjects that doesn’t involve their Transform data. By ignoring the Transform component, you can exploit the data locality of the GameObjects fully.

This is just one of the things I’ve discovered while developing Honeycomb. Modern software development contains so many more considerations to make than I would have ever imagined! Who knew that the order in which you create objects could have such a profound impact on the overall performance of the software, or that random-access memory isn’t really random-access any more? Stuff like this makes software development complicated and ridiculous, but that’s also what makes it fun for me. This post is rather lacking in colour and is just a 1,300-word block of text – apologies for that, hopefully the next devblog has some nice screenshots and diagrams in it!

Honeycomb Engine: Dev Blog 3 ~ Quaternions for Rotations

Quaternions. The mere mention of these mathematical constructs would’ve sent shivers down my spine a couple of years ago. They’re really weird and complex. However, when you’re making a game engine and you have to model the rotations of objects, you’d be crazy not to use them for several reasons.

The easiest way for people to think about an arbitrary rotation in 3D space is to think of three separate rotations around the x-, y- and z-axes respectively. This way of representing a rotation is commonly known as Euler angles. The advantage is that it’s easy for someone to reason about a rotation represented in Euler angles because they’re so simple – I just rotate around x, then y, then z, it’s that easy. However, this brings a couple of problems with it too; namely, it’s inefficient to do three separate rotations for every single rotation you apply, and Euler angles can run into a problem called Gimbal lock.

In a system where three gimbals each provide an axis of movement around a central point, it is possible to lose one degree of freedom by rotating one of the gimbals 90° such that its axis converges on one of the other gimbals. When this happens, the other two gimbals will rotate along the same axis. The word ‘lock’ is a tad misleading, because you can fix the problem simply by rotating the first gimbal back, but it still leads to weird behaviour sometimes. It’s best explained through an animated diagram.

Quaternions fix both of these issues. Firstly, Euler’s rotation theorem (Yes, Euler got around a lot) tells us that we can represent any rotation or sequence of rotations around a fixed point as one single composite rotation around some axis through that point. As it turns out, we can model rotations around an arbitrary axis as a quaternion!

img_20161109_003123

Rotating around an axis rather than three rotations around x, y and z axes.

To understand how this works, we first need to know what a quaternion is. I’m not going to go into too much detail, because I want to keep this post relevant to how we can use them for rotations. At their most basic level, a quaternion, q, is made up of four real numbers, x, y, z and w, where:

q = w + xi + yj + zk

Here, i, j and k represent versors, or unit quaternions. Don’t worry about what they mean too much, because your head might go nuclear trying to wrap your brain around them. What we want to do is represent x, y, z and w in a way that’s useful to us. Luckily, it’s really simple: take our axis to be a three-dimensional vector (a, b, c) and our angle to be θ. Then our quaternion’s real number parts are:

x = a * sin(θ/2)
y = b * sin(θ/2)
z = c * sin(θ/2)
w = cos(θ/2)

Now we have a quaternion that represents an angle-axis rotation, immune from the problem of gimbal lock. To apply the rotation to an object, we multiply the point we want to rotate by the rotation quaternion. To figure out what the quaternion is doing, we can take x, y, z and w and calculate the angle and axis from them – first of all we can find the angle:

θ = 2 * cos⁻¹(w)

Then, we can use this angle to figure out what the rotational axis – a 3D vector – is:

a = x / sin(θ/2)
b = y / sin(θ/2)
c = z / sin(θ/2)

With this in mind, it’s a little easier to reason about what quaternions are doing. Keep in mind that all these rotations are about the origin, so if you want to rotate around an arbitrary point, you’ll need to translate your object by the inverse position vector of the point, do the rotation, then translate by the position vector of the point to undo the first translation.

rotation-by-translation

This image is about 2D translations, but the general idea still applies.

To make a rotation by compositing two different rotations, we can just multiply their respective quaternion rotations together, paying attention to the order:

new_rotation = second_rotation * first_rotation

The other great thing about quaternions is that we can mix between two rotations really easily, with more believable results that using Euler angles. Whereas we’d use a regular lerp operation (linear interpolation) to move from one rotation vector to another if we were using Euler angles, we can use the more sophisticated slerp (spherical linear interpolation) technique for quaternion-based rotations.

To imagine the difference between these two techniques, imagine you were stood on a completely flat world, whether it be in 2D or 3D, and I asked you to walk from point A to point B on that surface in a straight line at a constant speed – that’s you using a lerp. Now imagine doing the same, but on the surface of a perfectly spherical meteorite instead – of course, walking in a straight line would end up with you inside the meteorite, which is impossible, but if you walk across the surface directly to your destination, that’s what a slerp is doing. Super simple stuff!

on-top-of-the-world

The flag looks like the USB logo, but it’s supposed to be an angle-axis diagram.

That rounds off pretty much all I know about quaternions and how much I could be bothered to look up online. If I got anything wrong, please do tell me because it’s definitely possible. Remember, if quaternions start to hurt your head, which happened plenty of times to me, keep in mind the most important thing: Don’t Worry About It™. You don’t need to know them inside out to be able to use them.

Game Design Tips #16 – [Unity + C#] Linear Interpolation

It’s been an awfully long time since my last post – blame coursework! I have a few weeks to get a couple of posts in before I have more coursework and then exams, so enjoy me while I’m here.

If you’ve coded at all with Unity, you’ve probably noticed its API has a lot of methods called ‘lerp’. Mathf.Lerp(), Vector3.Lerp(), Color.Lerp(); all of these are very helpful methods. But what exactly do they do, and how should we be using them properly? First of all, I’m gonna go ahead and show you how they’re meant to be used, then I’m gonna break them horribly to show you cheap ways of doing cool stuff.

How to use Lerp without being hacky

‘Linear Interpolation’ is a lot of syllables to get your head around, so first of all, let me explain what it means. Let’s say we have a thing. We want the thing to change into another thing at a constant (linear) rate. This is what linear interpolation does – it takes a vector, colour, float, you name it, and changes it into a new one.

tip-16_img01

This is the lerp method for Vector3. We pass in startPos, endPos (both Vector3s) and a float parameter; this parameter should be between 0.0 and 1.0. When time = 0.0, the object’s position will be 100% at startPos and 0% at endPos, and when time = 1.0, it will be placed at 0% startPos and 100% endPos. It’s easiest to demonstrate what lerp is doing when talking about Color.Lerp(), so we can use a pretty diagram:

tip-16_img02

Here, the square represents the RGB colour scale found in Unity’s colour picker (well, flipped horizontally). When we use Color.Lerp() in this way, when the third parameter is 0, the method returns a red colour (#ff0000 in hexadecimal RGB colour representation) and when the parameter is 1, we get full white (#ffffff). At any point in between, we blend between the two linearly – at 0.5, we’ll get a pink-ish colour exactly halfway between red and white on the RGB scale (#ff7f7f roughly) and at 0.75, we get something mostly white but retaining a tiny bit of red (about #ffbfbf).

Once we understand what lerp is doing when we pass in certain numbers, we can pull everything together cleanly into a coroutine.

tip-16_img03

We pass in the sprite renderer whose colour will change, the colour it will change to and how long it will take to change. The coroutine automatically works out all of the needed variables for the user, so we don’t need to pass in the start colour. Every frame, we set the new colour of the renderer based on what percentage the current time is between the start and end times. Simple! The final step is to ensure the colour gets set to the end colour exactly, since the loop might have exited only 99.9% through the lerp (it’s never going to be noticeable to the human eye, but I’m doing this for the sake of completeness and to avoid triggering anyone’s OCD).

How to use Lerp badly

Now that we know how to use lerp properly, it’s time to be a terrible person! I’ll show you one popular way of using lerp badly. Assume, for the following example, that the ‘speed’ variable is set to 0.1f.

tip-16_img04

tip-16_img05

I’ve tried to illustrate what happens on each frame here. At the start (on the first time interval), the sprite colour is at its original colour. At the second time interval (0.1s after starting), we have moved 10% from the original position towards the final position. This is easy to understand – we move 10% of the way between full red and full white (assuming the original colour was red and targetCol is white). On the next interval, we have travelled another 10%. However, the starting point was not the original red – it was 10% towards white. This means the current colour is 10% between the last colour and full white; it is now 19% towards full white. This process continues; rather than moving linearly between red and white, the end result is a curve.

The reason this works is because the time parameter we pass in is always a fraction between 0 and 1, but the start colour is always changing too. It’s not exact, but roughly every 0.1s, the colour will change 10%. The numbers above won’t be precise since the lerp is running every frame, not every 0.1s, but hopefully this gives you an idea of how this blasphemy is working behind the scenes. This isn’t how lerp is intended to be used, but it is a cheap way of moving between vectors, colours or floats on a curve. It’s disgustingly amazing – dismazing, if you will.

It’s also worth noting that if the parameter passed to lerp is set to below 0 or above 1, it will snap up or down to those boundary values. Now you should be a certified lerp expert! I’ve put both versions of the linear interpolation script online for you to download if you’re too lazy to copy them (which is only a problem because I’m too lazy to make them look nice without resorting to taking screenshots. My bad).

Game Design Tips #13 – [Unity] ScriptableObjects and Custom Project Gizmos

It’s been a while since my last Game Design Tip, but I’m back and ready to show off some cool things I started using very recently. Ever wanted to save data as an asset in Unity? Turns out, there’s a dead easy way to do that. I’d heard of ScriptableObjects before, but not used them; they’re a godsend for any task where you just care about keeping hold of static data for something – weapons, enemies, item drops, you name it.

I’ll take an example I was working on the other day. I have a load of guns that the player may own, each with their own cooldown rates, damage, clip size and whatnot. My strategy at the time would have been to create a MonoBehaviour script that holds a bunch of public variables, stick that script on a bunch of GameObjects and tweak their variables individually, then save them all as prefabs. Upon needing to read the data, I’d instantiate one of those objects (or have them all instantiated at level start), then read off all the variables. In doing so, I’d waste a bunch of memory loading up GameObjects whose sole purpose was to hold data, clogging up the RAM with redundant data and making the garbage collector mad.

tip_13-01

That was dumb.

Instead, I should have used ScriptableObjects, something Unity provides for this exact purpose. Instead of extending MonoBehaviour, we’re first of all going to extend ScriptableObject. That’s going to tell Unity that this script is special, just like every one of my readers. That’s my flattery quota for the day met!

tip_13-02

You’ll also notice we gave the entire class the [Serializable] attribute. This is provided by the System namespace (hence, that’s included on line 2) and tells Unity we’ll want it to do stuff to it to make it visible in the Inspector. In reality, it’s a lot more complex than that, but we don’t care for now, do we? We just want our data saved. Oh, and I’ve stuck this class in the WeaponClasses namespace for the hell of it, but you can ignore that if you so wish. In my example, WeaponType is just an enum to deduce which class the weapon falls under.

Now that we’ve gone about making our data serializable, we need a way to make these new Weapon objects. There’s probably many ways to do this, but I’ve used a bit of Editor scripting to get the job done. It might look a bit alien at first, but it’ll all start to come together soon.

tip_13-03

This is a brand-new script which doesn’t extend Monobehaviour, ScriptableObject etc. It just needs to import UnityEngine and UnityEditor, and the script must be placed under Assets/Editor. We use the [MenuItem] attribute to add a lovely menu entry for making new weapons – now, we’ll be able to click ‘Assets’ on the toolbar, hover over ‘Create’ and find ‘Weapon’ listed underneath all the usual entries. Clicking this places a brand-spanking-new Weapon under the path defined in the script (line 14) and focuses Unity on the new Weapon in the Project Window (lines 16 and 17). Just a word of warning – it’ll replace anything called NewWeapon.asset in that directory, so I’d rename it straight away! Now you’ll have an awesome new Weapon instance you can reference in your scripts without having to attach it to some empty GameObject.

tip_13-04

Not a typo, just a really fun thing for gunning people down.

I did a little more processing with mine using an additional, more complex Editor script to hide certain variables based on the type of weapon, but this is basically what you get when you click on one of your Weapon instances in the Project window. We’re done with ScriptableObjects now, but let’s go one step further and make a cool gizmo for our Weapons.

Weapon icon

This is the icon I’ll be using. It’s dead easy to tell Unity to use this for our Weapons; just save this under the exact name “Weapon icon.png” or “Weapon icon.tif” – only .png and .tif files are allowed. The syntax is [Class Name] [single space] [the word “icon”] [.png/.tif]. Super simple stuff!

tip_13-05

Now we have pretty-looking icons for our Weapons and a clean way to save data for each Weapon. Unfortunately, it doesn’t make them look different in the Inspector, but at least they have an icon in the Project view that makes them easier to find. I hope this has been helpful, and I’ll be back soon with more tips.

Epilepsy Simulator 2014

After staving off sleep for the past couple days, me and my friend Tom finished (well, sort of) our entry for the Warwick Game Design society’s two-week challenge, which had a theme of ‘reflect’. I showed a screenshot of it in my last post, but it’s come very far since then. It’s now got a name, Epilepsy Simulator 2014, which is only half a joke, because it will probably give you epilepsy (disclaimer: if you have epilepsy and play it, please don’t sue, we’re too nice to go to jail). So without further waffling, here’s a short video!

The basic premise of the game is: you have a laser gun. Black spheres drop down and try to kill you by touching you. Stave off said spheres using the laser gun. The laser will reflect off the walls, and when a sphere crashes into the wall, it has a chance of activating a strobe light on that tile of the wall (this is where the epilepsy starts). The lights get all colourful sometimes, and the more lights going, the easier it is to see the enemy spheres. The laser was ripped straight from one of my old projects, and was one of the easier bits to add.

es-02

It looks so pretty when everything’s lit up like this.

Tom (the other guy who was making this with me. Lives in the same flat as me. Cool guy.) had never used Unity before, so a lot of the programming for this project was me showing him how to do stuff with Unity, but he’s learning very quickly, much quicker than I did in the beginning. He also made the textures for the walls, which are about three times better than what I would’ve come up with, so have a gold star, Tom!

es-01

Dem textures, yo.

The next competition, which started yesterday has a theme of ‘Spooky’, which we’re currently in the process of thinking up ideas for. We didn’t win this first competition (sadface), but this game was so fun to make (because it’s completely bonkers), so here’s to another two weeks of game design. You can download it from the downloads page on IndieDB, my Dropbox, or the Warwick Game Design games page. Also, the music isn’t ours (it’s Savant – Snake Eyes), but we’ll change it if we ever do anything with this project that isn’t purely for fun.

-Daniel

I shall teach you new things! Project Spikes 9-11-13 Update!

Sorry I’ve took so long with this update, I’ve had stuff to do. And things. But without further delay, here’s the latest update! 

spikes-30There are new particle effects when you use a checkpoint, and a little “whooosh” sound effect that plays, hence they are infinitely cooler than before. More importantly than that, I’ve updated World 1 levels 1, 2, 3 and 4 (again) so they’re a little bit cleaner and, of course, textured. A newer level 5 will be coming soon, but so far it’s proven to be a bit of a nightmare, given how much is in the level. Each tile I’ve used to create the levels can now have a separate texture applied to each side, so each level should look tidier at the edges in particular.

spikes-34Perhaps the most important change in this update is the inclusion of an interactive tutorial, which guides new players into learning the mechanics of the game. This feels much better than the previous tutorial level and is a lot more enjoyable more than before, plus it’s much more useful at teaching the player the basic concepts of the game. Dotted around the level are mini billboards, which now have 64×64 images as opposed to the previous 32×32 textures, so my doodles are more detailed than before.

spikes-35I’ve also added a proper options menu, which is  copied just a little bit from one of my older projects (ctrl-C and ctrl-V are my friends). Here you can change your graphics and sound settings (from “basic” to “ermahgerd” for the video settings and 0-100 for audio), as well as check out your computer’s specs.

spikes-33

That’s about it for the bigger features in this update, here are a few smaller things:

-Turrets have sounds now! *pew pew*

-More scenery that can be blasted around using the force gun

-Medpacks will replace grapes as a health pickup (see picture above). I guess I’ll add food back in at some point though

-Running! Hold down left-shift to run, it’s a much better way of getting around

-Super-subtle code optimisation, it’s (probably) made things quicker than before

-Removed a random directional light in level 4 which was slowing things down rather a lot

I hope you enjoy playing! Have fun 🙂

-Daniel

Random Code: Pause Menu

Have you ever been creating a game when you thought to yourself, “Hey, I want to pause my game”, then you realised that you’re so silly that you don’t know how? Then this is the script for you!

private var paused: boolean = false;
private var mouseX: MouseLook;
private var mouseY: MouseLook;

function Start()
{
    Screen.showCursor = false;
    Screen.lockCursor = true;

    mouseX = GameObject.FindWithTag("Player").GetComponent(MouseLook);
    mouseY = GameObject.FindWithTag("MainCamera").GetComponent(MouseLook);
}

function Update()
{
    if(Input.GetKeyDown(KeyCode.Escape))
    {
        if(!paused)
        {
            paused = true;
            mouseX.enabled = false;
            mouseY.enabled = false;
            Screen.showCursor = true;
            Screen.hideCursor = false;
        }
        else
        {
            paused = false;
            mouseX.enabled = true;
            mouseY.enabled = true;
            Screen.showCursor = false;
            Screen.hideCursor = true;
        }
    }
}

function OnGUI()
{
    Time.timeScale = 1;
    if(paused)
    {
        Time.timeScale = 0;
        if(GUI.Button(Rect(Screen.width / 2 - 75, 200, 150, 25), "Back To Main Menu"))
        {
            Application.LoadLevel("StartMenu");
        }
        if(GUI.Button(Rect(Screen.width / 2 - 75, 250, 150, 25), "Back to Game"))
        {
            paused = false;
            mouseX.enabled = true;
            mouseY.enabled = true;
            Screen.showCursor = false;
            Screen.hideCursor = true;
        }
    }
}

This script isn’t too hard to get to grips with. First, we declare a few variables, and make them private so another script can’t come along and vandalise them. One to store whether we are saved or not, and two for each of the MouseLook scripts attached to the standard Unity first person controller. When these are initialised in the Start function, the script will look for the tags “Player” and “MainCamera” – in my project, these are the the tags assigned to my main camera and the actual player character, each of which have a MouseLook component. It also hides the cursor from view, and locks it to the centre of the screen.

Then, if the player presses the Escape key, it checks whether the game is paused. If it isn’t, then it pauses the game, disables the MouseLook scripts and frees the cursor; if it is paused, the opposite happens. In the function OnGUI(), which is called every time the frame is drawn and is used to draw stuff on-screen using the basic Unity GUI features, the time scale is set to zero when the game is paused, which stops all movement (this basically is the part of the script that actually pauses the game). Then it draws two GUI buttons, centred in the middle of the screen horizontally; one returns the player to the main menu, and the other unpauses the game. Pressing the first button will run Application.LoadLevel(“StartMenu”); which loads a level named “StartMenu”. The latter just unpauses the game.

PauseMenu1

This is the result when you pause the game, a basic menu with two buttons. In any case, I hope this helps, have fun coding!