Linux commonly connotes with open-source zealots and a small PC market
share, not blockbuster video games. However, the arrival of Steam on
the platform might change the outlook quite dramatically, and Linux
support may soon become a must-have feature for your game. Setting the
open-source ideology aside, this lecture is an overview of the
technical challenges a game developer may face while porting their
game to this platform, along with solutions.
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
Linux as a gaming platform, ideology aside
1. Linux as a gaming platform
Ideology aside
Digital Dragons · 19-04-2013
Leszek Godlewski
Programmer
leszek.godlewski@thefarm51.com
www.thefarm51.com
2. 2
What is this talk about?
www.thefarm51.com
It's NOT about:
● Free software
● Ideology
● Business
It is about:
● Linux 101
● Development
● Deployment
2
3. 3
Who is this guy?
www.thefarm51.com
Cross-platform work
(→ de facto – Linux)
● github.com/inequation
● Toy projects, personal utilities,
university stuff
● Games as well!
● AC-130
● Crystal Space
● idTech 3-based games
● Painkiller Hell & Damnation
● Linux as preferred OS for 7+ years
● Former open-source evangelist
● Not anymore – lost interest
3
4. 4
Who is this guy?
www.thefarm51.com4
WHAT IF I TOLD YOU
WE PREACHED FREE SOFTWARE
10. 10
Kernel and the distros
www.thefarm51.com10
Linux distro
(Ubuntu, Debian, Fedora...)
Linux distro
(Ubuntu, Debian, Fedora...)
Linux
kernel
Linux
kernel
Free
software
Free
software
Proprietary
software
Proprietary
software
27+ supported CPU architectures!
http://en.wikipedia.org/wiki/List_of_Linux_supported_architectures
We usually mean i386/amd64
11. 11
Who and why uses Linux?
www.thefarm51.com11
Who:
● Scientists (TOP500)
● IT companies
● Hackers and
power users
Why:
● It's free (well, duh...)
● It's robust
● It's customizable
● Long, intrinsic traditions of free software
● No established channels of proprietary
software distribution
● But Steam can become a gamechanger!
12. 12
Standards
www.thefarm51.com
● Linux adheres to ISO/IEC standards, such
as POSIX and Single Unix Specification...
● System API – file system access, threading,
access control, IPC etc.
● Command-line shell utilities
● ...which also happen to be supported by
MacOS X, Android, iOS (yes, really!) and
a handful of other OSes
12
13. 13
Standards
www.thefarm51.com
● Linux has OpenGL (ES) for 3D graphics
rendering
● Linux has OpenAL for 3D audio with DSP
● Linux has BSD sockets for networking
● Linux has lots of other portable libraries
● And all of these things are also available
on other platforms – Android, MacOS X,
iOS, Windows!
13
14. 14
What does that mean?
www.thefarm51.com14
MacOS X
Linux Mobile
*
* not to scale; actual
overlap is greater
15. 15
There are issues, too
www.thefarm51.com
● Open source legacy → unstable ABIs
● Why need a stable one when you can just
recompile the source?
● This is why NVIDIA distributes glue code with
their drivers
● Extreme heterogeneity
● Package managers (software distribution
mechanisms)
● Patches applied to upstream code → potential
differences in functionality
● Highly customized system configurations
15
16. 16
There are issues, too
www.thefarm51.com
● Proprietary vs free GPU drivers
● Rule of thumb: free drivers perform more
poorly than proprietary ones
● Intel only has free, but the hardware is bad anyway ☺
● Legacy AMD/ATI GPUs only have free, and it's quite
good actually
● NVIDIA drivers are equally good as the
Windows ones
● AMD/ATI drivers are a bit worse than the
Windows ones ☹
16
17. 17
Solution?
www.thefarm51.com17
Assume Ubuntu.
● For development and testing alike
● Probably the most popular desktop
distro*
● This is what Valve does
- Bonus points: Steam compatiblity!
● Power users will get your game running
on others anyway
* there are claims it's Linux Mint now, but it's still based on Ubuntu
19. 19
Getting started
www.thefarm51.com
● Virtual machine
● Fair enough for building
● No such luck with testing
(unless you can virtualise your GPU)
● Native installation
● Painless dual boot
● Which disc image to download?
● Get whatever Valve recommends for
Steam
(the Most recent LTS release is a good bet)
19
20. 20
Tools
www.thefarm51.com
● Tons and tons of IDEs, mostly average
- Code::Blocks, Codelite are OK
- There's also Eclipse if you can stand it
● Tried & tested native code toolchains
- GCC, LLVM (clang)
- gold – the new multithreaded linker by Google
- GNU binutils – objcopy, objdump etc.
● VM toolchains
- Mono, OpenJDK/Oracle JDK
● Build tools
- GNU make, Cmake, SCons, GNU autotools
20
22. 22
SDL – the cross-platform “DirectX”
www.thefarm51.com
● Provides:
- API in C with mappings to other languages
- Timers and threads
- Input – mouse, keyboard, joysticks/pads (incl.
Unicode characters)
- Window management (incl. GL context)
- Audio (very barebone)
- 2D graphics (hardware blitting)
● Be sure to use 2.0 for new projects!
- Support for OpenGL 3+
- Support for multi-viewport apps
22
23. 23
SDL – the cross-platform “DirectX”
www.thefarm51.com
● SDL hides away most platform-specific code
- That's right, no need to even use POSIX!
23
int main (int argc, char *argv[])
{
// initialize SDL
if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER) < 0)
return 1;
// set window caption
SDL_WM_SetCaption("My SDL Game",
"MySDLGame");
// hide mouse, grab input
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
// make SDL clean up on exit
atexit(SDL_Quit);
// main game loop
while (1) {
// dispatch events
while (SDL_PollEvent(&ev)){
switch (event.type) {
// ...
}
}
}
SDL_ShowCursor(1);
SDL_WM_GrabInput(SDL_GRAB_OFF);
return 0;
}
24. 24
What if SDL doesn't cut it?
www.thefarm51.com
Despite its awesomeness, SDL has its
shortcomings
● No explicit GLX/WGL context data sharing
and no direct context access
→ no threaded rendering ☹
(hit this corner while porting Painkiller HD)
● No 3D positioning or DSP support in the
stock SDL audio subsystem
- Partially remedied by SDL_mixer
But we need those! Now what?!
24
25. 25
Just DIY – POSIX API
www.thefarm51.com
● Most WinAPI features map to POSIX
- Threading (pthreads)
- Advanced file I/O, incl. memory-mapped
- Advanced memory allocation, incl. paging
- IP sockets
25
#if defined(WIN32) || defined(__WIN32__)
Emitter->InternalPtr = VirtualAlloc(NULL,
Size, MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
// ...
#else // It's a UNIX system! I know this!
Emitter->InternalPtr = mmap(NULL, Size,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// ...
#endif
26. 26
POSIX API
www.thefarm51.com
There is an extensive, centralised reference
manual in the manpages-dev package
● Type in a shell to access:
man <section number> <subject>
● Section number cheat sheet
1. General console commands
2. System calls
3. C standard library calls
4. Special files (/dev/*) and drivers
5. File formats and conventions
26
27. 27
X11 client API
www.thefarm51.com
● Windows graphical mode maps to X11
- Xlib is a popular client library for the X(11) Window
System server
- XCB is a more modern replacement (often a back-
end for Xlib)
- Raw event pump, window management
- OpenGL interoperability via the GLX extension
27
// event loop
XEvent Event;
while (XPending(GX11Display)) {
XNextEvent(GX11Display, &Event);
switch (Event.type) {
// ...
}
}
28. 28
Joystick/gamepad API
www.thefarm51.com
● Not part of X11 input event framework
● Kernel block devices
- Created as /dev/input/js*
- Hotplug events via libudev (also in Steam
Linux Runtime)
- Handled via open() and ioctl()
- Detailed documentation in the kernel
http://kernel.org/doc/Documentation/input/joystick-api.txt
28
30. 30
Porting a D3D renderer to OpenGL
www.thefarm51.com30
Porting Source To Linux:
Valve's Lessons Learned
Valve & NVIDIA, GTC 2013
Video: http://goo.gl/jMX9A
Slides: http://goo.gl/FtA5k
31. 31
How to deal with heterogeneity?
www.thefarm51.com
● As mentioned earlier, library ABIs tend to
be unstable
- Glibc tags its symbols with version → multiple
versions for backwards compatibility
- Compile with newest version → binary might not
run on older versions
● The ELF format is constant; but even then:
- Dynamic libraries' “sonames” (including version
numbers) are baked in at link time → binary might
not run if system provides a different version
31
32. 32
How to deal with heterogeneity?
www.thefarm51.com32
How?
Static linking
+ will work forever
- binary bloat
Distribute with libs
+ will work forever
- redundant to other
games (also a form of
bloat)
- potential licensing
issues
33. 33
How to deal with heterogeneity?
www.thefarm51.com33
Or use the Steam Linux Runtime
https://github.com/ValveSoftware/steam-runtime
● Collection of essential packages “ripped”
from Ubuntu repos + patches
- freetype, glew, gtk+2.0, libgsm, libogg, libopenal1, libsdl1.2,
libsdl2, libvorbis, libtheora, libx11, libxcb, pulseaudio...
- Release and debug versions of all libs
● Ready-to-use GCC-based toolchains for
i386 and amd64
● Ships with Steam, so every (non-orthodox)
Linux gamer has it
34. 34
Steam Runtime for non-Steam games
www.thefarm51.com
● Start-up shell scripts are common practice
- Search for an installed Steam Runtime
instance
- If not found, install your private copy
- Only when the SLR is available, run the
actual binary
34
35. 35
Steam Runtime for non-Steam games
www.thefarm51.com35
#!/bin/sh
if [ -z $STEAM_RUNTIME ]; then
STEAM_RUNTIME=$HOME/.steam/steam/ubuntu12_32/steam-runtime
fi
if [ ! -d $STEAM_RUNTIME ]; then
# install private copy of Steam Runtime
fi
export LD_LIBRARY_PATH="$STEAM_RUNTIME/i386/lib/i386-linux-gnu:"
"$STEAM_RUNTIME/i386/lib:"
"$STEAM_RUNTIME/i386/usr/lib/i386-linux-gnu:"
"$STEAM_RUNTIME/i386/usr/lib:"
"$STEAM_RUNTIME/amd64/lib/x86_64-linux-gnu:"
"$STEAM_RUNTIME/amd64/lib:"
"$STEAM_RUNTIME/amd64/usr/lib/x86_64-linux-gnu:"
"$STEAM_RUNTIME/amd64/usr/lib:"
"$LD_LIBRARY_PATH"
# launch the actual game here
36. 36
Locales
www.thefarm51.com
● The C standard defines locales for language
and regional settings (see man setlocale)
● They affect *printf()/*scanf() and more
● Xlib can modify locale categories for GUI
apps (see man XSetLocaleModifiers)
● Example POSIX locales: pl_PL.UTF8,
en_GB.ISO-8859-1, ru_RU.KOI8-R
● The Linux manual might make it seem like
retrieving current locale is as easy as calling
char *locale = setlocale(LC_ALL, NULL);
36
37. 37
Locales
www.thefarm51.com
No such luck!
// backup the original application locale
char *Locale = setlocale(LC_ALL, NULL);
char *OriginalLocale = NULL;
if (Locale && *Locale)
OriginalLocale = strdup(Locale);
// reset locale to system (user) default
setlocale(LC_ALL, "");
// retrieve the default locale
Locale = setlocale(LC_ALL, NULL);
// process locale here
// restore original locale
if (OriginalLocale)
{
setlocale(LC_ALL, OrigLocale);
free(OriginalLocale);
}
37
38. 38
Extracting debugging symbols
www.thefarm51.com
● We often want to keep symbols for
shipping binaries
● On Windows – keep the .pdb files
● On Linux
objcopy --only-keep-debug
"${tostripfile}"
"${debugdir}/${debugfile}"
strip --strip-debug --strip-unneeded
"${tostripfile}"
objcopy --add-gnu-debuglink=
"${debugdir}/${debugfile}"
"${tostripfile}"
38
39. 39
Crash handler
www.thefarm51.com
● On POSIX this is called a signal handler
● Signals are a primitive IPC mechanism used
not only for crashes
- Debugger traps, floating point exceptions, terminal
hangup, exit requests... See the output of kill -l
● You can take a shortcut by using:
- libSegFault – part of glibc, try:
$ LD_PRELOAD=/lib/libSegFault.so
/lib/libSegFault.so
- Andrew Tridgell's segv_handler
http://www.samba.org/junkcode/#segv_handler
39
40. 40
A word on licensing
www.thefarm51.com
Whenever you use a library, check its
licensing terms!
● GPL is restrictive
- Requires derivative works to use GPL
→ sharing the source code
● LGPL is restrictive with linking exception
- Allows linking to an LGPL library without
sharing the source code
● MIT, BSD and Zlib licenses are generally
permissive, some might require advertising
40
42. 42
Where do I put the files?
www.thefarm51.com
● Windows
- Game data and binaries: C:Program Files
- User data: %APPDATA%, Documents...
- AoS-like organization
● Linux (conventional)
- Game binaries: /usr/bin/, /usr/games/
- Game data: /usr/share/games/
- User data: $HOME/.config/
($XDG_CONFIG_HOME environment variable)
- SoA-like organization
- Filesystem Hierarchy Standard
42
43. 43
Where do I put the files?
www.thefarm51.com
● FHS mainly concerns distro packages
● Proprietary software often installs into
/opt/<package name>/
(“Add-on application software packages”)
● Proprietary software also often installs
“wherever”
● Steam games live in
~/.steam/steam/SteamApps/
● Just put game data and binaries in one
place, and save user data to ~/.config/
43
44. 44
Creating installation bundles
www.thefarm51.com
● Not relevant for Steam games (duh)
● Simple .tar.gz archives
$ tar czvf <archive name>
<input files...>
● Distro packages (.rpm, .deb...)
● Self-extracting command-line installers as
shell scripts
https://coderwall.com/p/y3upqw
● MojoSetup
http://icculus.org/mojosetup/
44
46. 46
Summary
www.thefarm51.com
● Engineering costs of a Linux port for an
already multiplatfrom game engine are low
- “It's just an API”™
● SDL covers a lot of boilerplate for you
● Overcoming heterogeneity is essential
- Steam Linux Runtime is helping to fix it
● Watch out for those licenses!
● When in doubt:
- Use Ubuntu
- Do whatever Valve does
46
48. 48
Special thanks
www.thefarm51.com
Ryan “Icculus” Gordon
Inspiration & software contributions
Michał Wielgus
Critical review & free software comrade
Reinhard Pollice
Getting stuff done for me on the PKHD port
48
49. 49
Thank you!
Like us on Facebook!
http://www.facebook.com/farm51
http://www.facebook.com/deadfalladventures
http://www.facebook.com/PainkillerGame
leszek.godlewski@thefarm51.com
www.thefarm51.com