It’s been with us since Unity 1.0, but its time is finally coming: we have begun the deprecation process for UnityScript, the JavaScript-like scripting language available as an alternative to C# in Unity today.
In this blog post, we’ll go into the details behind the decision, but to briefly summarise: continued support for UnityScript is obstructing our ability to deliver new scripting-related features, and only about 3.6% of projects are using it heavily.
Every time we remove something from Unity, we assume there are always some users that it’s going to inconvenience. So, it’s important that we have made sure our reasons are worthwhile.
There’s a lot happening around scripting at Unity right now. Some of the biggest pieces:
That’s just a fraction of what we’re working on right now - there are many more things happening, and that doesn’t even include some of the projects we have planned for the future. In addition to the specific scripting projects, we’re also increasingly opening up the engine and growing our API surface - which we want to do using the most appropriate language constructs available.
Today, UnityScript and C# are fairly evenly matched in terms of functionality and performance: there’s nothing you can do with C# that you cannot do with UnityScript. C# is the clear winner when it comes to developer ecosystem - not just the millions of C# tutorials and samples out there, but also tooling support, like refactoring and intellisense in Visual Studio - but you could say, today, that UnityScript works, and who needs those fancy tools anyway?
It’s true today, but it won’t be true forever. As we upgrade the Scripting Runtime and version of C# we support, there will begin to be things that UnityScript doesn’t do as well as C#, or even can’t do at all. It already does not support default values for method parameters, and there are more language features coming to C#, such as ref return, that will have the same problem. We don’t use these language features in the API today, but we want to, both for performance and to achieve a clean API design.
It’s all just software, and we could take the time to implement these missing pieces into UnityScript. Time is not free, though; asking an engineer to work on bringing UnityScript up-to-date means taking them away from working on something else (like one of the new features I mentioned above - or just from fixing bugs). This isn’t even mentioning the time we already invest in maintaining UnityScript - supporting it in the Script Updater, supporting it in the documentation, and so on.
So let’s look at the other side of this: how many users will be affected? The Editor periodically sends us data about your project, including the different file types you’re using and how much you’re using them, so from that we can calculate statistics about how many projects are actually using UnityScript. What we found was:
What this suggests to us is that the majority of you who still have UnityScript code aren’t using it heavily. You may even not be actively using it at all: a .js file in the project might be an example script for an Asset Store package, rather than code that you are actually relying on. Therefore, an early step in our deprecation plan is to start working with Asset Store publishers to get rid of packages that are providing these files - more on this below.
To the 3.6% of you who are using it more heavily - and especially the 0.8% who are using it exclusively - we are sorry. We know that this decision sucks for you. We’re taking some steps to try and smooth the transition, that I’ll describe below; and we hope that you will eventually agree with us that it was worth it in the end.
We’re not just going to pull the plug overnight. Here’s what you’re going to see us do:
Firstly, as of the beginning of June, we have amended the Asset Store submission policy to reject packages that contain UnityScript code. All new code that you’re writing for Asset Store packages should be in C#. (We ran this past the Asset Store Publishers discussion group before we did this, to give them a heads-up). Soon, we will begin a scan of all existing packages on the Asset Store to find ones that contain UnityScript files, and will contact publishers to ask them to port their code to C#. After a while, any package that hasn’t been ported will be removed from the store.
Secondly, you might have already noticed: the Unity 2017.2 beta no longer has a ‘Javascript’ (a.k.a UnityScript) option in the Create Assets menu. All we have done at this point is remove the menu item; all the support is still there, and you will still be able to create new UnityScript files outside of Unity (for example, via MonoDevelop). We’re doing this to help ensure that new users do not continue to adopt UnityScript; it would be irresponsible of us to let them invest time in learning it when it is not long for this world.
Thirdly, we have begun work on a UnityScript -> C# automatic conversion tool. There are a few of these out there already, but we weren’t happy with the approaches they use; we already learnt a lot about operating on UnityScript code when we wrote the Script Updater, so we decided just to apply that knowledge and build our own solution. We’ve not yet decided whether this will be integrated directly into Unity or just available as a separate open-source tool, but either way we are expecting to have something available by the time 2017.2 ships later this year. We’ll have a follow-up blog post about this tool when it’s ready.
After that, we will be watching our Analytics numbers. Our hope is that we’ll see a fairly quick decline in the use of UnityScript - particularly in the “fewer than 10% of scripts” group, who have less code to migrate - but if we don’t, we’ll pause our plans and investigate what’s blocking people from migrating. Sometimes it’s just a matter of timing, but other times there are real issues, and we want to make sure we didn’t miss something before we switch it off entirely.
Once we’re content that the usage level is low enough, Unity will no longer ship with the UnityScript compiler, and will no longer recognise .js files as user script code. We’ll also remove the UnityScript examples from the documentation, and remove UnityScript support from the Script Updater.
The UnityScript compiler will remain available on Github at https://github.com/Unity-Technologies/unityscript in case you need it for anything - we will not be accepting any pull requests to it, but you can fork it and use it for whatever you need.
We announced back in 2014 that we were dropping Boo support from the documentation and Editor UI. The Boo compiler itself has stuck around, though, because UnityScript is actually a layer on top of Boo - it uses the Boo runtime libraries, and the UnityScript compiler is written in Boo. This has allowed you to continue using .boo files in your projects, even if there’s nothing in Unity that mentions it any more.
The removal of UnityScript support will also mean the final removal of the Boo compiler. At this point, only 0.2% of projects on 5.6 contain any .boo files, and only 0.006% of projects have more than 3 boo files in. Again: we’re sorry, but its time has come.
We hope this post has explained our reasoning clearly, and given you some reassurance that we are not just doing this without having thought carefully about it.
Going forward, this is the kind of process we want to follow for every situation in which we are removing a feature: announce our intentions, push for change through the Asset Store and Editor UI tweaks, but ultimately make the decision based on actual data about what you’re all doing.
Deprecating and removing features can feel like the opposite of progress sometimes, but it’s an important part of streamlining Unity; like a forest fire clearing the way for new growth, it helps clear the way for us to deliver the fixes and features you want as quickly as possible.