Running Unity3D in a Virtualized Headless Ubuntu Environment

Jon Ibasco
5 min readOct 29, 2015

--

Over the past few months, I’ve been having this obsession with finding out how to write cleaner, smarter code for video games — an obsession that was inspired by John Carmack’s blog post about static code analysis and my experience with doing game dev for about a year and maintaining a non-trivially sized codebase of a mobile game (not to mention a not-so-secret nagging feeling that my code will perpetually suck).

So my first step to stifling this obsession is figuring out how to make automated testing a part of my workflow, and I figured that setting up a headless, virtual Linux environment that can run Unity3D would be a good place to start (with setting up a continuous integration server as the end goal). Luckily, Unity Technologies had just released an experimental Linux editor (and at least one engineer seems to be regularly working on it).

For my experimental setup, I set up a bare Ubuntu 14.04 virtual machine with Vagrant and downloaded the current latest build. These initial steps are fairly straightforward, and just involve following instructions (assuming a little familiarity with Linux and virtual machines).

There are three issues that you will likely encounter, and some of these might be challenging to solve with just Google search-fu because of the current scarcity of info you can find online about running a headless Unity 5 editor in a headless Linux environment.

1. Installation and Dependencies

Once you run `dpkg` to unpack and install the Unity package, you might encounter something like this:

dpkg: error processing package unity-editor ( — install):
dependency problems — leaving unconfigured
Processing triggers for mime-support (3.54ubuntu1.1) …
Errors were encountered while processing:
unity-editor

This can be solved by simply running

sudo apt-get update && sudo apt-get install -f

After that, try to install the Unity3D package again.

2. Running Unity3D in -nographics mode

Once you’ve installed Unity3D (“Holy crap, I can finally run Unity3D on Linux now without using WINE! … Oh, wait.”), trying to run

/opt/Unity/Editor/Unity -batchmode -nographics

— which tells the Unity editor to run in headless mode (-batchmode) and to “not initialize graphics device at all” (-nographics; more info on Unity3D documentation) — will yield this error:

QXcbConnection: Could not connect to display

Fortunately, this error message makes it fairly obvious what the error is about, but you might want extra info by making Unity more verbose, which you can do by adding the -logFile flag:

/opt/Unity/Editor/Unity -batchmode -nographics -logFile

With verbose logs turned on, you’ll find that even with the -nographics flag, the Editor is still seemingly looking for a display:

Forcing GfxDevice: 4
NullGfxDevice:
Version: NULL 1.0 [1.0]
Renderer: Null Device
Vendor: Unity Technologies
....
Receiving unhandled NULL exception
Launching bug reporter
#0 0x007ffc4b6015c0 in _L_unlock_13
#1 0x007ffc4b601a38 in _XimLocalSetICValues
#2 0x007ffc4b601a40 in _XimSetICDefaults
#3 0x007ffc4b601ab0 in _XimSetICDefaults
#4 0x007ffc4b601b20 in _XimLocalCreateIC
#5 0x007ffc4b601d50 in XCreateIC
#6 0x007ffc4b601e60 in InitX11ToSDL()
#7 0x007ffc4b6025f0 in InputInit()
#8 0x007ffc4b602600 in InitializeEngineNoGraphics()
#9 0x007ffc4b602640 in Application::InitializeProject()
#10 0x007ffc4b602be0 in InitializeUnity(void*)
#11 0x007ffc4b602c60 in main
#12 0x007ffc4b603000 in __libc_start_main
#13 0x007ffc4b6030c0 in _start

This can easily be solved by running the Editor with an X11 server, i.e. xvfb. (The xvfb package on Ubuntu is simply called xvfb.)

After rebooting, rerun Unity, but this time prepending xvfb-run, i.e.

xvfb-run /opt/Unity/Editor/Unity -batchmode -nographics -logFile

The QXcbConnection error should now have been silenced.

3. ALSA/sound problems

For this, I discovered three possible solutions. I shall enumerate them from complicated to simplest in an attempt to chronicle my experience. :P

3a. ALSA/sound problems — Complicated Solution

This is where it gets arguably tricky (and where my Google search-fu failed me when I tried to search for Unity3D-related stuff): attempting to run the editor with the same flag, you will now get

ALSA lib confmisc.c:768:(parse_card) cannot find card ‘0’
ALSA lib conf.c:4248:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory
ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings
ALSA lib conf.c:4248:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory
ALSA lib confmisc.c:1251:(snd_func_refer) error evaluating name
ALSA lib conf.c:4248:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:4727:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM default
....
Importing game controller configs
m_SoundManager
(Filename: /home/builduser/buildslave/unity/build/Runtime/Audio/AudioManager.cpp Line: 2575)Receiving unhandled NULL exception
Launching bug reporter
Setting up 1 worker threads for Enlighten.
#0 0x007ffe6c1fd340 in _L_unlock_13
#1 0x007ffe6c1fd790 in SoundManager::UpdateChannels()
Thread -> id: 7fe573343700 -> priority: 1
#2 0x007ffe6c1fd7b0 in SoundManager::Update()
#3 0x007ffe6c1fd8a0 in PlayerLoop(bool, bool, IHookEvent*)
#4 0x007ffe6c1fda10 in Application::UpdateScene(bool)
#5 0x007ffe6c1fda90 in Application::UpdateSceneIfNeeded()
#6 0x007ffe6c1fdaa0 in Application::TickTimer()
#7 0x007ffe6c1fdbf0 in MainMessageIteration(void*)
#8 0x007ffe6c1fdc00 in InitializeUnity(void*)
#9 0x007ffe6c1fdc80 in main
#10 0x007ffe6c1fe020 in __libc_start_main
#11 0x007ffe6c1fe0e0 in _start

While the error messages are less obvious this time, they’re at least kind enough to inform me that I am now having problems related to Unity3D audio. I figured that this was a similar problem to the graphics problem, so I searched for ways to create a dummy sound device (something a virtual machine obviously doesn’t have by default), which brought me to the ALSA website and a Reddit thread.

First, you have to install snd-dummy, which is basically a dummy sound driver for a dummy device:

sudo apt-get install — reinstall linux-image-extra-`uname -r`

After that, run

sudo modprobe snd-dummy

to insert the snd-dummy module into the kernel and confirm that it has been installed successfully. Once you have confirmed the installation, open /etc/modules with root access using your favorite text editor, e.g. `sudo vi /etc/modules`, and add the line `snd-dummy`. Your /etc/modules might look like this:

# /etc/modules: kernel modules to load at boot time.# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with “#” are ignored.
# Parameters can be specified after the module name.
snd-dummy

Then open /etc/group with root access and add “vagrant” — or whatever group your current user is in (which you can find out by entering “groups” on the command line) — to “audio:x:29", e.g.

audio:x:29:ubuntu,vagrant

Finally, reboot your virtual machine. Running Unity3D with the same flags should no longer crash.

3b. ALSA/sound problems — Really Simple Solution

After doing more reading, I learned about PulseAudio, which is a sound server that can take input from some “source” (for our case, the Unity3D editor) and reroute it to a “sink” (a sound card, or another PulseAudio process over a network). I’m honestly not sure where PulseAudio reroutes the sound from the Editor, but I guess it provides whatever it is the Editor needs under the hood (i.e. preventing the null exception in SoundManager::UpdateChannels()).

To install PulseAudio, simply run

sudo apt-get install pulseaudio

3c. ALSA/sound problems — Even Simpler Solution (that makes me feel stupid *facepalm*)

Simply passing the `-quit` flag to /opt/Unity/Editor/Unity will still output ALSA-related errors, but will make the Editor quit before SoundManager can run. :P

However, this may cause unforeseeable problems in the future, so I recommend solutions 3a or 3b, respectively.

Conclusion

I hope this will help some poor person who will happen to encounter similar problems. :D

If you’re curious about how automated testing works on Unity, check out Unity’s blog posts on it (part 1 and part 2) and download the example. You can run the tests in the example by entering

xvfb-run /opt/Unity/Editor/Unity -projectPath PATH_TO_EXAMPLE -batchmode -nographics -executeMethod UnityTest.Batch.RunUnitTests -resultFilePath=results.xml -logFile

Happy automating and testing (which is something I’m still figuring out with Unity and probably deserves another blog post)!

--

--

Jon Ibasco

Third culture kid. Indie game developer, software engineer, and data nerd. Avid consumer of the mundane and Absurd.