Unity in 2018

I don’t remember if I ever was as excited for what’s coming to Unity, as I am right now. And I have been through quite some times, all the way from Unity 1.5! (that was in 2006, or somewhere in the middle of Priabonian age)

A lot of exciting things are falling into place:

A lot of other stuff is happening too; many pieces that were considered “experimental/preview” before will soon drop their experimental labels (e.g. Progressive Lightmapper or .NET 4.6 Scripting Runtime).

And then way more stuff is being developed; some of it fairly close to shipping and I hope will ship this year; some still a bit further out. I wish I could tell more… suffice to say, among other things we have this custom emoji – whatever it might mean – in the company Slack, and it’s getting quite a lot of usage lately.

This is all very exciting!

But, what is perhaps even better, is that I think we’ve found a way how to do a big jump/move from “where we are today” to “where we want to be in 5 years”.

This is one of the hardest problems in evolving a fairly popular product; it’s very hard to realize how hard it is without actually trying to do it. Almost every day you’re off with something you’d want to change, but a lot of possible changes might break some existing content. A “damned if you do, damned if you don’t” type of situation, that @mcclure111 described so brilliantly:

Library design is this: You have made a mistake. It is too late to fix it. There is production code depending on the mistake working exactly the way the mistake works. You will never be able to fix it. You will never be able to fix anything. You wrote this code nine seconds ago. [source]

It’s easy to make neat tech that barely anyone uses. It’s moderately simple to make technically brilliant engine that gets two dozen customers, and then declare a ground-up 100% rewrite or a whole new engine, that This Time Will Be Even More Brilliant-er-er. Get two dozen customers, rinse & repeat again.

Doing a re-architecture of an engine (or anything, really), while hundreds of thousands of projects are in flight, and trying to disrupt them as little as possible, is a hundred times harder. And I’m not exaggerating, it’s easily a hundred times harder. When I was doing customer-facing features, improvements & fixes, this was the hardest part in doing it all.

So I’m super happy that we seem to have a good plan in how to tackle this! The Package Manager is a huge part of that. The new Entity Component System is the first big piece of this “re-architecture the whole thing”. You can opt in to use it, or you can ignore it for a bit… but we hope the benefits are too big to ignore. You can also start to use it piece by piece, transitioning your knowledge & production to it.

Many other systems are likely to follow in a similar fashion. For example the current Scriptable Render Pipeline approach replaces the high-level rendering code with C#, but the underlying “graphics platform” layer is more or less the same. Some parts of it are in less-than-ideal state or design… I’ve been thinking that it would be possible to “upgrade” it in-place to be way more modern, but by now it feels like maybe parts of it should be started anew. And so at some point a new graphics platform layer will be built, a new material/shader runtime will happen, etc. etc. It will live side by side with the “old stuff” for a while, similar to how the new ECS and the old GameObject/Component system will live together.

And this time I feel like we will be able to pull it off, more so than previous times :) Wish us luck!


UWP/WinRT Headers are Fun (not)

As established before, <windows.h> is a bit of a mess that has accumulated over 30+ years. Symbols in global namespace, preprocessor macros, ugh:

#include <windows.h>
// my code
void* GetObject(...);
// welp, GetObject is actually GetObjectW now

So naturally, someone at Microsoft decided it’s time to make a “v2” API set for programming Windows, without any of the horrors of the past, using more modern approaches, and so on. And so in 2012 Windows Runtime was born.

No more preprocessor hijacking identifiers! No more global namespaces! …hmm. or is it? Try this (tested with Windows SDK 10.0.16299.0, VS2017):

class Plane;
#include <windows.ui.core.h>

What does the compiler say?

Windows.Foundation.Numerics.h(490): error C2371: 'ABI::Windows::Foundation::Numerics::Plane': redefinition; different basic types
Windows.Foundation.Numerics.h(317): note: see declaration of 'ABI::Windows::Foundation::Numerics::Plane'

Compiling with /W3 tells more detail on why that happens:

Windows.Foundation.Numerics.h(317): warning C4099: 'Plane': type name first seen using 'class' now seen using 'struct'
test.cpp(2): note: see declaration of 'Plane'

Lo and behold, turns out that Windows.Foundation.Numerics.h (which is included by a lot of WinRT headers) has this:

namespace ABI {
    namespace Windows {
        namespace Foundation {
            namespace Numerics {                
                typedef struct Plane Plane;
            } 
        } 
    } 
} 

The code tried to be namespace-aware, but typedef struct Plane Plane apparently is not. Why does it have that thing in the first place? No idea!

But this means you can’t forward-declare classes/structs, that match WinRT structs/classes (even inside namespaces!), before including WinRT headers. Your own forward-declarations have to come after WinRT header inclusion.

Since that pattern in headers essentially creates code like this, which is a compile error on all C++ compilers:

class Plane;
namespace Test
{
    typedef struct Plane Plane;
    struct Plane { int a; };
}
// clang 5.0.0:
// warning: struct 'Plane' was previously declared as a class [-Wmismatched-tags]
// error: definition of type 'Plane' conflicts with typedef of the same name
//
// vs2017:
// warning C4099: 'Plane': type name first seen using 'class' now seen using 'struct'
// error C2371: 'Test::Plane': redefinition; different basic types
//
// gcc 7.2:
// error: using typedef-name 'Test::Plane' after 'struct'

“Great” job, WinRT headers. At least in WinAPI times I could undo most of the damage with some #undef

:sadpanda:


Header Hero Improvements

There’s a neat little tool for optimizing C++ codebase header #include dependencies: Header Hero (thanks Niklas for making it!).

It can give an estimate of “how many lines of code” end up being parsed by the compiler, when all the header files have been included. I suggest you read the original post about it. A more recent post from Niklas at how they are approaching the header file problem now is very interesting too; though I’m not convinced it scales beyond “a handful of people” team sizes.

Anyway. I just made some small improvements to Header Hero while using it on our codebase:

Precompiled Headers

I added a new field at the bottom of the main UI where a “precompiled header” file can be indicated. Everything included into that header file will be not counted into “lines of code parsed” lists that the UI shows in the report.

What goes into the precompiled header itself is shown at the bottom of the report window:

Small UI tweaks

Added quick links to “list of largest files” and “list of most included files” (hubs) at top of build report. Initially I did not even know the UI had the “hubs” list, since it was so far away on the scrollbar :)

Switched the “Includes” tab to have file lists with columns (listing include count / line count), and added a “go to previous file” button for navigation.

That’s it! Get them on bitbucket here.


Helped to Build a School in Cameroon

One thing led to another, and I funded construction of a new primary school in Cameroon. The school is built & working now. Yay!

What? How? Why?

It started out in a fairly unusual way, around September 2016. US election thing was nearing completion, and the guy who founded Oculus funded some shitposting campaign related to it. Cliff Harris wrote a blogpost about it:

The thing is, its really very EASY to do good things when you have a lot of spare money. I built a school in Africa for £18,000. Thats $23,000. I tried to work out what that was as a percentage of 700 million but my calculator goes into exponential results. Its fucking trivial. By the way, it involves zero effort just an email and then a bank transfer. You don’t get to have “a real jolly good time”, but you help people in the developing world get an education.

And that made me go “what? you can build a school?! that sounds interesting…”

For about a month I had this thought in the background, occasionally reading about various similar things. And then, because I’m generally a very unimaginative person with no original ideas, I just wrote an email to the same Building Schools for Africa (BSFA) organization that Cliff has built his school with.

Why? Because it sounded like a good thing to do, and my understanding is that more accessible primary education & clean water are fairly effective ways of help.

The Process

By middle of November 2016 I’ve agreed with BSFA that I’m willing to fund construction of a new primary school, and they with their Cameroon partner SHUMAS will start researching for possible locations & evaluating things.

However at end of 2016 a crisis between Anglophone and Francophone parts of Cameroon has emerged, including a teachers strike and an internet ban, and the school finding process has dragged out a bit.

A proposal for a school site, including feasibility analysis & budgeting, was done by February 2017. The proposed location is in Meyomessala village, Dja et Lobo division of the South region of Cameroon. Somewhere here is my guess. The village is home to some 7500 people.

A bilingual primary school has already existed in the village since 2009. Currently about 200 children attend it. However it never had any classrooms or equipment (!), borrowing temporary space from another nearby French school instead.

So the proposal was:

  • Construction of 3 new classrooms and an office.
  • Construction of a toilet block with associated hand-washing facilities.
  • Equipment of these classrooms with benches, tables and chairs.
  • Water provision for the school through the construction of a water borehole.

The total cost of funding was about 25 thousand Euros. This isn’t a trivial amount of money, but on the other hand, it’s basically as much as a new fairly non-remarkable car. So YMMV.

By April a 40 meter water borehole got constructed (funding for it was provided by someone else; not part of my budget):

During June-August most of the school construction was happening:

And then the school was almost done!

The Result

By November the school was operating, and the formal handover to BSFA happened on their Cameroon trip in December.

I will get updates on how the school is doing from BSFA after 1 and 2 years, will be interesting to see.

Thanks BSFA and SHUMAS for doing the actual work of school construction, and Cliff for being an inspiration.


Minimizing <windows.h>

I’ve been looking at our (Unity game engine) C++ codebase header file hygiene a bit, and this is a short rant-post about <windows.h>.

On all Microsoft platforms, our precompiled header was including <windows.h> since about forever, and so effectively the whole codebase was getting all the symbols and macros from it. Now of course, the part of the codebase that actually needs to use Windows API is very small, so I thought “hey, let’s see what happens if I stop making windows headers be included everywhere”.

But why would you want that?

Good question! I don’t know if I do, yet. Conceptually, since only very small part of the codebase needs to use stuff from windows headers, it “feels wrong” to include it everywhere. It might still make sense to keep it in the precompiled header, if that helps with build performance.

“Precompiled headers, grandpa?! What about C++ modules?”

It’s true that C++ modules perhaps one day will make precompiled headers obsolete. Good to see that the major compilers (MSVC, clang, gcc) have some level of implementation of them now.

Not all our platforms are on these compilers; and some others are not on recent enough versions yet. So… I dunno, some years in the future? But maybe we’ll just be writing Rust by then, who knows :)

Anyway. Just how large <windows.h> actually is? In VS2017 (version 15.5, Windows SDK 10.0.16299), after preprocessing and ignoring empty lines, it ends up being 69100 lines of actual code. When defining WIN32_LEAN_AND_MEAN before inclusion to cut down some rarely used parts, it ends up being 33375 lines. That’s not massive, but not trivially small either.

For comparison, here are line counts (after preprocessing, removing empty lines) of various STL headers in the same compiler:

  • <vector> 20354
  • <string> 26355
  • <unordered_map> 24291
  • <map> 21144
  • <algorithm> 18578
  • vector+string+unordered_map+algorithm 35957
  • <cstdlib> 1800; just <stdlib.h> itself: 1184. C was small and neat!

Actual problem with windows.h: macros

Back to task at hand! So, remove <windows.h> from precompiled header, hit build and off you go, perhaps sprinkling a now-needed windows include here and there, right? Of course, wrong :)

Others have said it in harsher words, but the gist is: Windows headers define a lot of symbols as preprocessor macros. While min and max are optional (define NOMINMAX before including), some others like near and far are not.

And then of course a bunch of function names that Windows maps to either ANSI or Unicode variants with a preprocessor. SendMessage, GetObject, RegisterClass, DrawText, CreateFile and so on. Good thing these are obscure names that another codebase would never want to use… oh wait. These are the exact function names that caused problems in my attempt.

If you have a central place where you include the windows headers, you could #undef them after inclusion, and make your own code explicitly do SendMessageW instead of using a macro.

But then there’s some 3rd party libraries that include windows.h from their own header files. I’m looking at you, Enlighten, Oculus PC SDK, CEF and others. Ugh!

Modular/smaller windows.h

There are other ways to approach this problem, of course.

One is to not have any Windows-specific things in many/any of your header files, wrap everything into a nice little set of Windows-specific source files, only include windows headers there, and go on doing fun things. That would be ideal, but is not a five minute job in a large existing codebase.

If you don’t need many things from Windows headers, you could declare the minimal set that you need yourself, manually. Contrary to what some Stack Overflow threads say (“why WAIT_OBJECT_0 is defined to be STATUS_WAIT_0 + 0? because the values might not be the same in the future!” – err nope, they can’t realistically ever change their values), it’s not a terribly dangerous thing to do. Windows API is one of the most stable APIs in the history of computing, after all.

Here’s an example of a minimal set of manually defined Windows things that Direct3D 9 needs, from @zeuxcg: Minimal set of headers for D3D9.

Another example is hand-crafted, quite extensive windows headers replacement from @ArvidGerstmann: Modular Windows.h Header File.

However, even Windows headers themselves can be used in a much more modular way directly! What I found so far is this:

  • Preprocessor macro _AMD64_ (for x64), _X86_ (for x86) or _ARM_ (for ARM) has to be defined by you, and then,
  • You can include one of the many “smaller” headers:
    • <windef.h> to get most of the base types (DWORD, HWND, …) as well as atomic functions and stuff. 7811 lines of actual code.
    • <fileapi.h> for file functions (CreateFile, FindFirstFile, …), 7773 lines.
    • <synchapi.h> for synchronization primitives (WaitForMultipleObjects, InitializeCriticalSection, …), 8450 lines.
    • <debugapi.h> for IsDebuggerPresent, OutputDebugString etc. No need to include whole thing for it :)
  • The Windows SDK headers, at least in Win10 versions, seem to be structured in a fairly stable way, and with same partition of these smaller header files across Win32, XboxOne and UWP platforms.

This is all.