Compiling for iOS
Relevant source files
The following files were used as context for generating this wiki page:
- ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java
- ios/robovm.xml
- ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java
- README.md
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/v3_X_Changes.java
- core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/v1_X_Changes.java
Shattered Pixel Dungeon is a cross-platform game, with iOS being one of its primary targets. The iOS build is made possible by a technology stack that allows the core Java-based game logic to run on Apple's mobile operating system. This is achieved primarily through the libGDX framework and the RoboVM ahead-of-time (AOT) compiler.
The iOS-specific module (/ios) contains the necessary launcher, platform-specific support code, and build configurations to package the shared core game module into a native iOS application. This document details the key components and configurations involved in this process. For information on other platforms, see Compiling for Android or Compiling for desktop platforms.
Sources: README.md, ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java
Build Technology Stack
The iOS build relies on several key technologies to translate the Java codebase into a native iOS application.
- libGDX: A cross-platform game development framework that provides a unified API for graphics, audio, and input across different platforms, including iOS.
- RoboVM: An ahead-of-time (AOT) compiler that translates Java bytecode into native ARM or x86 machine code for iOS. This is the core technology that enables the Java code to run on iOS devices.
- Gradle: The build automation tool used to manage dependencies and orchestrate the build process, including invoking the RoboVM compiler.
The following diagram illustrates the high-level compilation flow for the iOS target.
This diagram shows how the shared Java code is processed by RoboVM to create a native iOS application package.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java, ios/robovm.xml
Application Lifecycle and Configuration
The entry point and initial configuration for the iOS application are managed within the ios module.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java
Entry Point (IOSLauncher.java)
The com.shatteredpixel.shatteredpixeldungeon.ios.IOSLauncher class serves as the main entry point for the iOS application. It extends IOSApplication.Delegate from the libGDX backend.
The application launch sequence is as follows:
This diagram shows the sequence of calls from the static main method to the creation of the ShatteredPixelDungeon game instance.
Key responsibilities of IOSLauncher:
- Main Method: The static
mainmethod initiates theUIApplicationwithIOSLauncheras the delegate class. - Exception Handling: Registers a default Java uncaught exception handler to ensure the app crashes on MobiVM runtime errors, aiding in debugging.
- Version-Stamping: Retrieves the app version (
CFBundleVersionString) and build number (CFBundleVersion) from theInfo.plistfile. - Preferences: Initializes
SPDSettingsby loading the preferences.plistfile from the device'sLibrarydirectory. - Application Creation: The
createApplication()method instantiates and configures theIOSApplication. - Orientation Changes: The
didChangStatusBarOrientationmethod handles device rotation by callingShatteredPixelDungeon.seamlessResetScene()to redraw the UI correctly.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java:46-203
Core Application Configuration
Within createApplication(), an IOSApplicationConfiguration object is created and customized before being passed to the IOSApplication constructor.
| Property | Value/Description | Purpose |
|---|---|---|
colorFormat | MGLDrawableColorFormat.RGBA8888 | Sets the color format for the Metal/Angle rendering surface. |
depthFormat | MGLDrawableDepthFormat.None | Disables the depth buffer, as it's not needed for this 2D game. |
hdpiMode | HdpiMode.Pixels | Ensures rendering is based on physical pixels for crisp graphics. |
hideHomeIndicator | true | Hides the home bar indicator at the bottom of the screen on modern iPhones. |
overrideRingerSwitch | SPDSettings.ignoreSilentMode() | Allows the game to play audio even if the device's ringer switch is set to silent, based on user settings. |
useHaptics | true | Enables haptic feedback. |
useAccelerometer | false | Disables the accelerometer as it is not used. |
useCompass | false | Disables the compass as it is not used. |
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java:112-120
Device Support
To ensure correct display metrics on newer devices not yet recognized by the libGDX library, IOSLauncher explicitly adds them using config.addIosDevice(). This provides the device's hardware identifier and screen pixel density (PPI). This list is extensive and includes iPhones from the iPhone 12 up to speculative iPhone 18 models, as well as numerous iPad models. Simulator devices are also overridden for better testing.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSLauncher.java:122-189
RoboVM Build Definition (robovm.xml)
The robovm.xml file is the primary configuration file for the RoboVM compiler, defining how the native iOS application is built.
| Element | Description |
|---|---|
<executableName> | Defines the name of the output binary. |
<mainClass> | Specifies the main Java class to execute (IOSLauncher). |
<os> | Sets the target operating system to ios. |
<arch> | Sets the target architecture to arm64. |
<resources> | Defines asset directories to be included in the app bundle. |
<forceLinkClasses> | Lists classes that must be included by the compiler, preventing them from being stripped out during optimization. This is crucial for classes used via reflection. |
<frameworks> | Lists the native iOS frameworks the application depends on. |
Sources: ios/robovm.xml
Resource Management
The build process includes assets from multiple source directories.
../core/src/main/assets: Includes all shared game assets from thecoremodule, but excludes.oggaudio files, as iOS typically uses other formats like.mp3or.m4a.../desktop/src/main/assets: Includes assets from thedesktopmodule.assets: Includes iOS-specific assets.
<!-- Source: ios/robovm.xml:7-22 -->
<resources>
<resource>
<directory>../core/src/main/assets</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.ogg</exclude>
</excludes>
<skipPngCrush>true</skipPngCrush>
</resource>
<resource>
<directory>../desktop/src/main/assets</directory>
<includes>
<include>**</include>
</includes>
<skipPngCrush>true</skipPngCrush>
</resource>
<resource>
<directory>assets</directory>
</resource>
</resources>
Frameworks and Class Linking
The application links against several standard iOS frameworks. The <forceLinkClasses> section is critical for ensuring that RoboVM does not strip away classes that are accessed dynamically at runtime (e.g., via reflection), which is a common practice in libraries like libGDX and for certain Java functionalities like cryptography providers.
Linked Frameworks:
UIKit, OpenGLES, QuartzCore, CoreGraphics, OpenAL, AudioToolbox, AVFoundation, GameController.
Forced-Linked Class Patterns:
com.badlogic.gdx.scenes.scene2d.ui.*, com.badlogic.gdx.controllers.IosControllerManager, com.android.okhttp.**, com.android.org.conscrypt.**, among others.
Sources: ios/robovm.xml:24-53
Platform-Specific Implementation (IOSPlatformSupport.java)
The com.shatteredpixel.shatteredpixeldungeon.ios.IOSPlatformSupport class provides concrete implementations for platform-agnostic interfaces defined in the core module, tailored specifically for iOS.
Display and UI Handling
A significant responsibility of this class is managing the variety of iOS device screen shapes, including notches and the Dynamic Island.
getDisplayCutout(): This method returns aRectFrepresenting the physical area of a display cutout. It contains specific logic to estimate the size and position of the Dynamic Island on certain iPhone models by checking the safe area inset value (topInset / Gdx.graphics.getBackBufferScale() >= 51).getSafeInsets(): This method provides the safe area insets for the UI, ensuring that interactive elements are not obscured by cutouts or the home indicator. It intelligently adjusts the raw inset values provided by the system to be less conservative and handles landscape orientations.- Rendering Backend: The iOS build was updated to use Metal instead of OpenGL as its rendering backend for better performance and future-proofing on Apple platforms.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java:44-98, core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/changelist/v3_X_Changes.java:540-541
Hardware Features
The class provides wrappers for iOS-specific hardware interactions.
- Vibration: The
vibrate()method implements a tiered approach. It prioritizes controller vibration if available, falls back to the device's haptic engine, and finally uses a system sound (AudioServices.playSystemSound(1520)) for older devices with 3D Touch but no dedicated haptic engine. - Silent Switch:
setHonorSilentSwitch()allows the game to respect or ignore the physical ringer switch on the device.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java:111-137
Font Rendering
To support multiple languages with different character sets, IOSPlatformSupport implements a dual-font system.
- A primary pixel font (
pixel_font.ttf) is used for Latin and Cyrillic-based languages. - A fallback font (
droid_sans.ttf) is used for Asian languages (Hangul, CJK, Hiragana, Katakana).
The getGeneratorForString method uses a regular expression to detect the presence of Asian characters in a given string and selects the appropriate font generator. This ensures that all text is rendered correctly while maintaining the game's pixelated aesthetic where possible.
Sources: ios/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ios/IOSPlatformSupport.java:141-187
Conclusion
Compiling Shattered Pixel Dungeon for iOS is a sophisticated process that hinges on the power of RoboVM to convert Java bytecode into a native application. The ios module is meticulously configured to handle the application's lifecycle, define build parameters, and provide platform-specific implementations for UI, hardware, and font rendering. Key files like IOSLauncher.java, robovm.xml, and IOSPlatformSupport.java work in concert to bridge the gap between the cross-platform core game logic and the native iOS environment, ensuring a feature-complete and performant experience for players on Apple devices.