What WebGL is really for

Guillaume Lecollinet nails it:

In my opinion, WebGL shouldn’t be solely used for full-page 3D applications like the majority of examples we see online. It could also be integrated into regular web pages, in combination with other technologies and content.

Using WebGL to Add 3D Effects to Your Website

Advertisement

Syntax Coloring Shader Files in Xamarin Studio 4

Since Xamarin released the renamed MonoDevelop 4 as Xamarin Studio I’ve been using it alongside Unity 3D for all my development. It’s definitively better than the Unity-bundled version of MonoDevelop (2.8 with Unity’s patches) for C# development on a Mac. I think I’ve found my new favorite IDE – a title that MonoDevelop has previously never quite taken. There’s still a few rough edges though. The ones I care about most are Unity related. The Unity debugging plugins are missing, but I can live with that for a while. Unfortunately syntax coloring isn’t enabled for shader files, at least those with .shader and .cginc extensions. It’s amazing how hard code becomes to write when syntax coloring isn’t present!

Shader Code Fades to Black And White

Thanks to some helpful feedback on the Xamarin forums it’s clear that all the parts are there, but those file extensions need to have their mime type correctly for CG shaders. That requires writing a add-in, although it only needs to contain an XML file which gets compiled into a dll. Michael Hutchinson pointed me at the getting started documentation for add-ins. Add a dash of effort and out pops https://github.com/jools-adams/monodevelop-unity-mimetypes. Just compile it and drop the dll here (on Mac):

~/Library/Application Support/XamarinStudio-4.0/LocalInstall/Addins

Evil Merges in Git

What makes Evil Merges in Git … Evil?

The Git Glossary defines an “Evil merge” as…

a merge that introduces changes that do not appear in any parent.

To me that sounds like any merge with a non-trivial conflict. The sort of conflict that needs hand editing, rather than simply taking yours or theirs for each hunk. That’s pretty common, so why is it evil? To be honest I’m just guessing, but one feature of git that slowed me down considerably when trying to find out who had removed some lines from the file is that git log pretends that merge commits don’t change any files. Try

git log --stat

on a repository with merges. It says merges never change any files, even though they really do. Adding the options -c, --cc or -m to git log suddenly shows merge stats for files which had to change in a merge. When you do a search with git pickaxe the behaviour is the same; the search won’t find anything in merge commits unless you use one of those options.

To me that sounds totally crazy, but perhaps it makes some sense if you’re interested in where changes were first introduced. In that case you’re interested in the initial commit which created the change, not the merge-commit which is a later artifact of the revision control process.

However it hides the contents of Evil Merges by default and to my mind that is Git rather than the Merge being Evil.

Unity3D Live Code Reloading

After University I worked with 3 brothers. They’d written the software for an ISDN (remember that?) test system called the A8619. It was basically a PC, with a custom card in it, which contained (amongst many other things) another x86 processor. There was another team having trouble programming the x86 on the card. You wrote software for the card in C, compiled it to a binary, burnt it onto a prom, put it in the card, rebuilt the PC. It hurt; they were getting nowhere fast. So these chaps wrote a simple program for the card. It just sat there waiting for the host PC to send it another program.

Whenever host PCs program was restarted it would send the latest binary down to the card. Suddenly the development cycle became compile and run. I often felt that games I’ve worked on needed this – big titles take an age to load and then navigate to the area you’re trying to test. Only then do you find out that it works or not. Rubbish!

We can do better. Unity does – it supports live code reloading while running the game in the editor. There’s limits, of course, so code reloading broke at some point while we were developing Monkey Slam, and never got fixed. Next time I want to understand what’s acceptable, and keep it going all the way through. The code reloading uses Unity’s underlying serialization mechanism to preserve state while code is unloaded and reloaded. The only difference between ‘editor’ serialization and the normal case turns out to be that private variables are serialized for code-reloads.

This makes total sense to me intuitively. When you did a little deeper it become clear why Awake() is used instead of a constructor. The constructor is called after every code reload; Awake() is only called when the object is created. The correct values are serialized into each object after code-reload after each object is constructed. Breaking the game on code-reload simply means that something in the run-time state is not being correctly serialized. The Unity documentation covers the basics, but left me with a bunch of questions. Here’s a few more details:

  • Statics: are not serialized at all. Initial assignment and static constructors will re-run on code-reload.
  • Properties: all properties are not serialized. Counter-intuitively that’s what you want. Properties are code – they will work after code-reload as long as the object state is correctly serialized. For auto-generated properties the private backing field is serialized fine.
  • Collections: arrays and List are serialized are documented as being the only serialized collections. They work, but Queue and Dictionary do not. The loss of Dictionary is the biggest roadblock for me. Add Dictionary and I could imagine writing a game. Without Dictionary that’s … hard.

The good news is though that you can nest one of the supported collections within a class of your own and have it serialize correctly. So it’s perfectly possible to implement Queue on top of List and have Unity code-reload it. You could also do that for Dictionary if you’re prepared to settle one of the performance compromises possible implementing it while relying on List serialization. I suspect in many cases one of these implementation strategies and compromises would be acceptable:

  • a linear search over unsorted List. For relatively small numbers of entries this is probably fast enough. Assuming List uses a contiguous block of memory internally it may even faster for less than about 100 items as it’s cache friendly.
  • maintain a sorted List. In this case lookup is fast, but insertion is linear as list entries after the insertion point need to be moved. Great for read-only data.
  • use a contained Dictionary and in the Unity editor maintain a backing List which all Dictionary entries are appended to. You can avoid slow lookups on the List by blinding appending new values. On code reload you take the last value for a given key from the list and insert it into a clean Dictionary. To avoid an arbitrary size overhead of the List you could “garbage collect” the List if it’s size became bigger than a certain multiple of the Dictionary size.

All of the above would make a great projects for GitHub. I’d be tempted just to implement the Dictionary with a linear search over a List first, until there was a clear performance reason for other solutions. Years ago, when people wrote their own collections routinely I wrote a lot of software that just used lists and it was almost always fine!

I guess the question is whether that’s all worth it to maintain code-reloading? Alternately @Unity3D could we get Dictionary serialization working please?

Post Script

Recently there have been a couple of great blog posts about Unity serialization, both worth checking out. The main Unity blog has a lot of serialization details posted, and Jacob Pennock wrote a great post on leveraging Unity serialization for game configuration. I’d love to see all this detail wound into the Unity documentation.

So What Perforce Changelist Have I Got?

I’ve just used Perforce for the first time on a big project, and it was … ok. Feature-wise I’d use Git, Mercurial or Accurev in an instant instead, but I suspect that both the project’s history and scale were the reason behind using Perforce. Unlike all of the above Perforce has per-file versioning, rather than per-repository versioning. Commits to the repository are a sequence of changelists, each of which, presumably, must internally list out the revisions of each file in the repository. It didn’t seem to be widely known how to query Perforce to ask local workspace what the current changelist you have is. A bit of digging reveals that:

p4 changes -m1 /...#have -s submitted

Does the trick.

In Perforce you can update any file to any revision of that file, separate from updating to a changelist. In that case I’m not sure what the command will give back, but clearly a single changelist number can’t fully describe a local workspace where even a single file has been updated separate from a changelist.

Coroutines In Unity3D – The Gritty Details

In my last post I talked about why some code is easier to write, read and maintain in Unity 3D when it’s written using coroutines, and touched on how Unity3D uses C# iterators to implement them. Now let’s look at how Unity3D makes these work as coroutines.

With iterators your code is responsible for creating an iterator and causing the iterator code to continue after a yield statement, such as using foreach in the MSDN example. In Unity’s world coroutines work if you are a class derived from MonoBehaviour. This class has a function StartCoroutine() which can start any function which returns IEnumerator as a coroutine.

Coroutines aren’t very useful until they include a yield statement. Unity uses the values returned by yield as scheduling information – to decide when to call the next portion of the coroutine. I’ve never found a complete list of acceptable return values from yield for Unity3D. Here’s the ones I know about:

It’s not multithreading!

There’s no multi-threading going on here. All scripts in Unity are called on a single thread, so no locking of variables is required. However other scripts may change global or object state between function calls or across a yield instruction. At times it becomes important to know when during a frame the coroutine will be executed. The overall execution order documentation says:

  • Most coroutines run after Update() and before LateUpdate()
  • Coroutines started from LateUpdate() run after LateUpdate()
  • return yield new WaitForFixedUpdate() // causes a coroutine to run after the next FixedUpdate()

As a final complication StartCoroutine() causes the coroutine to run immediately, until its first yield.

That All Sounds Hard

It’s not. I’ve dug in here, and documented all the gritty details. 90% of the time you don’t need these details at all. Looking at my coroutines they are almost all using

  • yield break;
  • yield return null;
  • yield return StartCoroutine().

What are you waiting for? If it sounds like coroutines will solve a problem for you – try them out!

C# Coroutines In Unity3D

Why?

It seems like the best way to explain coroutines is by example. We’ll look at a portion of the class which controls the front-end in a game, and doesn’t use coroutines. It’s not horrible, but the logic is scattered across a delegate – OnPlayButton() and UpdateFrame(). We need a class member to hold a reference to the active UI page.

public class Frontend: GameState
{
    // need a member variable to hold a reference between functions
    private ZoneSelectUIPage mZoneSelectUIPage;

    public void Create()
    {
        mPlayButton = UITextButton.Create(GlobalResources.Instance.ButtonToolkit,
                                          "blank_up.png", "blank_down.png", font,
                                          fontMat, fontDropShadowMat, fontHighlightMat);
        mPlayButton.SetText("Play");
        mPlayButton.pixelsFromTopLeft(20, 20);

        // add delegate to handle button presses
        mPlayButton.AddOnTouchUpInside(OnPlayButton);
        ...
    }

    private void OnPlayButton(UIButton sender)
    {
        Hide();

        mZoneSelectUIPage = ZoneSelectUIPage.create();
        mZoneSelectUIPage.Show();
    }

    // called once a frame - that's how the game engine works!
    public GameState UpdateFrame()
    {
        if (mZoneSelectUIPage != null)
        {
            if (mZoneSelectUIPage.Level >= 0)
            {
                GlobalResources.Instance.SetLevel(mZoneSelectUIPage.Zone,
                                                  mZoneSelectUIPage.Level);
                mNextState = LevelLoadState.Instance;
            }

            if (mZoneSelectUIPage.Done)
            {
                mZoneSelectUIPage.Destroy();
                mZoneSelectUIPage = null;

                Show();
            }
        }

        return mNextState;
    }
}

On top of that there’s also a bunch of code to test whether mZoneSelectUIPage is null – we may not have one! The page also needs to explicitly contain a property ZoneSelectUIPage.Done which we can test to see if it’s work is done. Re-writing that using coroutines moves the logic into a single function CoroutineUpdate() and makes the logic linear to read.

public class Frontend: MonoBehaviour, GameState
{
    public void Create()
    {
        mPlayButton = UITextButton.Create(GlobalResources.Instance.ButtonToolkit,
                                          "blank_up.png", "blank_down.png", font,
                                          fontMat, fontDropShadowMat, fontHighlightMat);
        mPlayButton.SetText("Play");
        mPlayButton.pixelsFromTopLeft(20, 20);

        // now we start a coroutine to do our work
        StartCoroutine(CoroutineUpdate());
        ...
    }

    // called once a frame - that's how the game engine works!
    // bridge to the engine by having the coroutine set mNextState
    public GameState UpdateFrame()
    {
        return mNextState;
    }

    public IEnumerator CoroutineUpdate()
    {
        while (true)
        {
            // wait until the next frame update
            yield return null;

            if (mPlayButton.TouchUp)
            {
                Hide();

                ZoneSelectUIPage zoneSelectUIPage = ZoneSelectUIPage.create();

                yield return StartCoroutine(zoneSelectUIPage.CoroutineUpdate());

                if (zoneSelectUIPage.Level >= 0)
                {
                    GlobalResources.Instance.SetLevel(zoneSelectUIPage.Zone,
                                                      zoneSelectUIPage.Level);
                    mNextState = LevelLoadState.Instance;
                }

                zoneSelectUIPage.Destroy();

                // exit the coroutine
                yield break;
            }
        }
    }
}

Also we no longer have to check whether zoneSelectUIPage is null – it’s a local variable we’ve just created – or whether it’s finished. Once ZoneSelectUIPage.CoroutineUpdate() returns it’s done.

For this simple example the code is neater and simpler. As more buttons and pages are added the more of a win using coroutines is. Often game classes will end up with a state enumeration and state member variable, and the UpdateFrame() function becomes a gigantic switch statement. Each state may need additional variables, which become member variables. Over time it becomes hard to follow the logic and remember which variables affect which state. I’ve always found code like this to be hard to write and harder to read. With coroutines the entire state machine is written in a linear fashion with local variables and yield statements. There’s a more direct mapping of the code written to its effect. That’s got to be a win!

C# Support

C#, of course, doesn’t really support coroutines. You’ve probably noticed that I’m using yield statements which are part of iterators. Iterators provide the language infrastructure to return a value from partway through a function (using yield), and then start executing the function again at a later time from just after the yield statement. Unity3D adds support for using iterators as coroutines, which I’ll cover in my next post.

A Games Programmer at Full Frontal – Javascript Conference

I am a games programmer. I work in GLSL/HLSL, C++ and C#, mainly. What was I doing at a JavaScript conference?

  • The browser is everywhere
  • JavaScript powers programming in the browser
  • JavaScript performance is radically better than it used to be
  • WebGL is in Firefox / Chrome / Opera – GPU access in the browser
  • Browser API are increasingly covering games needs: full-screen, mouse capture

Of course it helps that the conference is in my home town, in the funky Duke of York cinema and has a reputation for being world-class event.

I enjoyed all the talks, but I’m only going to talk about the ones that resonated the most strongly with me:

CoffeeScript

Smoothing over the rough edges of JavaScript it’s a language that compiles into JavaScript. Normally I’d run a million miles from that sort of language translation, but with a mantra of “It’s just JavaScript” this might well be worth trying out. Jeremy Ashkenas spent a deal of time showing the clean, readable JavaScript that gets output in a very convincing way. I was sold on the idea of implementing new language ideas and proposals for JavaScript in CoffeeScript. Right now it feels like I need to do a much bigger project in JavaScript before I jump to the next level.

Excessive Enhancement

Phil Hawksworth’s talk resonated with me. On one level it was a plea to remember the user experience when adding fancy ‘shizzle’ to the web. The whole thing reminded me of front-ends for games. In games often the front-end is often completely bespoke, built on homegrown technology or possibly flash with a bunch of 3D thrown in for good measure. I’ve seen beautiful, logical, fun front-ends in video games, but they’re the exception, not the rule. We need to learn from the web!

Beyond The Planet Of The Geeks

I wish I could bottle Brendan Dawes’ charisma, enthusiasm and wittyness, and keep it on tap for grey horrible days like today! It was great to see someone enthuse and obsess about tools and quality: “whoever said a bad workman blames his tools was a moron and I want to smash his head in with a beautifully made hammer”. There isn’t a single, simple takeaway from this talk. My notes at the time say “explore serendipity, question everything, do more of this every day”. A nice thought!

You gotta do what you gotta do

In his 20% time at Google Marcin Wichary helps out on the Google doodles. He’s got unreasonable enthusiasm and set of smarts to back it up. “Nothing is impossible” he says – you can see that from his work. His presentation setup alone was:

  • presentation running in Safari on a Mac
  • Chrome sending accelerometer information from the Mac to Safari
  • his iPhone connecting to the same site as Safari and remote controlling the slides

I remember him talking about at least these doodles:

What’s so remarkable is not just the ideas, polish, and production values, but also that they really work in almost every browser out there – including IE6. They’re not just the latest html5 and Chrome only shizzle. The dancing 2D animation in the last link was done by exporting a whole image for each frame, calculating the minimum different rectangular image region, packing all these into a single image, then having JavaScript add the next frames difference image to the page on a timer. It’s such a neat hack I’m sure Marcin must have been a games programmer back in the day 🙂

His final thought was if you’re not doing something which feels hacky you’re certainly not pushing the state of the art!

More than that

What I liked most of all was the warmth of everyone that I met. It’s a friendly community, make no mistake 🙂 It was great to see Max Williams again who took the time to introduce me to people.

My only disappointment was that I couldn’t stay at the after-party for very long. Big mistake! Not only did I miss a lot of free beer, but I missed the chance to meet and share with a lot of interesting people. Judging by the tweets from the following morning I also missed a killer hangover. Next year I’ll make sure I have no plans for the next day, and painkillers at the ready.

Giorgio’s Tiramisu

Long ago I was an exchange student in Germany, and lived next door to Giorgio, an exchange student from Italy. He gave me his mum’s recipe for tiramisu. It was fantastic! That was almost 20 years ago. I lost the recipe, and never knew it well enough to make from memory. Occasionally I’d see a tiramisu recipe in a book or magazine. They were never anything like the recipe I knew. Tiramisu varies a lot! Last year I found Delia’s tiramisu – it’s the real deal! As per Giorgio’s mum’s recipe I don’t put in any rum, and use a dusting of cocoa powder instead of the chocolate. Which looks like:

Italian Tiramisu

These days some people don’t want to eat food which contains raw eggs, due to the risks of salmonella. Personally I use really fresh eggs for this, and make sure they have the Lion Mark. You choose!

Sons and their Dad’s Work

My eldest son is about six and a half now. For the last couple of years, from his perspective, my work has become a magical place. I’m lucky that I really enjoy what I do, but the office itself is never going to have that aura of magic for me that it has for Tom. To him, it’s like Disneyland. I can pretty much buy off a trip to Disneyland Paris with the promise of taking him into my office at the weekend. Practically the office doesn’t have any reason to excite him – there’s a lot of desks, and a lot of computers. Mostly we take in our games from home and play them there.

I wonder why he thinks it’s so cool? I reckon it’s because I go off there most days “to bring home the bacon”, and because the rest is a mystery to him.

When I was about his age I thought the same of my father’s job, and office. He did electronic design in the automotive industry and I remember his workplace smelling of solder, engine oil and cigarettes. It was fantastic! He took the time to show me his office, the electronics design office and the garage floor. Now I realise how ordinary it all was, from his perspective, and how it was all about me and our relationship. Thanks Dad!