<?xml version="1.0" encoding="utf-8"?> <project name="my-cool-game" standalone_source="my_cool_game.lpr"> </project>
CastleEngineManifest.xml file is used by the Build Tool to know how to build and package your games (or any other projects using the Castle Game Engine). It should be present at the top-level directory of your project.
When you create a new project, you can generate a new manifest file by running
castle-engine create-manifest. Or just manually create a new
CastleEngineManifest.xml file, using the samples on this page. It’s a trivial XML file, just edit it using your favorite text editor.
This is the simplest example manifest:
<?xml version="1.0" encoding="utf-8"?> <project name="my-cool-game" standalone_source="my_cool_game.lpr"> </project>
standalone_source value must point to an existing source file to compile the project for desktop platforms (Windows, Linux, MacOSX…). An example is below. Alternatively, you can specify a list of
game_units (see the documentation of game_units attribute), in which case the
standalone_source is not necessary (the build tool can internally auto-generate a suitable program file for compilation).
When compiling, the resulting executable file name is derived from the project
name (in this case:
my-cool-game). So it’s
my-cool-game.exe on Windows and just
my-cool-game on Unix.
The project name is also used for other things:
When packaging the project (by the
castle-engine package), the archive names are derived from it. For example, packaging the project for Linux (64-bit architecture, x86_64) will result in
In some cases we assume that the
ApplicationName function (from the standard FPC
SysUtils unit) returns the same project name at runtime. It’s never strictly necessary, but it is helpful e.g. for Android logging (where we need to filter the logs by project name). Therefore, it’s advised to assign in your source code the
OnGetApplicationName callback, and make sure it returns the same thing as project name. See the example below, and the FPC documentation about ApplicationName and OnGetApplicationName .
To be on the safe side, the build tool requires that the project name is limited to ASCII letters, numbers, underscores and hyphens. No spaces, no dots, no other special characters are allowed.
For example, place these contents in the
uses SysUtils, CastleWindow; function MyGetApplicationName: string; begin Result := 'my-cool-game'; end; var Window: TCastleWindow; begin OnGetApplicationName := @MyGetApplicationName; Window := TCastleWindow.Create(Application); Window.OpenAndRun; end.
Congratulations, you have created a game! Now you can compile the project by running this on the command-line:
Then you can run it by simply executing the file
my-cool-game.exe on Windows or
./my-cool-game on Unix. Or you can run this:
Sooner or later, you may want to add more information about your project. It is used when packaging your project in various formats. Note that everything has sensible default values anyway.
Example information that can be expressed in the manifest file:
icon (various alternative formats possible),
version number (on some platforms, the version numbers are not only displayed; they are also used to signal possible upgrades to user; in particular, on Android platform, the version numeric "code" should always be increasing),
screen orientation (for mobile devices; by default, all orientations are OK, and they can change at runtime),
Below is a sample project manifest with more information:
<?xml version="1.0" encoding="utf-8"?> <project name="my-cool-game" standalone_source="my_cool_game_standalone.lpr" game_units="MyGameMainUnit" caption="My Cool Game" author="My Cool Game Company" qualified_name="org.mycoolcompany.my.cool.game" screen_orientation="landscape"> <version value="1.0" code="1" /> <icons> <icon path="icon.png" /> </icons> <android> <services> <service name="vibrate" /> </services> </android> </project>
To create a cross-platform game (that easily compiles to standalone, Android, iOS and other targets) you should use the
game_units attribute in your manifest file. Like this:
<?xml version="1.0" encoding="utf-8"?> <project name="my-cool-game" game_units="MainCoolGameUnit"> </project>
The above example is a complete
CastleEngineManifest.xml file, that allows to compile your game to any platform.
You can specify multiple unit names, separated by commas, like
game_units="OneUnit, TheOtherUnit". All the listed units will be automatically compiled into the game. But typically it is enough to specify a single main unit, and this unit can pull the other units by using them by a
uses SomeOtherUnit; declaration in the Pascal source code.
The main program (or library) file, suitable for each platform, will be created automatically before every compilation, if you don’t set appropriate
xxx_source attribute for your platform. So if you don’t set
plugin_source, but request compilation to a given platform, we will automatically generate a program (or library) file as necessary.
This is an important attribute to use when making a game portable to both standalone and mobile. It allows you to avoid writing any Android or iOS specific code. And you don’t need to maintain the main program / library files. (These are the files typically with
.lpr extension for FPC / Lazarus or
.dpr for Delphi.)
NOTE: In order to use Lazarus or Delphi to develop and debug your application, it is often useful anyway to create the main program file for the standalone platform. You can even create and maintain it automatically using
castle-engine generate-program command, see the documentation.
In this case you should specify the generated
my_cool_game.lpr file in the
standalone_source attribute. The other platforms (Android, iOS) can still use an auto-generated library file.
The standalone program file can be customized to initialize a specific window size or fullscreen mode, to parse command-line options and so on. These are features not available on mobile devices.
NOTE: make sure that the compiler can find the units mentioned in game_units (just like every other unit necessary). For example, you can add these lines to add
code/ subdirectory to your unit search path:
<compiler_options> <search_paths> <path value="code/" /> </search_paths> </compiler_options>
Your game can define custom component classes useful with the Castle Game Engine Editor. These component classes heave to descend from
TCastleTransform, and must be registered in the
initialization section of some unit by calling
RegisterSerializableComponent(TMyButton, 'My Button');.
You should list the units that contain these components in the
editor_units attribute, which has a syntax similar to the
game_units attribute: a number of units separated by commas.
When you call the build tool with
castle-engine editor command, it will automatically build and run a special version of the CGE editor with your
editor_units included. This way you get special editor version that includes your project-specific components.
This section documents the complete manifest file, with every possible attribute documented.
<?xml version="1.0" encoding="utf-8"?> <project name="my_game" caption="My Game Title" author="My Name" qualified_name="org.domain.my.my_game" executable_name="my_game" standalone_source="code/my_game.lpr" android_source="code/my_game_android.lpr" ios_source="code/my_game_ios.lpr" plugin_source="code/my_game_plugin.lpr" game_units="MyMainGameUnit, MyOtherGameUnit" editor_units="MyVisualComponents" screen_orientation="any" fullscreen_immersive="true" lazarus_project="my_game.lpi" delphi_project="my_game.dproj" build_using_lazbuild="false" compiler="autodetect" mac_app_bundle="true" > ...
name: Required name of your game. It determines the names of various output files/packages of your game. It should not contain spaces or non-ASCII characters. It’s best to also specify it as OnGetApplicationName inside your code.
caption: User-visible game title. Optional (by default equal to
name). Here you can use spaces, any special characters and so on.
author: Author and/or company name. Optional. Used where suitable in the metadata information in the final package or binary.
qualified_name: Unique identifier of your game for some purposes (e.g. used by various Android stores, iOS AppStore, Windows manifest). It is optional (by default equal to
name limited to alphanumeric characters and a dot).
A convention is to derive this from the website address of your project. For example, for a game hosted on https://example.org/tetris , a sensible qualified name would be "org.example.tetris". But this is just a convention (no automatic mechanism will actually check is the portion of the name an existing domain name on the Internet), the only important fact is to make this string really unique.
executable_name: Binary name (without platform-specific extension, like
.exe on Windows). Optional, by default equal to just
standalone_source: Main file for standalone (desktop — Windows, Linux, MacOSX…) targets. Optional. You need to provide this, or the
game_units, to compile for standalone platforms.
plugin_source: Main file for a specified target. Optional. Using these attributes is discouraged: it’s much better to specify only
game_units, and let the engine auto-generate the appropriate main file for you. You need to understand a little the engine internals to create a valid
xxx_source for Android, iOS or web plugin.
screen_orientation: Desired screen orientation on devices that support it, e.g. on Android. Allowed values are
fullscreen_immersive `: Indicates whether you want to have the status bar and navigation buttons hidden on Android and iOS . Allowed values are `true (default),
game_units: List of game units. To be included in the auto-generated library or program of your application. See the section above for more information.
editor_units: List of the units that register custom components useful in CGE editor. See the section above for more information.
lazarus_project: The Lazarus project (
.lpi extension) file of this project. It will be used to open this project in Lazarus. It will also be used to compile it, if
build_using_lazbuild. By default this is calculated as
standalone_source with extension changed to
If this is
false (default) then we use plain FPC to compile, passing command-line parameters to find the CGE unis and other options listed in
true then we will compile using lazbuild through the LPI file defined by
lazarus_project. This is useful if your project uses Lazarus LCL, or other package distributed as Lazarus LPK file. Thanks to
lazbuild and LPI file, these packages will be automatically correctly used. On the other hand, some other features of the build tool do not work (instead we rely that you configured the project in Lazarus correctly):
We do not construct the FPC command-line anymore, so we ignore custom
We don’t pass location of CGE units to lazbuild (Lazarus projects should use
We don’t pass any compilation syntax options, but this usually doesn’t matter (because our
castle_xxx packages are compiled with proper options, and for your own projects — the Lazarus defaults are largely similar to CGE defaults, e.g. using ObjFpc mode with AnsiStrings).
We do not pass
--mode (Lazarus supports build modes, but not all projects define Debug/Release modes).
delphi_project points to the
xxx.dproj file of the project. By default this is calculated as
standalone_source with extension changed to
compiler changes the default compiler used to compile this project (note that command-line
--compiler=xxx option of the build tool can override it):
autodetect (default) - use FPC or Delphi, whichever first is found
mac_app_bundle: On macOS, should we run and package the project using the Apple App Bundle. By default this is
true and it should stay
true for GUI applications. For command-line applications, that don’t need an App Bundle, you can turn this
By default, we expect a subdirectory named
data inside the project directory. This is the only "special" directory name for Castle Game Engine projects, it will be specially packaged, and your application can read from it on any platform using URL like 'castle-data:/xxx.png'.
If you don’t have any data files in your project, you can say it explicitly to avoid some warnings from the build tool:
... <data exists="false" /> ...
... <version value="1.0.0" code="1" /> ...
<version> element declares program version. It is used when packaging for some formats (Android package, Windows executable information, iOS project). Attributes:
value: User-visible version name. Any string representing your version. We advise (but do not strictly require) to use the major.minor.release format for version numbers, with all components being simple integer numbers.
code: Optional (by default 1) version number. This must be an integer number >= 0, specifying the version as a simple number that always grows. This may be used by some platforms (like Android) to compare your applications versions to decide when to automatically upgrade.
Note that some platforms (notably Google Play) require that this version number starts from 1 (never 0).
On the other hand, on some platforms (like Nintendo Switch) this number sometimes must be 0.
We allow to override this number per-platform using
<override_version> elements mentioned below. So the global
<version.../> element is just the default version, which may be adjusted per-platform later.
... <icons> <icon path="icon.svg" /> <icon path="icon.png" /> <icon path="icon.ico" /> </icons> ...
You can provide an optional icon of your application, in various formats, by listing them inside
Each platform (or package format) will use the most suitable icon format and size. In particular:
For Windows application we use the
Android and iOS use any version readable by our engine (like
.jpg). We take care to use the best icon format in the best possible way, resizing it (with good quality algorithm) if necessary.
For Debian package, it’s recommended that you provide an icon version in the
.xpm format if you generate a Debian package. If an icon in
.xpm format is not available, Build Tool will try to convert a
.png icon into
.xpm format using Image Magick if it’s installed.
... <launch_images> <image path="launch-image-640x1136.png" /> <!-- Will be used on iPhone (Portrait) --> <image path="launch-image-1536x2048.png" /> <!-- Will be used on iPad (Portrait) --> <image path="launch-image-2048x1536.png" /> <!-- Will be used on iPad (Landscape) --> <storyboard path="launch-image.png" scale="1.0" background_color="000000" /> <!-- If set, the "storyboard" will be used on all devices since iOS 8, in all orientations --> </launch_images> ...
iOS shows a launch image when the application starts. Launch image is shown very early, before any CGE code can run and render anything. So it is displayed even before CGE loading image shows. The point of the launch image is to communicate to the user that the application is, well, launching.
To enable you to customize this, we will use the images defined as
There are 2 ways to customize it (and you can use both):
Provide a set of
<image> elements inside
<launch_images>. This works on all iOS devices.
This approach requires a couple of image sizes, with various aspect ratios, to cover all possibilities. We will scan the list of your
<launch_images> and choose the one with closest aspect ratio (width / height proportion), and use it (eventually resizing if needed). Only if you don’t define any
<launch_images>, we will use a default one. The suggested sizes, and their usage, is shown in the example above.
Note that there’s no iPhone Landscape launch image. For some reason, Apple doesn’t want it, and in landscape iPhone applications it will show the launch image in portrait orientation. To overcome this, you need to use the
<storyboard> described below.
Provide a single
<storyboard> element inside
<launch_images>. This works on iOS 8 and newer devices.
This approach requires you to provide just one launch image, that will be centered on the background of solid color.
path is the filename inside CGE project of the launch image. Must be PNG. It doesn’t need to be in
data subdirectory, it can be anywhere in the project (we will copy it anyway to proper Xcode project place). The image can use partial transparency (alpha channel), in which case
background_color will be visible underneath.
scale (default 1.0) determines the scale of the image. This is relative to the default set in CGE, which is to fit the image within 256x256 frame, and allow Xcode storyboard algorithm to scale it to adjust to various devices. The Xcode scaling algorithm does not match CGE UI scaling algorithm. In practice, you just have to experiment if you want a particular size.
background_color (default black, i.e.
000000) is the background color visible around and (if image uses transparency) under the image. This is in hexadecimal notation (as accepted by
HexToColor CGE function), e.g. use
FFFFFF for white, use
FF0000 for pure red). You can use pretty much any graphic application to pick a color and copy its value in hexadecimal form (6 or 8 hex digits).
Notes for testing: iOS really aggressively caches these launch images. If you change the
launch_image.png, but the application seems to stubbornly show the same old version (even after you’re sure you installed the updated version!), then you may need to use an ugly workaround: uinstall the app and reboot the iOS device before installing the app again. This will show new launch image. Note that doing only one of these things (only reboot, or only uninstall + reinstall) is not enough. See https://github.com/expo/expo/issues/1918 , https://github.com/facebook/react-native/issues/28389 .
... <android compile_sdk_version="33" min_sdk_version="21" target_sdk_version="33" > <services> <service name="google_play_services" /> <service name="google_play_games"> <parameter key="app_id" value="XXXX" /> </service> </services> </android> ...
<android> element provides various extra Android-specific information.
See Android services about services that are available inside the
compile_sdk_version: Optionally customize the Android SDK platform version used to compile the project. Note that this does not determine the minimum (or maximum) Android version your application supports.
min_sdk_version: Optionally customize the minimum supported Android version. It is a hard limit on where the application is installable, it also limits for which devices it appears in the Google Play store.
target_sdk_version: Optionally customize version of Android Java APIs you can use. Don’t worry about it, unless you use a specific Android service that requires increasing this version.
You generally should not customize the
xxx_sdk_version values, the defaults have been chosen to support widest possible range of Android devices and allow smooth publishing in stores like Google Play (that place some minimal requirements on these values for new and updated applications).
See the Android FAQ: What Android devices are supported? for what (and why) Android devices are supported by CGE.
If you really need to customize them, you should not customize them to be lower than the defaults. To see the default values execute build tool with command-line option
--help, it outputs something like:
... Defaults: android.compile_sdk_version = 33 android.min_sdk_version = 21 android.target_sdk_version = 33 ...
... <ios team="..." override_qualified_name="org.example.ios.qualified.name" uses_non_exempt_encryption="true|false" > <override_version value="1.0" code="1" /> <services> <service name="apple_game_center" /> </services> </ios> ...
<ios> element provides various extra iOS-specific information.
team is the identifier of your Apple team, used to sign the application. See how to find my Apple Developer Id. You can also set the Development Team using the XCode GUI before compiling the project.
override_qualified_name overrides the qualified name (by default taken from
qualified_name) for iOS. This allows you to use different qualified names for Android and iOS applications, in case you need it.
<override_version>, if specified, overrides the main
<version> only for iOS. This allows you to use different version name for iOS release than the other platforms (Android, desktop etc.), in case you need it. On iOS,
the version display value (
<override_version>) must match the version set in iTunes Connect website (where you release iOS applications).
the numeric version code (
<override_version>) isn’t used for now.
uses_non_exempt_encryption says whether your application uses an encryption that requires you to do some legal things when it is distributed from U.S. This is important for distributing your application internationally from the Apple AppStore, which qualifies as exporting your application from U.S..
By default this is
true, which is consistent with the default of the Apple iTunes Connect setting. If your application does not use encryption at all (unlikely, in modern times, as even reading stuff through HTTPS qualifies as "using encryption"), or if you fall under some exemptions (e.g. you only use HTTPS), then you can set this to
false. This way Apple iTunes Connect will no longer bother you about this.
Please read the Apple documentation on this issue. Setting this to
false is equivalent to using
<key>ITSAppUsesNonExemptEncryption</key><false/> in the
xxx-Info.plist file in your XCode project.
See the iOS Services for information what can you use within the
... <associate_document_types> <document_type caption="VRML Scene" name="vrml"> <extension>wrl</extension> <extension>wrz</extension> <mime>model/vrml</mime> </document_type> <document_type caption="ZIP Archive" name="zip" icon="zip_icon"> <extension>zip</extension> <mime>application/zip</mime> </document_type> ... </associate_document_types> ...
<associate_document_types> element associates some file types with your application. The intention is that when user tries to open a file of given type (e.g. by double-clicking it in the file manager), then this application should open, if it is installed. A document type can be identified by one or more file extensions, and it must correspond to one of more MIME types.
This feature is implemented now only for Android, iOS, macOS.
<document_type> element defines the document type to associate.
caption: short caption, nice to display for users (you can use spaces etc.), describing this document type.
name: internal unique identifier for this document type. It must be unique within this application. Use only alphanumeric characters.
icon: (optional) icon file shown for this document type. When none supplied, the application icon will be used.
<extension>EXT</extension>: multiple file extensions that match this document type can be given.
<mime>MIME</mime>: multiple MIME types that match this document type can be given.
TODO: We should expose
To handle the URL to be opened, you have to implement
... <dependencies> <!-- read font files like .ttf --> <dependency name="Freetype" /> <!-- read .gz files --> <dependency name="Zlib" /> <!-- read .png files --> <dependency name="Png" /> <!-- play sound --> <dependency name="Sound" /> <!-- read .ogg (OggVorbis) compressed audio files --> <dependency name="OggVorbis" /> <!-- ability to download using https (not only http) --> <dependency name="Https" /> </dependencies> ...
<dependencies> element allows to explicitly declare dependencies on various libraries. These dependencies are applied on all platforms. On some platforms (for now: Windows, Android, iOS) the necessary libraries are automatically bundled with your binary when packaging.
Note that it’s often not necessary to specify these dependencies. The build tool automatically adds the dependencies when it detects a particular file format in your game
data. For example, if you have a file
music.ogg, we will automatically add the
An example usage:
... <package> <include path="documentation/*" recursive="True" /> <include path="README.txt" /> <include path="COPYING.GPL2.txt" /> <exclude path="*.xcf" /> <exclude path="data/internal/*" /> </package> ...
<package> element allows to fine-tune what files to include in the package. Package is created using the
castle-engine package command of the build tool.
By default, the build tool includes the
data/ subdirectory, the executable file and (on Windows) necessary DLLs. And it excludes some files known to be useful only for development, like
*~ (backup files from various applications). To be precise, the defaults are like this:
... <package> <include path="my_executable[.exe]" executable_permission="True" /> <include path="some_necessary_library.dll" /> <include path="data/*" recursive="True" /> <exclude path="*.xcf" /> <exclude path="*.blend*" /> <exclude path="*~" /> <exclude path="*/.DS_Store" /> <exclude path="*/thumbs.db" /> </package> ...
<package> element allows to list additional files/directories to include or exclude.
The important fact to understand how the inclusion/exclusion masks work is that the paths (specified in the
path attribute) are matched against the relative path (like
data/my_subdirectory/my_image.png) of every existing file in the project.
<include>: Add given files to the package. The
path is actually split (by last
/) into a subdirectory (relative to the project directory) and the mask within it (with wildcards * and ?). We include the files matching the mask within the given subdirectory, possibly recursive (if
<include path="gfx/textures/.psd" recursive="True" /> adds files matching
.psd that are found inside the subdirectory
gfx/textures/ (or any of it’s subdirectories).
You can request to set Unix executable bit (like
chmod +x ...) on the packaged file using
<include ... executable_permission="true" /> (default
false). The executable bit will be set, or unset, regardless of the executable bit of the original file.
<exclude>: Exclude files whose whole path (relative to project directory) matches given mask. You can use wildcards * and ?, where * matches any number of any characters, including slash (directory separator).
<exclude path="*.xcf" /> to exclude all GIMP xcf files.
<exclude path="data/internal/*" /> to exclude all files inside data/internal/ subdirectory.
<exclude path="data/internal/*.xcf" /> to exclude all GIMP files inside data/internal/ subdirectory.
<exclude path=".gitignore" /> to exclude file named
.gitignore but only at the project top-level directory.
<exclude path="*/.gitignore" /> to exclude file named
.gitignore at any place within the project, not only at the project top-level directory.
<exclude path=".svn/*" /> to exclude
.svn subdirectory but only at the project top-level directory.
<exclude path="/.svn/" /> to exclude
.svn subdirectory at any place within the project, not only at the project top-level directory.
The order of including and excluding:
first we include all included files,
then we remove excluded stuff.
The inclusion and exclusion compare paths of files. The directories themselves are not considered for inclusion or exclusion. Empty directories (with no included files) are simply not packed.
... <compiler_options detect_memory_leaks="true"> <search_paths> <path value="code/subdirectory/"/> <path value="code/another_subdirectory/"/> </search_paths> <defines> <define>MY_CUSTOM_SYMBOL</define> </defines> <custom_options> <option>-Mdelphi</option> </custom_options> <library_paths> <path value="static_libraries/"/> <library_paths> </compiler_options> ...
<compiler_options> element contains optional configuration for the compiler (FPC or Delphi):
<search_paths> define additional locations for the source code (units and include files). These are used to search for units and include files.
These should be relative paths, like
../../some-shared-code (it is OK to point to parent directories).
Note that the main project directory (the one where
CastleEngineManifest.xml is located) is always searched, regardless of the
<defines> list the symbols defined during the compilation. These are symbols you can check in Pascal code using e.g.
It is possible to also define symbols using custom option like
<custom_options> are custom compiler options, passed directly to the compiler (FPC or Delphi DCC).
-Mdelphi means that FPC will compile the code in Delphi-compatibility mode (this only changes some syntax, e.g.
@ not necessary when assigning a method to an event). The default FPC mode is "ObjFpc", which is not perfectly compatible with Delphi, but has some advantages over Delphi.
Note that custom option may also be
@my-custom-config.cfg in which case FPC reads
my-custom-config.cfg file, and you can put more options inside (using features like
#IFDEF MSWINDOWS for platform-specific options).
The custom compilation options specified here are also placed in auto-generated Lazarus lpi and lpk files. This is used by
castle-engine generate-program and
castle-engine editor commands of the Build Tool. The point is that your source code is always compiled with these compilation options.
<compiler_options> supported only by FPC (for now):
<library_paths> define paths where the linked may found
xxx.o files. This is typically used to statically link with Pascal units code compiled from other languages. It corresponds to the FPC
-Fl command-line option.
detect_memory_leaks attribute activates memory leak detection using HeapTrc.
... <debian control_section="games" menu_section="Games/Adventure" /> <free_desktop categories="Game;RolePlaying;" comment="Short description of the game." /> ...
You can generate a Debian package of your application using:
Castle Game Engine Editor menu option Run → Package Format → Debian Package (DEB) and then Run → Package.
Or using command-line Build Tool like
castle-engine package --package-format=deb.
Creation of a Debian package uses additional information in the manifest documented below.
Debian-specific information inside the
control_section (default value:
games): section of the package for Debian (in Debian’s
See Debian policy: Sections for a list of possible values. These sections are visible e.g. in Synaptic.
Games): section in a Debian-specific menu system.
Free Destop information inside the
<free_desktop> element. These values determine the
xxx.desktop file contents, that describes the application to most Unix graphic environments, like GNOME, KDE, MATE etc. They follow various FreeDestop specifications, and may be used by other packaging methods (not just Debian) in the future.
Game): category of this application (determines where is it visible on various graphic environments menus).
See FreeDesktop Menu Specification: Registered Categories for allowed values.
comment: Short human-readable description of the application. This is used in
xxx.desktop file, and is used as the Debian package description too.
Following Desktop Entry Specification, this is the tooltip for the application. The value should not be redundant with the application name.
End of the manifest file.