14
\$\begingroup\$

Game engines like Unity and Unreal can run on mutiple platforms. I am wondering how they do this.

I have been using C++ and OpenGL for a while, and what I am looking for is resources to integrate something that will allow me run on different platforms without rewriting. Something like LibGDX where you write code using a base API and then the API converts it to HTML, Android, iOS, et cetera. I am aware that I can use another engine instead of writing my own but I'm interested in the learning experience.

\$\endgroup\$

5 Answers 5

27
\$\begingroup\$

Port your engine to each platform. There's nothing special about it. If you have some code that is Windows-only, then either add some #ifdef logic in the file or add a second file (so you'd have FooWindows.cpp and FooLinux.cpp or whatever) that implements that feature on the other OS(es) you care about.

The one-click publish stuff that an engine like Unity has is allowed because Unity itself is never modified by the end-user. You're just writing scripts and data, so the engine has pre-built binaries for all the platforms and the publish button just bundles those binaries together with the data.

Other engines rely on build systems and cross-compilers to create the compiled game when needed, just like you would do with any non-game cross-platform application.

For things like HTML5, there are tools like emscripten that can compile a C++ application to run in JavaScript. You basically just need to make another port of your engine for emscripten (since it can't use any arbitrary C++ library/feature).

You don't have to rewrite your whole game, but you're definitely going to have to do a lot of development, coding, and porting work for each new platform you want to support.

\$\endgroup\$
1
  • 14
    \$\begingroup\$ In my experience working with crossplatform software (the biggest project would be HotSpot) you really want to avoid having ifdefs thrown through the code. It's definitely better to have something like share/os/<linux> (or share/cpu/x86) and put all the platform specific code in there and then do conditional includes. That's at least what gcc, HotSpot and the Linux kernel do (not a hard rule certainly). Yes you may start with only a single function that's platform dependent and think it's overkill but it never stays like that and it becomes a mess quickly otherwise. \$\endgroup\$
    – Voo
    Jul 10, 2014 at 19:39
14
\$\begingroup\$

There's no magic bullet here. If you want your game to run on multiple platforms, you have to write code for multiple platforms (or leverage third-party libraries that already do this for you).

The things you are asking for don't align: you say (emphasis mine)

what I am looking for is resources to integrate something that will allow me run on different platforms without rewriting

but also that (emphasis mine again)

I am aware that I can use another engine instead of writing my own but I'm interested in the learning experience.

You are pretty much going to have to do one or the other: elect to use a third-party library, engine and/or toolchain that provides cross-platform support for you, or build your own by writing cross-platform code (designing your own abstraction over the platforms you have available to you, and implementing that abstraction for each platform).

Game engines like Unreal or Unity that support this either recompile your code against the appropriate platform abstraction, or require you to build a library or DLL against their internal APIs, which they load from a platform-specific driver executable which they have compiled for the appropriate platform.

\$\endgroup\$
3
\$\begingroup\$

I'm building a cross-platform game engine at the moment. I'm using SDL, which is an excellent (and suitably low level) cross-platform library for building graphics applications, to ease the pain.

Beyond this, though, is a lot of "custom code" for each platform. This you just have to get through. I've found it to be a very small fraction of my development time so far, mostly spent looking up docs for systems I'm not as familiar with as my native Linux.

I'd discourage you from using #ifdef everywhere throughout your code. Instead, build abstractions around key primitives (an example of such a primitive might be a TCP socket).

When you encounter a new problem which requires different solutions per-environment, ask yourself "can I solve this problem using only the cross-platform primitives that I've already constructed?" If the answer is yes: voila, simple cross-platform code. Otherwise figure out what primitives you're missing and implement them.

\$\endgroup\$
2
\$\begingroup\$

Contrary to the other two answers (which are rightfully C++-specific), there is another way. Some architectures that come to mind:

  • Port your engine: Modify or write code so that it works across multiple platforms. This is addressed in the answers above.
  • Write something above a cross-platform library: This is the example of libGDX, which runs on Java. Java runs on Desktop, Android, and iOS (via RoboVM). By using something like Java, you get the benefit of free additional platforms when the underlying library/tool supports them. In this case, when RoboVM came out, libGDX (almost) "just works" on iOS.
  • Write a code generator: This is the approach of Haxe and other tools. You have a core language (eg. Haxe/AS3), and you write converters that generate output for other languages. Eg. Haxe converts to C++ for Desktop, Java (I think) for Android, etc.

Personally, I find the approach of libGDX is the simplest: find a language or platform that meets your needs, and write on top. Code generation and portable engines are complex and hard to write well.

libGDX is actually a great choice, since it hits both major mobile phones, desktop, and web (via applets or Google's web compiler).

\$\endgroup\$
3
  • \$\begingroup\$ Even with Java or C#, you don't get cross-platform code magically; you still have to be cognizant of 3rd party libraries that may have platform dependencies (for example, SlimDX or SharpDX would be a poor choice for a cross-platform C# project). \$\endgroup\$
    – user1430
    Jul 10, 2014 at 20:08
  • \$\begingroup\$ @JoshPetrie you certainly get a lot "for free" compared to rolling your own C++ engine and porting it across platforms. \$\endgroup\$
    – ashes999
    Jul 10, 2014 at 20:32
  • \$\begingroup\$ @ashes999 thanks for the answer, libGDX is brilliant I do use it but I'm going to write it so it works cross platform then use CMake, I'm more in it for the the challenge than using a pre existing library or engine \$\endgroup\$ Jul 10, 2014 at 20:45
0
\$\begingroup\$

If you want to do this "from scratch" as a learning experience then you'll need to use the Win32 API where you can find information about opening a window and an OpenGL context on MSDN and on the OpenGL wiki (http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)). For Linux get a second hand copy of the O'Reilly Xlib Programming Manual and the Xlib Reference Manual and also read up on GLX (OpenGL Extension to the X Window System). See also http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

Then you just need to provide the same API to your application with functions that do the same thing (e.g. open a window) but have different implementations for each platform. You rewrite parts of your engine for different platforms. Then a game you write using the engine you only have to write once but it will work on different platforms.

\$\endgroup\$
1
  • \$\begingroup\$ thanks for the answer but I would rather just use SDL2 for windowing, its cross platform and very easy to use. just how LibGDX uses LWJGL for windowing \$\endgroup\$ Jul 17, 2014 at 19:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .