0 Unity and the Garbage Collector

This is something I knew I had to deal with sooner or later. Not that this is the right moment to start worrying about memory or performance, but I felt the need to at least understand how this is going to affect the game when it comes the time.

I like to write declarative code and C# is very good at it, which is kind of evil if you ask me. In imperative languages you write code that describes how things have to be done. In declarative languages you write code that describes what's to be done no matter how, which basically means: the more you move away from imperative towards declarative, the more you allow your programming language, run-time or compiler do things its way, not yours.

In the case of Mono for Unity, letting it to do things its way will result in hundreds of thousands of little memory allocations, which is not a big deal since allocating memory on these platforms is really cheap, The problem is that this massive amount of allocations causes the garbage collector to kick-in quite often. While garbage collection is not a bad thing in itself, it's definitely something you want to avoid at all costs in FPS-sensitive games.

There are three main sources of declarative awesomeness that will feed the garbage collector heavily:

1. Closures


Every time a closure is called, the CLR will allocate memory to create an object which contains all the captured state. Place this within a tight loop and there you have it. Since I love the succint and concise code you can write with them, I tried to get around this limitation. I came up with a solution which consists of just stripping out the state and turning them into mere anonymous functions like this:

/// <summary>
/// Turning a closure into an anonymous function
/// </summary>
public void DoSomethingstring _name )
{
    // this will capture the parameter _name, thus creating an object
    Closure( () => _name );
    
    // this version will 'capture' _name as a parameter, 
    // thus turning the closure into a mere local anonymous function
    ClosureNOT_name_n => _n );
}
 
public void ClosureFunc<string> _getStrFn )
{
    var str = _getStrFn();
    // ...
}
 
public void ClosureNOTstring _strFunc<stringstring> _getStrFn )
{
    var str = _getStrFn_str );
    // ...
}


2. The 'foreach' keyword


It's hard to imagine how much evil is hidden under this keyword. Unless the underlying type is known at compile time to be an array, two things will happen:

-Due to a bug, each call to foreach (not every iteration!) will cause the returned Enumerator object
to be boxed, thus eating 24 bytes of memory in the way. This is an ancient known bug but it's still not fixed in Unity 4.6

-For every iteration, the 'MoveNext()' function is called, which performs some kind of validation. A lot of people will argue that this is not an issue, but in my case, using iterators within high-frequency functions (which is quite common in video-games) will kill the frame rate.

3. LINQ:


Using LINQ extension methods is just like using 1. and 2. but on steroids. Nearly every function in there will not only allocate closures and foreach calls, but also a lot of temporary arrays and lists.

If you want to be safe, try to stay away from the declarative part of C# and just make your sensible code look like C++.




It's been a lot of time since I updated this blog for the last time. It would seem that the project had been abandoned. Far from it. I've been actively working on this project but I realized that maintaining a blog requires a lot of work and energy and I just don't have the time.

During the past few months I've been working on the prototype and now I can say I have something going on. I've also found a couple of people who are willing to help with design so I can focus on programming.

That's all I can say for now...

0 Scripting with Unity 3D: Coding "into" Unity vs. Coding "in" Unity

Looks like Unity is going to stay around for a while. It's getting better with every version. Much wanted features are added, new platforms are supported, better performance, better graphics... and the list goes on. If I were to create a start-up today, Unity 3D will be my tool of choice hands down.

However, let's not forget it's a tool and it's not going to last forever. Eventually, some other tools will flourish, embracing new technologies, new devices, new platforms, better languages, or just being cheaper or having an editor with all beautiful colors. Of course this doesn't mean you'll quit making games. This means you'll go through the painful path of learning new ways of doing the same old stuff. It's always been like this. Although there's no way to get rid of this learning curve, wouldn't it be nice to try and minimize the impact? Certainly you can't prepare yourself for an imaginary tool that doesn't exist yet, but you can do things that will help you in the future.
"Programmers who program "in" a language limit their thoughts to constructs that the language directly supports. If the language tools are primitive, the programmer's thoughts will also be primitive.
Programmers who program "into" a language first decide what thoughts they want to express, and then they determine how to express those thoughts using the tools provided by their specific language."
(Steve McConnell - Code Complete) 
I think this is true not only for languages, but for any means to an end. I'm not saying that Unity is primitive, but it's just a medium and thus it's limiting by its own nature. Knowledge and experience are never replaced but tools and technologies are, so I'd rather put technology at the service of knowledge and not the other way around.

In object-oriented programming, when some part of a program needs to interact with some other part, it's usually done in the most abstract way possible, normally through interfaces or abstract classes. A lot of the cool features found in OOP, if not all, stem from sheer common sense, so wouldn't it be wise to apply common sense for everything? My common sense dictates me that while coding into Unity, or whatever medium for that matter, I try at the same time to stay away from that medium as much as I can. I usually code as if I had to port my game to a different medium tomorrow, forcing me to separate medium-agnostic code from medium-dependent code, which in turn forces me to first think in medium-agnostic terms and thus not producing medium-dependent thoughts.

Following this premise, my common sense also tells me to not put all my code in scripts. Because not every piece of code needs to be a script. I regard scripts as if they were little wrappers encapsulating some medium-specific features, like manipulating some GameObject's transform, playing a sound, reading input, tweaking some camera's properties... you get the idea. I put the rest of the code in normal classes and make sure these classes don't reference medium-dependent assemblies. (In practice this is usually not feasible since you'll probably be using some of the medium's basic types for everything, like Unity's Vector3, but I like to think of them as coincidental dependencies)

But, why bother? Doing things like this will make you slightly slower, probably. Let's say it makes you 10% slower. If you look at the final product, it may seem you wasted 10% of your resources by doing it in a different way just for the sake of it, but it's not the case. Actually you've invested that amount in modeling, sharpening and polishing your own tools, like your way of approaching problems and the way of coming up with solutions. Not a waste at all. Even if Unity is here to stay forever.