I’ve known Unity since 2007 but only started using it seriously in 2013. At that time,
a hobbyist shopping for quality engines could either go with one of the Open Source
projects, UDK (3) or Unity 4.

While the workflow was very unusual for someone used to code-centric engines where your
main working environment is an IDE and perhaps a wonky level editor that lets you place
things in the world, Unity was a huge productivity gain.

The interface between game code and engine was very tidy (necessarily so because game
code is written in .NET rather than the engine’s C++ but the Unity developers also
had good taste in API design). Thus I purchased a Unity 4 Pro license for 1500 Euros
(it was an early adopter license: use Unity 3 Pro now, switch to Unity 4 Pro as soon
as it is released).

Two years later, Unity announced the interation of Enlighten into Unity 5, promising
real-time global illumination. I took the early adopter offer again, 600 Euros for
a Unity 5 Pro license for existing customers. There were some issues with new lighting
system, but overall, the integration is pretty well done.

Early Unity

Until this point, I was very happy with Unity’s business model:

rather than collect royalties, I paid an (admittedly large) sum of money and
never had to worry about sending sales numbers to Unity Technologies or
other bureaucracy.

major engine versions became (mostly) stable targets to develop against and
after feature development ceased, there was still 1+ year of bugfixing going
on, leaving those major releases in a pretty robust sunset state.

lastly, it was classical business: UT builds the product I want,
I pay them to get it. If they want me to pay again, they need to improve
their product so I consider it worthwhile to pay for the next version.

Late Unity

Sadly, during the last years, things took a depressing turn towards “Economy 2.0”

In late 2013, ex EA CEO Riccitiello joins the board of directors at
Unity Technologies. I have seen no public releases revealing who pushed for
what in Unity’s board of directors, but I believe to see the EA CEO’s
handwriting in many of the changes, resembling directional changes at EA.

In early 2014, Unity Technologies acquires Applifier, a company owning a
mobile video ad network.

Also in 2014, Unity Technologies acquires Playnomics, a company offering
telemetry services for software.

In late 2014, Riccitiello advanced from board member to CEO of Unity Technologies,
replacing CEO David Helgason.

Early 2015, Unity suddenly gives away their bread-winning features for free.
While many of us Unity users expected a reaction to Epic offering Unreal Engine 4
for merely $20 per month, this was a strange turn, especially since for
most of Unity 5’s beta phase, the licensing terms remained in a state of flux.

In 2015, Unity Technologies acquired ecommerce business SilkCloud which has
had many dealings with EA developing advertising, shop and mobile device
account systems.

Still 2015, Unity Technologies introduces Unity Analytics, a telemetry solution
as a service directly from Unity Technologies.

Also in 2016, with Unity 5.3, micro-transactions are natively integrated
as “Unity IAP.”

Also in 2016, Unity introduces more services. You now get “Unity Ads,”
“Unity Analytics,” “Unity Cloud Builds,” and “Unity Collaborate” all from
one hand.

Still in 2016, the future licensing model becomes clearer: perpetual licenses
will be discontinued; for $35 monthly (the $600 upgrade to Unity 5 translated
into $25 monthly over its 2 year lifecycle) you get saddled with a revenue
cap and can’t disable telemetry anymore while having the same feature set as
the free version. Major versions are replaced with a rolling release model.

Quo Vadis?

From the business direction, what I am seeing here is:

Unity Technologies has quit the traditional economy. Rather than create
features (packaged into major versions) and sell them to customers,
the customers sign a contract (subscription) and will pay for
whatever Unity decides to do or not do.

It’s not as bad as the Windows 10 business model yet, where Microsoft can
essentially do whatever they want to their OS, customers will
download it and install it with no choice, but it’s close enough.

The basic product is free, revenue now needs to come from taking a share from
advertising and micro-transactions (thus the Unity Ads and Unity IAP features)
and services sold to developers.

This way, Unity’s business now squarely depends on the toxic business model
of money-grabbing mobile games.

Developer PoV

As a game developer, further worries this creates are:

The rolling release model is pretty ugly on the Asset Store. There never was
support for downloading older versions of assets, but with rolling releases
this has become a real problem. If you stay with Unity 5 for example, pretty
soon all your script asset purchases are worthless because they all target
Unity 2017.

Unity always had slight image problem. Not because the engine is bad,
but because of the low barrier to entry allowing inexperiences developers to
release very poorly made games.

With Unity being completely free for everyone, this will get worse. With
Unity being the engine behind most ad-supported and/or IAP cash-grabs on
mobile devices, this will get worse again.

I like to pay small development teams for features. What am I paying for
when I subscribe for $35 or $125? Will I pay for the development of useful
engine features or for server rent to process the IAPs of some poor suckers?

I hope Unity Technologies will continue to invest in cutting-edge features
(like Enlighten was for Unity 5), but I do not see a strong business case
for Unity Technologies to do anything more than just stay relevant with their
current model.

Dilemma

These two concerns have so far prevented me from upgrading to Unity 2017.

I have purchased a large number of assets on the asset store, so this would
be a big loss, but I also don’t feel comfortable with the direction Unity is
heading and want to jump ship as soon as possible.

I have been looking into Unreal Engine 4 since 2015. It is capable of flashy
results, but the technical foundation looks rather weak (everything is
integrated with everything, where does the engine stop and the gameplay
framework start? why do assets opaquely store their IDs with their data?).

Furthermore, I ran into real obvious showstopper bugs everywhere as late
as 4.14. Lately things have been getting better, however.

So now I’m sitting here, unsure of when would be the right time to abandon
Unity. Should I go with the 2017 license for 12 months and then switch.

Alternatives

I’ve also been looking into Open Source engines again.

Ogre3D
has taken a nosedive in quality since the original project lead left,Horde3D
looks abandoned,Atomic Engine
is lacking Linux support (for its editor), butUrho3D
is in great shape andGodot Engine
might be a good choice, too.

I’ve recently made the decision to learn some drawing skills. Specifically,
I wanted to start with a tablet right away so I could avoid having to
re-teach myself to using a tablet instead of paper. However, I still
consider it important to be able to shift and rotate the canvas with my
hand, so I went for a Wacom tablet with touch.

Most artists I knew swear by Paint Tool SAI, but that just happens to be
one of the applications not fully supported by Wacom’s drivers (pressure
works fine, but touch is a no-go). Luckily, Wacom’s drivers are pretty
flexible and you can easily modify them to support your favorite application.

Here’s another fairly trivial code snippet. I’ve stumbled across some
borked attempts at initializing and maintaining rendering windows for
games lately. Most failed to properly respond to window messages, either
ignoring WM_CLOSE outright or letting DefWindowProc()
call DestroyWindow()
when WM_CLOSE was received, thereby not giving the rest of
the game’s code any time to cleanly shut down before the window handle
becomes invalid.

So I’ll provide a clean and well-behaved window class here. It doesn’t
use any global variables – in fact, you could create any number of windows
from any number of threads. WM_CLOSE simply causes the class’
WasCloseRequested() method to return true, so by polling this
method you can first shut down graphics and input devices and then destroy
the window in an orderly fashion.

For your convenience I also added some helper methods: one resizes the window
in a way that ensures the client area will actually end up with the exact
pixel size requested. Another will center the window on the screen without
messing up if the user has extended his desktop over multiple monitors.

Many games choose to store their resources in packages instead of
shipping the potentially thousands of individual files directly.
This is sometimes an attempt at tamper-proofing, but mostly it is
about performance. Try copying a thousand 1 KiB files from one drive
to another, then copy a single 1 MiB file on the same way – the
former operation will take many times longer.

A good choice for a package format is the well known .zip
archive. It’s not necessarily well-designed, but it decompresses fast
and you definitely won’t have any problems finding tools to create, modify
and extract .zip archives. Thus, when I started work on a file system
abstraction layer for my future games, seamless .zip support was one
of my main goals (I may also add 7-Zip at a later time
just for fun).

Here is the design I came up with after exploring the file system APIs
available on Windows, WinRT and Linux:

You may notice some rather radical design choices in my File class: there
are no Open() or Close() methods and there is
no Seek() method, either – each read or write specifies
the absolute position without requiring the file to be opened.

Those binaries no longer work with the Windows 8 Release Preview and Visual Studio
2012 RC, so I thought I’d provide an updated package!

This time I went a bit further: while the last package was compiled with multithreading
disabled, I have in the meantime ported Boost 1.50.0 to compile on WinRT (using a slightly
modified version of Shawn
Hargreaves’ WinRT CreateThread emulation code. Thus, this Ogre build has full support for
multithreading and includes Boost!

When you work on a larger project, you cannot easily keep track of which header
depends on which other header. You can (and should) do your best to keep the number
of other headers referenced inside your headers low (to speed up compilation) and
move as many header dependencies as you can into your source files, but this still
doesn’t prevent you from building headers that implicitly depend on another header
being included before them.

But WinRT/Metro applications cannot use the shell API and have to do it manually.
So here’s a piece of code that takes care of directory deletion using nothing
but Win32 API calls that are also available to WinRT/Metro applications:

/// <summary>Automatically closes a search handle upon destruction</summary>class SearchHandleScope {/// <summary>Initializes a new search handle closer</summary>/// <param name="searchHandle">Search handle that will be closed on destruction</param>public: SearchHandleScope(HANDLE searchHandle):
searchHandle(searchHandle){}/// <summary>Closes the search handle</summary>public: ~SearchHandleScope(){::FindClose(this->searchHandle);}/// <summary>Search handle that will be closed when the instance is destroyed</summary>private: HANDLE searchHandle;};/// <summary>Recursively deletes the specified directory and all its contents</summary>/// <param name="path">Absolute path of the directory that will be deleted</param>/// <remarks>/// The path must not be terminated with a path separator./// </remarks>void recursiveDeleteDirectory(const std::wstring&path){staticconst std::wstring allFilesMask(L"\\*");
WIN32_FIND_DATAW findData;// First, delete the contents of the directory, recursively for subdirectories
std::wstring searchMask = path + allFilesMask;
HANDLE searchHandle =::FindFirstFileExW(
searchMask.c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, 0);if(searchHandle == INVALID_HANDLE_VALUE){
DWORD lastError =::GetLastError();if(lastError != ERROR_FILE_NOT_FOUND){// or ERROR_NO_MORE_FILES, ERROR_NOT_FOUND?throw std::runtime_error("Could not start directory enumeration");}}// Did this directory have any contents? If so, delete them firstif(searchHandle != INVALID_HANDLE_VALUE){
SearchHandleScope scope(searchHandle);for(;;){// Do not process the obligatory '.' and '..' directoriesif(findData.cFileName[0]!='.'){bool isDirectory =((findData.dwFileAttributes& FILE_ATTRIBUTE_DIRECTORY)!=0)||((findData.dwFileAttributes& FILE_ATTRIBUTE_REPARSE_POINT)!=0);// Subdirectories need to be handled by deleting their contents first
std::wstring filePath = path + L'\\'+ findData.cFileName;if(isDirectory){
recursiveDeleteDirectory(filePath);}else{
BOOL result =::DeleteFileW(filePath.c_str());if(result == FALSE){throw std::runtime_error("Could not delete file");}}}// Advance to the next file in the directory
BOOL result =::FindNextFileW(searchHandle, &findData);if(result == FALSE){
DWORD lastError =::GetLastError();if(lastError != ERROR_NO_MORE_FILES){throw std::runtime_error("Error enumerating directory");}break;// All directory contents enumerated and deleted}}// for}// The directory is empty, we can now safely remove it
BOOL result =::RemoveDirectory(path.c_str());if(result == FALSE){throw std::runtime_error("Could not remove directory");}}

This code is free for the taking and you can use it however you want.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

As I just found out, the CreateDirectory
function on Win32 can only create one directory at a time. If one, for example,
specifies C:\Users\All Users\FirstNew\SecondNew as the directory to create,
and both FirstNew and SecondNew do not exist, then
CreateDirectory() fails.

That’s less than ideal for some cases. Recently, for example, I wanted my game to
create the C:\Users\<Whoever>\Documents\My Games\<GameName>
directory, where both My Games and <GameName> may not yet
exist. Here’s a workaround:

/// <summary>Creates all directories down to the specified path</summary>/// <param name="directory">Directory that will be created recursively</param>/// <remarks>/// The provided directory must not be terminated with a path separator./// </remarks>void createDirectoryRecursively(const std::wstring&directory){staticconst std::wstring separators(L"\\/");// If the specified directory name doesn't exist, do our thing
DWORD fileAttributes =::GetFileAttributesW(directory.c_str());if(fileAttributes == INVALID_FILE_ATTRIBUTES){// Recursively do it all again for the parent directory, if any
std::size_t slashIndex = directory.find_last_of(separators);if(slashIndex != std::wstring::npos){
createDirectoryRecursively(directory.substr(0, slashIndex));}// Create the last directory on the path (the recursive calls will have taken// care of the parent directories by now)
BOOL result =::CreateDirectoryW(directory.c_str(), nullptr);if(result == FALSE){throw std::runtime_error("Could not create directory");}}else{// Specified directory name already exists as a file or directorybool isDirectoryOrJunction =((fileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=0)||((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)!=0);if(!isDirectoryOrJunction){throw std::runtime_error("Could not create directory because a file with the same name exists");}}}

This code is free for the taking and you can use it however you want.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

This post’s title says it all. I’ve just installed the Windows 8 Release Preview
with Visual Studio 2012 RC. Just like in the previous release, Visual Studio 11 Beta,
the Express edition does not contain any plain Win32 project templates, only ones
for Microsoft’s new Metro UI.

This is a pretty scary situation for me: recently, the C++11 Standard was completed which
finally makes threading in C++ bearable (when writing libraries, you no longer have
to force a decision between Boost, TBB
or POCO on your users). But C++11 threading was only
added to Microsoft’s C++ compiler & standard library in Visual Studio 2012.

So unless Microsoft reverts the decision to no longer offer a free C++ compiler for
Windows desktop applications, these are my options:

Buy Visual Studio 2012 Professional and exclude anybody out there
who doesn’t want to shell out $500 from using my libraries. Make it harder to build
any kind of team because there’s now a significant hurdle to entry. Probably be forced
to modify 3rd party libraries in the future because Open Source projects will
no longer test compilation of their code with Visual Studio.

Keep Visual C++ 2010 Express and either write my own threading
wrapper (increasing dependencies of my libraries from 0 to 1) or just go with
Boost and forget the rest.

Switch to Eclipse CDT + MingW and build my Windows desktop
applications this way. That would give me C++11 threading (at least I suppose so –
I couldn’t get it to work, see screenshot) but I’d have to always port anything
I write to GCC (of which MingW is a port). Could be a good thing, since it lowers
the barrier to port my stuff to Linux and Android.

Update2: the disaster is averted! Today, the Visual Studio blog announced
that Microsoft has given in and will be offering two Express editions: The already
known Visual Studio 2012 Express and, Visual
Studio 2012 Express for Windows Desktop. That means it’s safe to use C++11 across the
board now. GCC 4.6 has it, the modded Android NDK has it, and Visual C++ 2012 has it!