Jan Adamec edited this page Jan 2, 2018 · 35 revisions

Supported iOS Devices

The engine should work with all devices running iOS 4.2 or newer. It was successfully tested with iOS 5.1, 7, 10, and the most recent iOS 11. The engine runs flawlessly on iPhone Simulator as well.

Overview and Examples

There are two ways to use the engine on iOS:

  1. The advised (and easier) way is to use the build tool to compile and package your game for iOS. Doing it is a matter of preparing CastleEngineManifest.xml for your project (with game_units or ios_source defined), and then running castle-engine package --target=ios. This gives you a ready project that you can open, run and publish from Xcode. This is the advised approach if you develop games using Object Pascal.

    Various engine examples demonstrate this approach. Try e.g. examples/2d_dragon_spine_game/ or examples/2d_standard_ui/zombie_fighter/ .

  2. An alternative way is to use the engine as a library that exposes a simple functionality of a VRML/X3D viewer. You can use this in your own custom Xcode projects. This approach is useful if you want to use the engine as a VRML/X3D file viewer, and wrap it in a custom user-interface in Xcode.

    The library API is defined in the src/library directory of the engine. An example application using this approach is located in examples/library/ios_tester.

    This approach is documented in more details on iOS Using the Custom Xcode Project page.

Building the App

Get macOS and Xcode

You will need any Mac computer with Xcode installed (available in Mac App Store, free).

Note: If you browse the documentation on http://wiki.freepascal.org/iPhone/iPod_development , it will talk about Xcode templates and proprietary iOS SDK headers. For the sake of developing games using Castle Game Engine, this can be ignored -- we don't need these headers or templates (since our entire GUI is drawn using GLES through Castle Game Engine).

Install FPC for macOS

You will need to install this before installing the cross-compiler.

The FPC compiler needs the "Xcode command-line developer tools" installed. In short, open /Applications/Utilities/Terminal and execute xcode-select --install.

See https://castle-engine.sourceforge.io/macosx_requirements.php for more information about developing desktop applications for macOS using Castle Game Engine.

Installing FPC cross-compilers for iPhone and iPhoneSimulator

You will need to have FPC cross-compilers able to create these OS/CPU combinations:

  • iphonesim/i386 and iphonesim/x86_64 applications (for the iPhone simulator)
  • darwin/arm and darwin/aarch64 applications (for the actual iPhone device). Note: aarch64 is also called arm64.

It's easiest to get them from the FPC:

Testing FPC cross-compilers

Before attempting the compilation of a full program, we advise testing that your fpc is installed OK and supports the necessary platforms.

First, test that you can compile for the necessary CPUs. The cross-compiler for each CPU is actually a different FPC executable, so the lines below will make an error immediately if you cannot cross-compile to the given CPU. The desired result is that they should answer No source file name in command line.

fpc -Pi386    -l # maybe add -V3.0.5
fpc -Px86_64  -l # maybe add -V3.0.5
fpc -Parm     -l 
fpc -Paarch64 -l 

Note: Add -V3.0.5 to the lines marked above, if you use the official "FPC for iOS" installed from fpc-3.0.5.intel-macosx.cross.ios.dmg file. See the Getting Started - iOS.rtf file inside for explanation.

Second, test the actual compilation.

cd /tmp/
echo 'library test_compilation; begin end.' > test_compilation.lpr

fpc -Pi386    -Tiphonesim -WP5.1 -XR${SIMULATOR_SDK} test_compilation.lpr # maybe add -V3.0.5
fpc -Px86_64  -Tiphonesim -WP5.1 -XR${SIMULATOR_SDK} test_compilation.lpr # maybe add -V3.0.5

fpc -Parm     -Tdarwin    -WP5.1 -Cfvfpv3 -Cparmv7 -XR${DEVICE_SDK} test_compilation.lpr
fpc -Paarch64 -Tdarwin    -WP5.1                   -XR${DEVICE_SDK} test_compilation.lpr

Every fpc invocation should create libtest_compilation.dylib.

The reasons behind some of these compiler options:

  • We test by compiling a library, not a program. Compiling a program fails at linking:
    • iphonesim/i386 error: Undefined symbols for architecture i386: "___keymgr_dwarf2_register_sections", referenced from:
    • iphonesim/x86_64 error: Undefined symbols for architecture x86_64: "___keymgr_dwarf2_register_sections"
    • darwin/arm error: Undefined symbols for architecture armv7: "start"
  • We use -WP5.1, otherwise the darwin/arm fails at linking (error: symbol dyld_stub_binding_helper not found, normally in crt1.o/dylib1.o/bundle1.o for architecture armv7).
  • The additional parameters (the -XRxxx, and -Cfvfpv3 -Cparmv7) come from the Getting Started - iOS.rtf file from the FPC for iOS package.

iPhone Simulator is not an iPhone emulator

The iPhone Simulator is not an emulator of a real iPhone device, i.e. it does not emulate the processor (like ARM) inside the iPhone. Rather, it's a modified version of the normal (desktop) macOS system, running on a normal (i386 or x86_64) CPU.

See "iPhone Simulator is not iPhone" on http://wiki.freepascal.org/iPhone/iPod_development for more information.

This should help you understand why we did some things above, e.g. why do we have a special compilation target for iPhone Simulator (because we cannot just run in the simular the application compiled for an actual iPhone), and why it works fast (because it doesn't emulate the iPhone CPU).

This is in contrast to the Android emulator.

Using the build tool

  1. Make sure the build tool is available on $PATH, so you can call castle-engine in the terminal.

  2. Run in terminal:

    cd <castle-engine>/examples/2d_dragon_spine_game/
    castle-engine package --target=ios

    Tip: You can speedup this process: The package command by default cleans and recompiles everything, to make sure everything is recompiled for the current mode (which is a release mode by default). When developing, it's often useful to make this process quicker, and recompile only what changed. Do this by adding --fast option:

    cd <castle-engine>/examples/2d_dragon_spine_game/
    castle-engine package --target=ios --fast
  3. Run Xcode and open the resulting project in <castle-engine>/examples/2d_dragon_spine_game/castle-engine-output/ios/xcode_project/.

  4. Run the project from Xcode (Command + R), to see your game working in an iPhone simulator.

    Tip: Scale the simulator window: You will often want to change scaling using the simulator Window -> Scale -> xxx menu item. Otherwise, the simulator window may be huge compared to your desktop.

    Tip: Running on a real, physical device: It works out of the box! You only need to set the Development Team in Xcode, or set <ios team="xxx" /> attribute in CastleEngineManifest.xml.

    Selecting a team in Xcode

Debugging the Pascal Code without iOS

Same instructions as for Testing mobile (OpenGL ES) rendering without an Android apply here too, as the Pascal code is platform independent.


The event loop on iOS must be controlled by the main program in Objective-C, not in Pascal. This means that Application.ProcessMessages does not work. The library cannot force the main process to handle some events, and wait for something to happen. This means that you cannot use Application.ProcessMessages, or things depending on them:

  • CastleMessages (functions in this unit make modal windows, running a message loop inside and only returning when user exits --- similar to ShowMessage in Lazarus LCL / Delphi VCL),
  • CastleWindowProgress (it processes messages to redraw the screen inside Progress.Step).

To make modal windows on iOS, use CastleDialogStates unit with modal windows using TUIState class. You can also set MessageOKPushesState to true. To show progress bar, use TCastleProgressBar control, which you will need to continuously update yourself, for example in your Window.OnUpdate event.

Also, on iOS, the OpenGL(ES) context is created and destroyed solely by the Objective-C code, not Pascal. You also cannot use the Window.Open and Window.Close from the Pascal code to force recreating OpenGL context.

More information about FPC and iOS

Alternative: Using FPC trunk (unstable)

Instead of using the stable FPC (3.0.4 / 3.0.5 now), you can try using the latest FPC trunk version (3.1.1 now). You need to install 4 cross-compilers, for all 4 platforms that are included in the "iOS target":

  1. arm / darwin
  2. aarch64 / darwin
  3. iPhoneSimulator / i386
  4. iPhoneSimulator / x86_64

An easy way to install cross-compilers is to use fpcupdeluxe. Notes:

  • iPhoneSimulator is called i-sim in the fpcupdeluxe UI.
  • Our build tool uses the fpc binary available on your $PATH environment variable. Make sure you create an appropriate symlink to make it call the FPC installed by fpcupdeluxe (this wiki page describes this).

When you compiled your own FPC version, you will want to use --fpc-version-iphone-simulator "" on the command-line to the build tool. Otherwise the build tool will try to call FPC 3.0.5 for iPhone Simulator target (because the standard FPC 3.0.4 / 3.0.5 mix requires this). So you will usually call this in your project:

$ fpc -v
Free Pascal Compiler version 3.0.4 [2017/11/26] for i386
$ castle-engine package --target=ios --fpc-version-iphone-simulator "" --fast
Compiling project "drawing_toy" for target "ios" in mode "release".
FPC version: 3.1.1
FPC executing...
Compiling Release Version
Target OS: Darwin/iPhoneSim for i386
Target OS: Darwin/iPhoneSim for x86_64
Target OS: Darwin for ARM
Target OS: Darwin for AArch64

TODO: Uh, right now FPC 3.1.1 seems to crash when compiling our engine for Darwin/AArch64 (other combinations work OK). That's an FPC 3.1.1 bug (not reported yet, as we have not yet identified the exact cause or distilled a testcase to submit -- if you want to help, it would be much appreciated).

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.