I’m Making a Game Engine

It’s sure been a while since I last posted, well, anything. Part of that was me getting reacquainted with uni life, part of it was me adjusting to a real-person sleep cycle and part of it was me thinking about the game engine this post will be about. But most of it was just me being lazy because my last post was in early July, about three months ago. That’s my longest disappearance yet. Oops.

However, since I was last here, a lot has happened! As part of my third year at uni (I’m already halfway through, where does the time go?!), I have to do a big project about something to do with computer science; I’ve decided to make a game engine, which has resulted in some people thinking I’m a tad insane. I’m inclined to disagree – doing it will make me insane. Without further ado, introducing my concept: the Honeycomb Game Engine!

honeycomb_logo

At some point I will vectorise this image.

The basic idea is that Honeycomb will be geared towards people who don’t have all that much experience in game design or programming (or both!). The way I will achieve that is by turning the idea of a game engine on its head. Some game engines try to give the developer tons of tools for any imaginable situation, but I think this is overwhelming for a new user – that’s how I felt way back when I started using Unity, anyway. Instead of following in those footsteps, I’m going to try and condense my game engine down to easy-to-use key features and avoid adding anything that’s unnecessary. Essentially it will lie somewhere between Unity and Game Maker.

In my opinion, a beginner-friendly game engine should have most of the following features:

  • A clean interface with easy-to-understand buttons and menus for common tasks;
  • A way to add behaviour to game objects that is intuitive and doesn’t require writing tons of boilerplate code (a simple scripting language, for example);
  • A room-building tool that lets you add game objects to a room and snap them to a grid easily;
  • Support for common 3D modelling packages, such as Blender or Maya. I think supporting .fbx files is sufficient for this;
  • A big, red button in the corner of the editor that donates an energy drink to an exhausted game engine developer somewhere in the world;
  • One-button exports to the platforms the engine supports. Users shouldn’t have to sift through mile-long lists of options for their exports;
  • A UI designer toolkit that lets users place buttons, text elements and sliders on a virtual ‘screen’ that then gets overlaid onto the running game;
  • A ‘play’ button that lets users run their game directly in the editor, or at least build the game quickly and provide debugging feedback to the user. This is one of the most difficult things I will try to implement (it’s a stretch goal);
  • A material editor that lets users plug in values and textures for various parameters. Then users can drag those materials onto models in their game;
  • An animation toolkit that lets users control how models are animated and how different animations work together;
  • Coroutines. Holy hell, they are so useful in Unity while writing behaviour.
  • Many many more things that I’ve inevitably missed out!

Some of these features obviously require more work than others. For example, I plan to create a scripting language (called Honeycode, because I’m an awful person) that will get compiled to C++. The advantage of creating my own scripting language is that I can abstract some of the less beginner-friendly features of C++ and ignore some less useful ones entirely, while making assumptions about what Honeycomb provides. This way, I can bake engine integration directly into the language, similar to how the Unity API augments C# to provide Unity’s features.

Essentially, my motivation for the engine is to create something that new users can just pick up and start making things with, without having to spend hours with setup and tutorials. A user should be able to drag in a default character controller and immediately have working character input and movement, the whole shebang. They should then be able to easily add behaviour to objects in the scene in a way that feels natural – telling a sheep to jump 17 feet in the air when the player approaches should be a simple line or two of code. Obviously sheep don’t jump that high though, it’d be terrifying if they did. Or baaaaad.

So that’s my approach. I’m going to add in the absolute basic features that a new user will want or need and let them build everything else on top of that framework. To aid that, I’ll also try and write a bunch of tutorials and sample code to guide users into writing the more complex and weird stuff that I don’t think needs to be baked into the engine itself. That way, it’s not as if I completely neglect the existence of the more useful features, but I don’t just provide them for the sake of making my engine do your tax returns and make toast for you while you’re working.

One of the more exciting things about my project is that I’m going to try and use Vulkan, the shiny new graphics API by the Khronos Group. It’s sorta like OpenGL++, but not really. Khronos basically took the remnants of AMD’s Mantle API and created a cross-platform graphics API for the modern age, which allowed them to make different design decisions to the ones made during OpenGL’s development. As a result, the API provides much lower-level access to hardware, but this makes everything so much more verbose; it’ll be a challenge to implement Vulkan support, but I’m confident I can get it working with a little elbow grease. By that, I mean a lot of coding all-nighters. And hey, if it doesn’t work, I can always fall back to OpenGL.

I’ll be returning to this blog every now and then to document my progress, and when the time comes, upload working downloads for people to try out the engine. That’s a very far way off currently though! I hope this whirlwind tour of my plans make sense, although I’ve probably missed some stuff out, so let me know if something doesn’t make sense. It’d actually be hugely useful for me to know what people’s most requested features or major gripes about their choice of game engine or development tool are, so feel free to bellyache and rant in the comments section about something your game engine does that you think could be improved!

Unity Super-Helpful Tips: Scripting

unity-logo

This is the first in a series of (hopefully) helpful mini-tutorials and tidbits of knowledge I’m gonna be passing onto you, my loyal readers! I say series – you know how these things usually turn out, but I’ll do my best! There’s a wealth of hidden tricks that some of you won’t know about – the point of these posts are to reveal them to you all in their globally-illuminated beauty. I swear Unity 5 hasn’t gone to my head. This post will focus on scripting – I’ll be using C# examples mostly, but these tips should also be applicable to Unityscript.

Changes from Unity 4 to 5

First up, only a tiny change, but an important one; you know all those helpful property getters such as xxxxx.rigidbody, xxxxx.renderer, etc? They got killed off in Unity 5. The API changed, and to better modularise the codebase, these properties no longer exist. A moment of silence for our fallen friends, please. With the exception of .transform, which stays because it’s part of Unity’s core module and not the physics or rendering modules, you’ll need to use something like:

myComponent = GetComponent<MyComponentType>();
myTransform = this.transform;     // Still fine.
myGameObject = this.gameObject;   // Fine, part of MonoBehaviour.

Don’t worry though – Unity 5 ships with a tool for automagically finding usage of the deprecated API and switching usages of it for the new one, so switching old projects to shiny new Unity 5 goodness is a breeze. 

Attributes: Serializable and SerializeField

These are two very helpful attributes I use a lot – SerializeField can be used to make any variable appear in the Inspector, even if it is private.

private int myInt = 0;
[SerializeField] private float myFloat = 0.0f;

The first variable, myInt, won’t show up in the Inspector, as it is private. However, myFloat has the SerializeField attribute before it, so it’ll defy its private modifier like a moody teenager and show up in the Inspector anyway – super handy if you have variables you want to change quickly AND keep private.

Serializable is useful for taking entire private classes and making them visible to the Inspector. But when would that be useful? Say you had a particular kind of object that makes it easier to hold a set of values, but then you only need those objects in a different class.

using UnityEngine;
using System.Collections;
using System;

public class MyClass {
    [SerializeField] private DataHolder dataHolder;
    // do other stuff in the class like usual...

    [Serializable]
    private class DataHolder {
        // variables, methods like usual...
        // can only be accessed from MyClass.
    }
}

In the code, no external class can access the DataHolder class, but since we have added the Serializable attribute, we’ll be able to access any public variables stored in DataHolder in the Inspector through MyClass’ dataHolder variable. It’s also worth noting you’ll be able to see any of DataHolder’s private variables if you prefix them with a SerializeField, too, and you can have arrays and lists of DataHolders. Since Serializable is contained in the System namespace, you’ll need to put “using System;” at the top of your code, too.

Preprocessor Directives – different code based on export platform

One of the great things about Unity is its portability – it exports to EVERYTHING. But what if you wanted one script to do different things based on the platform it’s on? A great example would be controls, which are completely different on mobile compared to desktop. There’s a way to do this using preprocessor directives. Don’t let those huge words dissuade you, they’re easy as hell to put in and very useful!

#if UNITY_EDITOR
    Debug.Log("Only runs in the editor");
#elseif (UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8)
    Debug.Log("Only runs on mobile");
#endif

With these, you can make different parts of the same script become invisible to the platforms they’re not needed for. There’s a whole host of Unity-specific directives, and (in C# at least, I’m not sure about Unityscript) there are many more ways to utilise them.

Invocations and Coroutines

Both of these are hugely useful, and you ought to be using them all over the place. Invoking a method is basically like telling Unity “Do this please. But not yet – maybe in five seconds”. You can even go as far to say “Well, do this thing in seven seconds. Then every three seconds after that” using InvokeRepeating.

Invoke("MyMethod", 5f);
InvokeRepeating("MyRepeatingMethod", 7f, 3f);

Coroutines are a bit more of a pain in the ass to get working, unfortunately. It’s a shame, because they’re awesome. Coroutines are a special kind of method that allow you to use yield statements – in non-jargon terms, you can tell a method to hold its horses and wait for a few seconds, or until the end of the current frame, amongst other things. There’s the CancelInvoke() method too, which will remove all invoked instances of the method passed in and stop them being executed after their waiting time.

void Start () {
    StartCoroutine("DoStuff");
}
private IEnumerator DoStuff () {
    Debug.Log("I'm gonna do stuff");
    yield return WaitForSeconds(2f);
    Debug.Log("I did stuff! Woo!");
}

It’s worth noting a few things: in C#, a coroutine must be called with the StartCoroutine() method. You can pass in the method name as a string (plus one parameter after a comma), or like this

StartCoroutine(DoMoreStuff(5f, 7f, 9f));

which is far more useful for any method that requires more than one parameter. The coroutine method itself must have a return type of “IEnumerator”, and will break horribly if it doesn’t return any yield statement. The “WaitForEndOfFrame()” yield type is really useful because it lets you call code after LateUpdate() has finished doing stuff – consult the order of function execution diagram for more information. Seriously, that thing’s basically the equivalent of the 10 Commandments for Unity Developers. There’s also a StopCoroutine() method which is effectively the analogue of CancelInvoke() but for coroutines.

I’ll be back soon with a heap of useful Unity things soon – it probably won’t be scripting next time, but we’ll be digging into the engine itself.