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.
Why deprecate it?
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:
- The Scripting Runtime upgrade, which brings the ability to use .NET 4.6 and C# 6.
- The JobSystem, making it possible to easily write multithreaded code in a way that protects you against race conditions and deadlocks.
- The NativeArray type, allowing you to create and work with large arrays that have their storage controlled by native code, giving you more control over allocation behaviour and exempting you from garbage collection concerns.
- Control over the script compilation pipeline, so you can customize how your scripts are combined into assemblies.
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:
- To date, of all the projects that have used Unity 5.6, about 14.6% of them have at least one file with a .js extension in it. 14.6% sounds quite high, but then we broke the numbers down further, and looked at how many files were .js files as a fraction of total script files in the project (.js + .cs).
- So, that leaves 85.4% of all projects which are entirely in C#, with no UnityScript files at all.
- 9.5% of all projects are mostly in C# — they have some UnityScript files, but fewer than 10% of their total script file count. Another 1.5% of all projects have between 10% and 20% of their code in UnityScript files.
- That leaves 3.6% of all projects that have more than 20% of their code in UnityScript.
- Only 0.8% of all projects are exclusively (i.e. 100%) in UnityScript.
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.
How will it happen?
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.
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.
A note about Boo
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.