Is Strange Right for You?

Ask your Doctor

A user on our forum — going through the teething pains most of us experience when learning IoC — asked us about Strange’s suitability for use with Unity. I was happy to oblige with something of an empirical defense: look at our user base, all the studios, all the cred we have inside and outside Unity. Of course Strange is suitable!

But still, I conceded, suitability for some cases doesn’t automatically imply that Strange is right for him or his project. It’s not a one-size-fits-all question. Rather, the answer lies somewhere on a continuum. So how do you know if Strange is the tool for you and your project? So glad you asked!

Strange has several advantages — and a few disadvantages. The more your intended project plays into these strengths, the more likely you would want to apply it. And even when applying it, a sensible understanding of the weaknesses should help you understand exactly where in your product Strange is best applied. In this post, I want to suggest some metrics by which you can make these decisions, none of which will be affected by the upcoming release of StrangeIoC 1.0.

Complexity (yours)

Perhaps more than anything, Strange is a tool for dealing with code complexity. Is your project likely to be complex? If I’m throwing together a quick example, or building Tic-Tac-Toe, I’m probably not going to be motivated to use Strange. The bigger my project, though, the more likely I will want something to handle my dependencies in an elegant manner.

Complexity (ours)

There can be no denying that Strange has a learning curve. For some, it’s pretty steep. To use Strange, you and your team need to learn to use it. They need to understand not just how Strange works, but why. The end benefits are pretty impressive, but only if they’re used according to the manufacturing instructions. If you’re just learning how to code, it might be good enough simply to know that we exist. Learn the basics and come back when you start to understand why code decoupling is a problem you want to solve. Similarly, if you doubt your team’s ability to circle up around a framework, don’t worry. Just put the blame on us.

Programming AbilityTeam Size & Complexity

Team size is also an issue of code complexity, with a slightly different twist. In this case, we’re thinking about the myriad styles in which different coders code. This difficulty can be mitigated with coding standards, but just as every writer has a distinct voice and syntax, so every coder implements ideas in her own inimitable style. That’s great up to a point. But when you have a large team and a tight deadline, ironing out these differences such that I can jump into your code and you can jump into mine can be the difference between making a deadline or not. Opinionated  frameworks like Strange tend to urge you to code in a particular way, leading to greater homogeneity. For lots of common problems, the architectural solutions become obvious and automatic, so you don’t need to spend time thinking about them. When you move from class-to-class (or even from project-to-project!) the code looks familiar and you can get right into it with minimal learning.

Additionally, Strange’s management of multiple Contexts means that teams or team members can break a project into sub-modules. Each module can be built independently, then joined up near the end of the development process.

Team Size & ComplexityVolatility

Another key selling point for Strange is its inherent resilience to change. A simple project is unlikely to change much. A real product operating under real world circumstances (with customers, producers, product managers, data analysts, etc. all urging you for fixes, new features and enhancements) might alter considerably. And these alterations may not be predictable or under your control.

The more volatile your project and environment, the greater the odds that you need the ability to adapt.

Code VolatilityPerformance

“How much performance do you need?” The knee-jerk reaction, naturally, is “all of it”, and that’s fair enough. Strange manages performance hits related to reflection, but even with that, there’s always going to be modest overhead related to requesting an injection. Usually, this is tiny when compared with driving your visuals or running an AI algorithm, but even so, we, like you, want to minimize overheads. For this reason we typically suggest keeping your Strange-related activities to a minimum in your most performance-hungry loops.

So be realistic about your performance needs. In a turn-based game or even for occasional events in a shooter, Strange’s overhead is negligible. The nearer your game approaches the realm of performance junkie, however, the more you want to limit its activities.

Performance requirementsTestability

Unit testing is a huge win…some of the time. It can also be a burdensome time-sink. Which one it is for you is a matter of experience, expertise, and personal preference. Generally, I find that testing my models and services is advisable. Testing controllers depends on complexity. Views are often hard or impossible to test. Whatever your opinion, if you value testing at all then offloading code away from MonoBehaviours makes unit testing possible. You don’t need Strange to do this, but it sure helps.

Code testabilityIntegration with other Assets

I’ve not had much trouble with this, but it’s possible you might. One of the very first wins I personally got from using Strange was isolating nGUi into a handful of View classes, thereby keeping it away from everything else. When uGui came along, refactoring was a breeze. Some assets unsurprisingly employ tactics that Strange philosophically opposes, such as using Singletons or attaching non-View logic to MonoBehaviours. Again, for me this has been a net win for Strange, because I can isolate those “bad” practices, wrap them in an interface, and keep them from infecting my code base. If I someday decided to swap one asset for another, I have minimal refactoring to do, since I never let them get out of control.

Now, I can’t guarantee that you’ll never run across an asset that doesn’t play well with Strange. Let’s assume you do. In that very rare case, you may need to shoehorn some logic in a weird, crazy patch. Disaster? Not in my book. If 90% of my code is well-managed, I’ll gladly accept 10% patched together. I’m still beating the odds handily.

Plays well with other assetsPlatforms

Unity deploys to an awful lot of platforms. Strange hasn’t been tested on all of them. We’re good for the obvious stuff (iOS, Android, standalone and web). Follow this link for the complete list of platforms where we’ve validated our framework.

Are we Strange yet?

As you can see, Strange offers many advantages as your code gets complex and volatile. Among these are insulation, flexibility, modularity, and testability. It also comes with a learning curve and some very modest performance costs. So is Strange right for you? I think you’re ready to answer for yourself.

Owning my responsibilities

Today’s post is not precisely about Strange so much as about keeping one’s eye the fundamentals.

As you might already know, we’ve been working on adding editor functionality so that you can create StrangeIoC-based Extensions for Unity. I usually approach a new project like this in a few simple steps:

  1. Quick and dirty proof of concept
  2. Refactor and tighten
  3. Test and correct

As you can see I’m not really a TDD guy, though I end up with a similar product.

In step one, I copied and pasted the MediationBinder and hacked a version that would work with EditorWindows. This led, in step two, to an obvious refactor: extracting commonalities between MediationBinder and the new EditorMediationBinder into an AbstractMediationBinder. And Oh Look! all those commonalities – freed from the surly shackles of MonoBehaviours – reveal big chunks of testable code!

This has always been an Achilles’ Heel for Strange. The untestability of the mediation package has meant that we have never been entirely certain of the quality of our code in this part of the framework. Because of this, we necessarily approach changes here with a lot more caution then we might do any other part of Strange.

My buddy Will saw this and immediately went to town with a further refactor. The result is amazing: virtually the whole of the (Abstract)MediationBinder is now open to unit testing. The bits that aren’t tested simply represent specific lines where we supply access to the MonoBehaviour-specific API. All the rest has been abstracted away.

The practical result for you – whether or not you care about Editor extensions or even unit testing – is safer, more reliable code in an area of the framework on which you probably rely a great deal.

The mea culpa and moral of all this: the single responsibility principle exists to help us. My failure to consider this fully when writing the original version of the MediationBinder is only coming clear to me years later. Had I broken down the elements of my methods into smaller atomic parts back then, we probably wouldn’t have written off the whole of this package as untestable.

Lesson learned.

ListensTo: The Sound of His Master’s Voice

Just a quickie post to introduce you to a nice enhancement, now part of the upcoming Strange release.

The sound of his master's voice.

Good Will Corwin, author of Strange Signals and my co-owner of StrangeIoC, has added a feature that allows you to remove some unnecessary legwork from your Mediators.

How many times have you typed some variation of this?

[Inject]
public MySignal mySignal {get; set;}

override public OnRegister()
{
    mySignal.AddListener(listenerMethod);
}
override public OnRemove()
{
    mySignal.RemoveListener(listenerMethod);
}
private void listenerMethod()
{
    //Took a lot of lines of code to get here
}

Now in the whole, vast scheme of things, this isn’t the worst thing in the known universe (I reserve that kind of derision for blended whisky). But it’s a lot of boilerplate, and pretty annoying when you’re trying to code as fast as you think.

Will’s latest work gets us to the same result a lot faster, and just as clearly:

[ListensTo(typeof(MySignal))]
public void listenerMethod()
{
    //Wow! That was fast!
}

[edit]I changed the method accessor above to ‘public’. Only public methods are  scanned for ListensTo. ‘private’ and ‘protected’ methods aren’t scanned (we always try to minimize the costs associated with reflection), so there’s no simple way at present to throw an error and alert you if you mark the method incorrectly. We’re looking at whether we can do this better.[/edit]

The ListensTo attribute allows us to implicitly handle injection, and the adding and removing of Signal listeners at the default moments, thereby making your code that bit more concise and manageable. As with anything to do with reflection, we encourage you to be cautious with this use in your main game loop (i.e., don’t create and destroy lots of Mediators at performance-critical moments…this has always been the case).

The new version of Strange is fast approaching. You can see the evolving feature list here: https://github.com/strangeioc/strangeioc/wiki/TODO-list-for-next-version.

It’s probably worth pointing out that these features are in flux…and we’re not ruling out more. If there’s something you need or just really want, please let us know!

New feature: Editor Views within Editor Contexts

At the SF Unity User Group a few nights ago, one gentleman asked me (as he had in fact once before) whether Strange could be used within the Unity Editor. He wants to do a better job building Editor extensions, and he’d like it if we could assist.

sherlock_strange

Sure, I said, if you want to build in the necessary changes. I wasn’t too keen to do the work myself…how many people actually have this need? But the more I thought about it, the more I decided it was an appropriate use case…and it didn’t actually seem that hard. We’d mostly just need a specialized Context and a specialized MediationBinder.

So I’ve been whirring away at this for a day or two, and the (definitely not-ready for production) alpha is now on branch feature/editor. It principally involves a new extension package called ‘editor’ that includes the following classes:

  • EditorContext (same as Context, but specialized for Editor)
  • EditorContextException (for reporting errors)
  • EditorMediationBinder (a specialized variation of MediationBinder)
  • EditorMediator (similar to, but with important differences from, Mediator)
  • EditorMVCSContext (a specialized variation of MVCSContext)
  • EditorView (like View, but we extend EditorWindow instead of MonoBehaviour)

Please review the code. For the most part, there’s not a lot that’s surprising. But we do have some differences to discuss, which I’ll get to after I (finally) get to our actual headline.

In order to test my work, I’ve started working on a StrangeIoC inspector. The beginning of this is also on the branch. Thing is, I don’t do a lot of Editor extension work, so I’m not entirely sure how to proceed. And any way, what features would be most useful? So I’m going to start working on this tool-thingy as part of the next release, but I’ll probably come to you via this blog to generate ideas and help me fix the things I break.

OK? Ball’s in your court my friends.

Moving on, here are some things you probably want to know about the differences between regular Strange and Editor-extending Strange.

There’s a lot more working around statics

EditorWindow features seem to be built on a lot of static methods. This isn’t helpful in a Strange world. On the other hand, Strange can help isolate a lot of this silliness. For example, my StrangePanel already has a ScriptReloadService to isolate the service aspect of knowing that scripts have been updated. This helps with abstraction and keeps my StrangePanelView focused on View-related behavior.

There’s no ContextView

Traditionally, we kick off a Strange app with a MonoBehaviour at the top of a view hierarchy. This doesn’t make sense in Editorland (the most magical place on Earth), where we instead use the [InitializeOnLoad] attribute. What’s nice about this, though, is that [InitializeOnLoad] means our package is just plain up-and-running when we enter Unity. And there’s no need to track or think about which View is “on top”.

There’s no Cross-Context behavior

At least for V1, this seems OK to me. It’s a bit hard to say at this point whether we want multiple contexts in a single Editor extension. I suppose we might. Anyway, let’s cross that context when we come to it.

To be clear, I’m talking about multiple Contexts in a single extension. I’ve made sure to handle the possibility of more than one extension, both of which happen to use Strange (this is called ‘optimism’). Each extension gets it’s own Context within which to operate.

EditorMediators are not Views

In regular Strange, your Mediators are MonoBehaviours, so in some respects they’re just like Views. I’m not even sure I could make this happen in Editor-flavored Strange, but I really didn’t try. EditorMediators now actually behave much more like Mediators in Robotlegs, in that they are in contact with the View, but unable to perform actual View logic themselves. This doesn’t seem like a problem to me. You’ll have to let me know if you disagree.

For the EditorMVCSContext, Signals are the primary event bus

I’ve been thinking about doing this in the rest of Strange, where the primary event bus is still EventDispatcher. For Editor, this seems an obvious thing to do, since Signals really are a better approach, and we may as well hit this brave new world with the best tools.

Review and Comment

As always, I ask you to look at this now, before it’s a fait accompli and in the live product. It’s better for everyone if this work is challenged and vetted a lot before we use it in anger.

And let me know what you want/need in a Strange Inspector. Should we be able to inspect our bindings from there? Write them? List all our Contexts/ContextViews? Give me some ideas!

JSON and the (A/B)rgonauts

argonauts
As far back as Robotlegs days, I’ve been wanting to drive my bindings from JSON. It would be cool to change the behavior of my app without requiring a recompile, just by editing a text file. And in these days of mobile apps, the utility of doing this could be greater than ever before.

Since this is now a feature in the works (on branch json-binding), let’s talk about a key way you might put this to use.

The basic paradigm

The new feature allows you to take a properly formatted blob of JSON and feed it to a binder. For example, some JSON like this…

[
    {
        "Bind":"strange.examples.strangerocks.game.IGameModel",
        "To":"strange.examples.strangerocks.game.GameModel",
        "Options":["ToSingleton", "CrossContext"]
    },
    {
        "Bind":"strange.examples.strangerocks.game.IGameConfig",
        "To":"strange.examples.strangerocks.game.GameConfig",
        "Options":["ToSingleton"]
    }
]

…can be loaded from a text file or server and fed into Strange like this.

//after I've loaded the JSON file...
injectionBinder.ConsumeBindings(injectionBindingJson);

Once consumed, your binder will implement these bindings as if they had been written out by the following code:

injectionBinder.Bind<IGameModel>().To<GameModel>()
    .ToSingleton().CrossContext();
injectionBinder.Bind<IGameConfig>().To<GameConfig>()
    .ToSingleton();

With this new feature, you can write most instructions you’d write in the Context, such as injections, View/Mediator bindings and Signal/Command bindings, but in JSON instead of in C#.

Side-track: a quick intro to A/B Testing

(If you’re already clear on what A/B testing is, you might want to jump to the next section.)

To my thinking, one of the best uses of runtime JSON bindings is A/B testing. A/B Testing is an analysis technique for tuning application or game features. You have an idea that some feature in your game could be better than it is, so you experiment. You segment your user base: some users will see the feature one way (the ‘A’ segment), others will see it a different way (the ‘B’ segment).

A simple example:

There’s a button you really want your player to click, maybe the entrance to your in-app store. Your UI designer says the button is in the wrong spot. OK. Test it.

Create a segment of users who see the button in the new spot (‘A’ segment) and a control group (‘B’ segment) who see it in the old way. Who goes into the store more? The ‘A’ group or the ‘B’ group? You can use an analytics tool like Unity Analytics to find out, and decide whether or not the UI designer was correct.

This technique removes a lot of the guesswork from understanding how your players behave.

The fault in our binaries

In the traditional approach to A/B testing, the app contacts a server which sends back some numbers/strings to express the terms of the test (in our example above, where to place the button). If the test is particularly radical, the server might return a completely different binary. That might be acceptable in a web app, but a different binary is impractical and usually against the terms of service on mobile and consoles. This means that for really powerful A/B tests, you need to release a new binary for each test…possibly even multiple binaries.

At this year’s GDC, one speaker told our audience that they don’t do A/B testing on iOS. Why? The release cycle through Apple’s App Store is too slow. Sure, a server can feed in a few numbers and strings, but their tests are too complex for that. They need to alter how the game runs, and they just can’t release new binaries fast enough to work effectively with iOS. So they test on Android. Needless to say, this pretty much surrenders any hope of understanding how their iOS market differs from their Android market; and it’s well understood that these two platforms differ in many important ways.

So what if you could run a battery of tests without releasing a new binary?

This is where I think JSON bindings become really useful. With a little foresight, I can include numerous permutations within a single binary, all ready to be bound together based on instructions from a server.

Example:

Hypothesis: The user will be more likely to make an in-app purchase if they receive a call to action when they fail at a level.

Test: Do users upgrade if presented with a screen directly after failing a level?

Segment ‘A’: (Test Group)

[
    {
        "Bind": "mygame.signals.LevelLostSignal",
        "To": "[mygame.commands.LevelCompleteCommand, 
                mygame.commands.PresentUpgradeOptionCommand]"
    }
]

Segment ‘B’ (control GROUP):

[
    {
        "Bind": "mygame.signals.LevelLostSignal",
        "To": "[mygame.commands.LevelCompleteCommand]"
    }
]

Example:

Hypothesis: The AI on level 7 is too hard.

Test: Which AI allows an acceptable number of players to beat level 7?

Segment ‘A’: (Test Group)

[
    {
        "Bind": "mygame.ai.IEnemyAI",
        "To": "mygame.ai.EasierLevel7EnemyAI"
    }
]

Segment ‘B’ (control GROUP):

[
    {
        "Bind": "mygame.ai.IEnemyAI",
        "To": "mygame.ai.Level7EnemyAI"
    }
]

Segment ‘C’ (A/B tests can be A/B/C/D/E…So this is another test group):

[
    {
        "Bind": "mygame.ai.IEnemyAI",
        "To": "mygame.ai.SuperEasyLevel7EnemyAI"
    }
]

As you can see from these two trivial examples, runtime JSON bindings open up the whole of your binding infrastructure for testing and tuning without the need to release a new binary. This isn’t a magic bullet, of course. You aren’t going to turn Pac-Man into Assassin’s Creed on the strength of a few binding changes. But the ability to broaden the scope of what you can consider testable, and even compose fundamentally new tests without a new release cycle, should put a little extra power into your hands.

When does JSON set sail?

The code is available today on the branch mentioned at the top. I’d love to have it tested and any bugs exposed before we make it officially a part of the next release of StrangeIoC.

Do you Strange?

Today’s post is just a quickie.

Alongside our rapidly developing next version of Strange, we’ve been working on an updated website. The new site contains two new community-oriented pages:

Strange Projects

This page will feature released projects that have utilized StrangeIoC. We’re encouraging you to submit anything you’ve built…a game or app, on web, mobile, standalone, etc, that shows how you are putting Strange through its paces.

Other resources

This page is part of our ‘Help’ section, and provides, alongside all our other documentation, links to code samples, tutorials, videos, and anything else that can help a developer learn and grow with StrangeIoC. If you’ve written a blog post, created a presentation, or done anything else that could help your fellow coders learn to do Strange things, we’d love to include it in our list.

Thanks friends. Keep it Strange!

A farewell to names

This past Saturday I woke up with a surprise. For some reason the answer to a problem that had lingered subconsciously for years inexplicably bubbled up fully formed into my head.

The name blame game

The problem was naming: specifically, named binding injections in Strange. Named bindings is a solution to an important problem, solved by our friends at Robotlegs. They knew that an application might need more than one implementation of an abstract class or interface, so when injecting they had to have a way to determine which concrete version to instantiate. To solve this, they used naming to differentiate one implementation from another. In Strange, it looks like this:

injectionBinder.Bind<IEnemyAI>().To<CrazyIvanAI>().ToName("Ivan");

This solved the problem, but in my view solved it rather inelegantly, because the client class that uses a named injection now needs to look like this:

[Inject("Ivan")]
public IEnemyAI aiModel { get; set; }

This is precisely the opposite of how dependency inversion is meant to work. The client is telling its  provider what it needs, instead of the other way around. That said, I had no better idea how to fix this, so it’s what we ended up using in Strange. That all changed with my flash of insight on Saturday.

Could naming, like the rest of binding, be inverted?

Not naming any names

So my mission was to supply injections to identical interfaces and abstract types without editing the consuming class. Which means what used to look like this:

public class EnemyMediatorOne
{
    [Inject("Ivan")]
    public IEnemyAI aiModel { get; set; }
}
public class EnemyMediatorTwo
{
    [Inject("George")]
    public IEnemyAI aiModel { get; set; }
}

Now needs to look like this:

public class EnemyMediatorOne
{
    [Inject]
    public IEnemyAI aiModel { get; set; }
}
public class EnemyMediatorTwo
{
    [Inject]
    public IEnemyAI aiModel { get; set; }
}

That latter example yields scarily similar injections, but there is one thing that obviously sets them apart: the classes in which they are defined. So we can use the client class as the identifier to separate one injection from another!

This leads us to a new InjectionBinding method: SupplyTo.

SupplyTo is an optional instruction in your injection binding that explicitly identifies a client class you want to have consume this injection.

Here’s an example:
(Note: there’s a bug — in WordPress I presume — that causes this example to render a bit oddly in some browsers. I got tired of trying to solve their issue. My apologies. I think the idea comes across. If you really need to see it correctly, it renders fine in Firefox.)

injectionBinder.Bind<IEnemyAI>()
    .To<BasicEnemy>()
injectionBinder.Bind<IEnemyAI>() 
    .To<BossEnemy>()
    .ToName("Boss") 
    .SupplyTo<RedBossMediator>() 
    .SupplyTo<BlueBossMediator>() 
    .SupplyTo<GreenBossMediator>();
injectionBinder.Bind<IEnemyAI>() 
    .To<BigBossEnemy>()
    .ToName("BigBoss")
    .SupplyTo<BigBossMediator>();

In the above example, we have three implementations of IEnemyAI:

  • BasicEnemy
  • BossEnemy
  • BigBossEnemy

By default, anyone who requests IEnemyAI receives an instance of BasicEnemy. But certain marked classes, such as RedBossMediator, receive a different class instance. And one class, BigBossMediator, receives its own special AI. The key point is that each mediator simply marks the interface for injection…no naming in the class is required.

public class StandardEnemyMediator
{
    [Inject]
    public IEnemyAI aiModel { get; set; }
}
public class RedBossMediator
{
    [Inject]
    public IEnemyAI aiModel { get; set; }
}
public class BigBossMediator
{
    [Inject]
    public IEnemyAI aiModel { get; set; }
}

The result is a much better form of inversion, and more flexible code (which is what we’re always after, right?

A couple things to call out from our example. First, note that we still name the binding itself, whenever there’s more than one key. This is important both for backwards compatibility and in order to retrieve the binding, should you ever need to. And see how we apply multiple SupplyTo’s in a chain. This makes it convenient to list any number of consumers for this injection.

Finally, I’ll mention that this change should be fully backwards compatible. So you don’t need to use it if you don’t want to. And you should be able to safely mix-and-match the new approach with the old one.

Naming the limitation

There is one important caveat to this model. Since we’re using the client class as the key, there’s no way to use this technique to inject two of the same interface/abstraction into the same client class. That’s a corner case, albeit an important one, in which you’ll still have to rely on the old-fashioned naming method.

The name of the branch

This work is now on the branch invert-names. If all checks out, we hope to release it as part of the next major release of the framework. Happy binding!

IoC solutions for Unity

This post is just a list of Inversion-of-Control/Dependency Injection solutions for Unity3D for anyone looking to compare. I can’t at this time validate how good any of them are (well, with the obvious exception).

This is a living list. If you know of any I’ve missed, please let me know.

StangeIoC

Strange is the open-source IoC framework I built and which is the main focus of this blog. It borrows heavily from previous OS projects Robotlegs and SwiftSuspenders.

http://strangeioc.github.io/strangeioc/

Robotlegs for C#

The Actionscript version of Robotlegs was foundational for StrangeIoC. In 2015, our friend prankard ported the framework to C#. Unsurprisingly, the framework will look very familiar to our user base.

https://github.com/robotlegs-sharp/robotlegs-sharp-framework/

Stiletto

A .NET port of Dagger, the lightweight Android dependency injector from Square.

https://github.com/paulcbetts/stiletto

Zenject

Zenject, like StrangeIoC, is an OS project with a focus on helping Unity developers write large, flexible code bases.

https://github.com/modesttree/Zenject

Sebastiano Mandalà

Sebastiano developed some early ideas on Injection containers for Unity. His work was inspirational for many projects that followed, Including StrangeIoC and Zenject.

http://blog.sebaslab.com/ioc-container-for-unity3d-part-1/

http://blog.sebaslab.com/ioc-container-for-unity3d-part-2/

Simple Injection by Kasper Mindra

http://blogs.unity3d.com/2014/05/07/dependency-injection-and-abstractions/

Simple IoC Container for Unity3d

http://www.codeproject.com/Articles/774606/Simple-IoC-Container-for-Unity-d

uFrame

uFrame is a paid MVVM framework available from the asset store.

http://invertgamestudios.com/home

Uniject

Uniject is an Open Source DI project with a heavy emphasis on creating/promoting testable code. Note that as of this writing this project has been dormant for 2 years.

https://github.com/banderous/Uniject

Inconspicious Framework

Inspired by Strange, the developer tells me. The main difference/selling point is integration with UniRx for type-safe commands/signals.

https://github.com/yuhe00/Inconspicuous.Framework

The Good, The Bad and The Strange

This is a presentation I gave awhile back, which I finally got around to recording. It explains the core principle of dependency inversion upon which Strange is based. It’s largely intended as an intro that explains why writing Singletons is such bad practice (and writing Factories only marginally better), and why injection is a better way to go.

Part 1 (theory)

Part 2 (practice)

I’m going to Unity!

Unity logo

Powered by Unity

As friends of Strange will know, things have been very quiet on the development front over the last eight months or so. The reason is that I’ve been engaged in building a new startup company which frankly had nothing whatsoever to do with Unity. All that is changing today.

The sad news is that my startup didn’t take off as quickly as we had planned or hoped. The good news is that this puts me back in the Unity game, and therefore back into StrangeIoC. Even better, I’m not just going to work on Unity, I’ll be working at Unity.

So what does this mean for Strange? Well, Unity are hiring me, they’re not buying Strange, so on the one hand don’t expect them to be integrating it into the product anytime soon, or charging for its use, or anything of that sort. From Unity’s perspective i don’t think anything about Strange will really change. On the other hand, you can expect that future StrangeIoC development (and there will be further development) will be able to take better account of upcoming features, and of course I hope to both increase the profile of Strange in Unity development circles and help improve the overall community ethic around relevant issues such as decoupling, testing, and other best practices.

I hope everyone in the Strange family is as excited about this turn of events as I am. While I’m naturally disappointed that my little startup didn’t meet with instant success, I’m nevertheless stoked to be back with Strange and Unity. I hope you’ll forgive my absence and celebrate an exciting future.

So what will I be doing? Well, my first responsibility will be to the analytics team, helping you to make better sense of how users are playing your games. From our early discussions (and this Unite 2014 presentation), it’s clear Unity wants to eliminate the pain points that keep you from instrumenting your app or understanding the resulting data. My experience in front-end development and decoupling come very much into play in achieving these goals. More generally, you can be assured that the philosophies underpinning IoC will have another in-house advocate.

Before I wrap, let me take a moment to once again thank the superheroic efforts of Will Corwin, who has looked after Strange, answered questions on the Google Group, handled pull requests and bug reports, and generally kept this enterprise alive in my absence. It’s down to him and you that there is an enterprise to return to.

So, the ball is in your court. Where should Strange go next? Ideas for new features? More examples/documentation? I’d certainly love to build a roster page at our site listing games and companies using Strange, which I think would help advance the cause. Please chime in. We’re off to a Strange new start!