macOS

1. Installation of FPC and Lazarus

Just install Lazarus for macOS from the official Lazarus webpage (FPC is also included in Lazarus download).

Note
Alternatively you can also install FPC / Lazarus using your favourite package manager: Homebrew, MacPorts, Fink.

The FPC compiler needs the XCode command-line developer tools installed. To do this, open terminal (/Applications/Utilities/Terminal) and execute xcode-select --install.

The latest macOS doesn’t include gdb (a debugger, user underneath by Lazarus) by default. Lazarus will warn you about this on the 1st run. You can install GDB e.g. using HomeBrew, just execute brew install gdb.

More information:

2. Using TCastleWindow

2.1. TCastleWindow with X (Xlib backend)

Xlib is for now the default backend on macOS. While it does not look pretty, and does not show a menu bar, but it’s easiest to use right now.

To use it, install XQuartz and recommend your users to do it too. Our programs will appear as part of "X11 server" on your desktop.

To compile, you also need to add this line to your fpc.cfg file:

-k-L/usr/X11/lib/
Warning

If you get an error (when running our applications) that glX extension not found: Check do you have a /usr/X11R6 symlink (e.g. by running ls /usr/X11R6 in the terminal). Some versions of XQuartz seem to not install it (see here). You can fix it on your system by:

sudo ln -s /usr/X11 /usr/X11R6

Alternative fix (see here):

sudo /usr/libexec/x11-select /opt/X11
sudo chmod a+rX /usr/X11/ /usr/X11R6/

2.2. TCastleWindow with Cocoa (using LCL backend)

Using Cocoa means that your application will look pretty and native.

To do this:

  • open your project in Lazarus

  • change in Project Inspector castle_window.lpk to alternative_castle_window_based_on_lcl.lpk

  • compile from Lazarus (in this approach, you cannot compile using CGE build tool or editor).

Internally, this means that TCastleWindow is using LCL backend, and LCL in turn is using Cocoa.

TODO:

We plan to improve this situation, because

  1. The above approach means that we rely on LCL event loop. E.g. mouse look may "stutter".

  2. The above approach means that you cannot build from CGE build tool or editor, as they don’t link LCL.

The plan is to implement CastleWindow backend based directly on Cocoa (without using LCL in the middle).

Can you help us with this?

  • It’s a matter of creating and implementing a file castle_game_engine/src/window/castlewindow_cocoa.inc, based on castle_game_engine/src/window/castlewindow_backend_template.inc.

  • Or send Michalis a simple and clear example of FPC program using Cocoa that 1. creates and shows a window, 2. with menu bar 3. and with OpenGL context area covering the window.

3. Using TCastleControl

Using TCastleControl on macOS is completely standard. Just drop TCastleControl on LCL form.

TCastleWindow is our most advised way to create a window where Castle Game Engine can work.

4. Other libraries

OpenAL (sound)

(For macOS older than Tiger, that is ⇐ 10.3). OpenAL may be downloaded from Creative, see download links from openal.org downloads.

In macOS > Tiger, OpenAL comes already preinstalled.

Even without OpenAL installed, all our programs will still work fine, you just will not get any sound.

VorbisFile (reading OggVorbis)

It may be installed using MacPorts, Homebrew or Fink.

LibPng

If you want to use LibPng library in your programs, to read PNG faster, you can install it using MacPorts, Homebrew or Fink.

Note that this is not necessary. If we don’t find LibPng, we will fallback to reading PNG using Vampyre Imaging Library, which works too.

FreeType (reading font files)

It is available in package managers like Homebrew. As a fallback we will also try to use FreeType version installed by your X11, in /usr/X11/lib/ .

5. Creating macOS applications

  • Make "macOS bundle". It’s basically a directory pretending to be an application.

    You can use Lazarus to create macOS bundle. Or you can use our create_macosx_bundle.sh script. The example usage is inside view3dscene and castle-view-image sources.

  • Optionally, add libraries (like libpng and vorbisfile) to the bundle. If you link to them dynamically (e.g. using our TDynLib.Load), you should load them from a path relative to BundlePath, like BundlePath + 'Contents/MacOS/libpng.dylib'.

    See macOS Libraries on FPC wiki for general instructions how to include library inside a bundle.

  • Pack the bundle into a .dmg file. See Building Fancy DMG Images on macOS for nice description how to make the directories inside dmg look pretty, so you can visually suggest user to drag your application in the Applications folder.

    Alternatively, you can pack the bundle into a regular zip file. There are convincing arguments that using ZIP is actually more user-friendly than DMG (users can just double-click to unpack, and they have the application; they don’t need to understand how "disk image" works). See also here for discussion. And making zip is definitely simpler.

    Alternative method of distribution macOS applications is the package manager (.pkg). For normal applications (like games) the simpler .dmg or .zip are a better choice.

5.1. Packaging data with macOS applications

Behavior of the data directory (castle-data: protocol) on macOS:

  • On macOS, if you run the application through the "application bundle", then we expect the data to be found inside MyApplication.app/Contents/Resources/data subdirectory. This way user can move around MyApplication.app to move, install and uninstall the application.

  • If the MyApplication.app/Contents/Resources/data subdirectory is not found, we will use the data subdirectory that is sibling to MyApplication.app. This feature is intended to be used only during development. This way things work "out of the box" if you run through Lazarus, with checkbox “Use Application Bundle for running and debugging”.

  • When distributing the application to the end users, you should manually copy the “data” subdirectory inside the bunde (to MyApplication.App/Contents/Resources/data).

    In case of compiling and packaging using our build tool we could do it automatically at some point (although it’s not implemented for now).

    In case of using Lazarus to create the bundle — you will have to do it manually always.

    I recommend writing a simple shell script to create the bundle. Copy the data like this:

    rm -Rf MyApplication.app/Contents/Resources/data
    cp -R data/ MyApplication.app/Contents/Resources

To improve this documentation just edit the source of this page in AsciiDoctor (simple wiki-like syntax) and create a pull request to Castle Game Engine WWW (cge-www) repository.