A Strange Camera System in Unity: Part I

Our friend Brett Fowle has another quite awesome tutorial featuring StrangeIoC. This time, Brett delves into structuring a familiar demo scene with a more flexible camera. Includes some nice examples of mocked unit testing.

Screen Shot 2013-10-30 at 1.44.29 PM

http://unity.bfowle.com/2013/10/strange-camera-system-unity-part-i/

Advertisements

Generic tears don’t mean you’re cryin’ over nuthin’

If you’ve been keeping up, you’ll know the main focus of feature development in Strange these past few weeks has been around pooling. Yesterday my pooling implementation hit a serious snag so now you get to hear me sing the blues.

Image

My thinking around the implementation of pooling has shifted around a lot as I’ve worked it over. Remember that it needs to function as an internal mechanism for Strange, but also as a useable tool for other developers (i.e., you). My latest iteration felt really simple, which I usually take to be a sign that I’m on the right track. It looks (from outside) like this:

//A pool is:
Pool<TypeOfInstancePooled>
//Bound in the Context like this:
injectionBinder.Bind<IPool<ISomeInterface>>().To<Pool<ImplementingClass>>();
//And Injected like this:
[Inject]
public IPool<ISomeInterface> myPool { get; set; }

Notwithstanding all the brackets, this is really nice to me: I’ve declared my dependency but kept it as broad as possible: something that implements IPool; it generically handles instances which implement ISomeInterface. The concrete dependencies are left (as they usually are in Strange) to the binding Context.

But there’s a flaw in the plan. Old hands at Unity/C# (well, older than mine, anyway) will see it I expect. This elegant flow relies on something called covariance. Covariance is a high-falutin’ way to describe the property of broadly-defined types (such as interfaces and abstract classes) to be assignable from narrower types (the classes that implement/extend the broad types. This, of course, is how Strange does its most important job, dependency injection, by allowing you to declare a dependency on ISomeInterface and fulfill that dependency with SomeImplementer.

Well, boys and girls, it turns out that this simple idea is a great big pile of fail because, you see, covariance wasn’t implemented for generics in C# until 4.0. And as you probably know, Unity uses something that ain’t quite 4.0, so no-covariance-in-generics-go-to-bed-without-any-supper-for-you.

I am Le Sad.

My current plan (not wanting to make the Perfect the enemy of the Good) is to carry on as I am, with the obvious, frustrating limitation that all Pool bindings will need to be concrete. While this kinda blows, I think the larger value of pooling outweighs the sin of a handful of concrete dependencies.

What do you think? Is there a better way to rethink the problem? Can you salve my conscience with something fine and smoky, perhaps from Islay? Constructive input welcome!

Waiting for Pools

Waiting for Pools

Been a little quiet on the blog lately. Never fear. This has nothing to do with a lack of work on or interest in Strange. Rather, the vast majority of my Strange attention has been focused on implementing a long-promised feature: Pools. My thinking on pooling changes almost constantly, so I’m hesitant to say too much yet about what form the final implementation will take (though you can always follow the commits on the ‘pool‘ branch). But what I can speak to are some of the uses of pools and how they will make your Strange life better.

What is a Pool? Why should I care? Can I please go read The Oatmeal or XKCD now?

No. Stay here. This is important.

Object creation can be expensive. In processing terms, expensive means that a process uses up performance resources or processing power that you’d rather have going to your amazing game. Every time you instantiate an object, a certain amount of memory gets allocated to storing the result (and a puppy dies…not that you care, you heartless bastard). As important, when you destroy an instance, that memory needs to be released. In Unity, most of this work is hidden from us via a process known as reference-counted garbage collection. That just means that once there are no references to an instance, that instance is marked for garbage collection (GC). At some interval, the garbage collector sweeps through and removes your discarded junk. The less GC you require, the more processing gets to go to the chills and thrills that make your game fun. You don’t want to waste resources, especially if you’re running on a mobile device where resources are very precious.

A pool is a mechanism for minimizing the creation and destruction of objects. Just as you recycle real-world refuse to make efficient use of resources, so a pool allows you to recycle (and be more efficient with) your instances. Simply put, you create some objects; when you’re done with one of them, instead of destroying it, you return it to the pool for later reuse.

OK, Got it. What’s this got to do with Strange?

Strange has been rather a bad citizen on the recycling front. While I’m not exactly clubbing baby seals, Strange doesn’t really play well as a delivery system for Events on your main game loop. The reason is that every time you dispatch an Event, you create a new TmEvent instance (Signals don’t have this problem). Every time you fire a Command, a new Command instance is instantiated. This is clean and simple (and why I wrote it this way on my first pass), but as you’ll now understand, not very environment-friendly. If you have an Event mapped to a Command running on your main game loop, you’re creating two throwaway objects 30x/second (or whatever your frame rate is). Depending on what else is happening in your loop, you might be creating/destroying lots more.

So the main use of pools for Strange is added efficiency. When pools are done, you should find Strange far better suited to use in a main game loop. Events and Commands will draw from pools and then be recycled, so there will be far less waste.

A secondary — though no less important — use case for the Pool is manual recycling. Currently you can map an injection as either Singleton, Value or Factory. Singleton and Value are efficient, since they both store a single instance. Factory is inherently wasteful, since you create a new instance every time you need one. In the new sexy, you’ll be able to map a Pool, and the Pool will create either a fixed number of instances, or else as many as you require, recycling the instances that you’re done with. Consider this in the context of a field of enemies: you can pool the enemy prefabs, then recycle instances as they vanish offscreen or are destroyed, claiming them back from the pool when you need new ones. This is much more efficient than throwing old objects away and re-instantiating.

So that’s what I’m up to. Hope you agree that it’s worth the time spent and the whisky drunk. I’ve been moving forward pretty fast in the last week and hope to have some Strange Pools to share on dev very soon!