Together with the engine we include a tool to help with building and packaging your programs for various platforms (standalone, mobile, consoles…).
Just download Castle Game Engine and the build tool is included inside.
In most cases, you will use Castle Game Engine Editor (
bin/castle-editor executable) that automatically uses build tool described here, under the hood. Alternatively, you can execute the build tool directly, on the command-line, using
Open a terminal (command-line), and enter the directory containing
CastleEngineManifest.xml file. This is the main project directory.
Run this command to compile the project (for the current operating system and processor):
Run this to compile and also package (again, for the current operating system and processor):
By default we compile in release mode. Use option
--mode=debug to compile a debug version (slower, but more friendly for various debuggers).
That’s it, you can now use our "build tool" to easily compile and package your games for various platforms:) Read on to learn about more useful commands of the build tool.
CastleEngineManifest.xml file in your project’s directory. See the CastleEngineManifest.xml examples page for samples and documentation. You can create an trivial starting
CastleEngineManifest.xml file by executing
castle-engine create-manifest. The manifest file describes your project’s name, source code, what files to include in the package and such.
Then you call
castle-engine from within your project’s directory (or any subdirectory, we automatically look for
CastleEngineManifest.xml in parent directories) to quickly compile, package and clean the project. See the description of command-line parameters to
castle-engine below. The tool is integrated with our engine, so it can automatically compile the code correctly, and package it following our usual conventions. The data for the game is automatically packaged. On Windows the required DLL files are automatically included (see also the description of <dependencies> in CastleEngineManifest.xml). On Android the required Java wrappers and libraries are automatically used.
Create CastleEngineManifest.xml file if it does not exist yet, guessing the project name based on directory name. You can use this
CastleEngineManifest.xml as a starting point.
Compile the project, with the syntax options and optimizations suggested for programs using our engine.
By default we compile for your current OS (operating system) and processor, so if you’re on 32-bit Windows -> you will compile a 32-bit Windows binary, if you’re on 64-bit Linux -> you will compile a 64-bit Linux binary and so on. You can use
--cpu options to cross-compile. Underneath, proper cross-compilation options will be passed to FPC.
castle-engine compile --cpu=x86_64 to compile a 64-bit version for the current operating system.
castle-engine compile --os=linux --cpu=x86_64 to compile a 64-bit version for Linux.
Windows is a little weird (due to historical conventions beyond FPC), and you have to use
castle-engine compile --os=win64 --cpu=x86_64 (thus, you request 64-bit "twice" in the command-line) to get a 64-bit version on Windows. Use
castle-engine compile --os=win32 --cpu=i386 to get a 32-bit executable for Windows.
--cpu options, you can also use
--target. A target is a collection of OS and CPU combinations that typically are distributed together. Right now, these targets are available:
custom (the default target), which means that we look at
--cpu options, and compile for this single OS/CPU.
android, which consists of 2 combinations of OS/CPU: Android on ARM (32-bit devices) and Android on Aarch64 (64-bit devices, only if your FPC is capable of compiling to Android/Aarch64 — FPC 3.3.1 is necessary).
ios. By default this consists of 2 combinations of OS/CPU, to include 32-bit and 64-bit iOS devices. Add the
--ios-simulator option to include 2 more combinations of OS/CPU to include also support for the iOS simulator. See iOS to learn more.
nintendo-switch, which builds an application for Nintendo Switch.
--mode=valgrind for a specific compilation mode. By default, it is "release". The "valgrind" mode is for profiling (speed, memory usage) using the excellent Valgrind tool.
In all cases, your programs will be compiled with the same options as engine units. We turn the same optimizations as for the engine core. In FPC it which means that we use ObjFpc syntax mode by default.
By default we auto-detect the compiler: using the compiler indicated in CastleEngineManifest.xml by
compiler="xxx" option, otherwise using FPC or Delphi (whichever first is found). You can use
--compiler command-line option to override the compiler choice, like
You can customize what options we pass to the compiler by:
Adding options to the
<custom_options> in CastleEngineManifest.xml. This is the good place to define options specific to your project (that should be used by all developers working with this project).
--compiler-option command-line option. For example,
--compiler-option=-gl --compiler-option=-gh. This is the good place to pass options specific to your development system or preferences, that should not be shared by all developers working on this project.
--plugin to compile a web browser plugin.
--output DIR to place the output files (executable, temporary
castle-engine-output subdirectory) in a specified directory. When not given, they are placed in the current project directory. This option is also available for other commands, like
Compiling on Windows will also copy the necessary
.dll files from the engine to be alongside your
.exe file. This allows to run the executable afterwards, in any way.
|This is not the only possible way to compile programs using our engine (for example, you can also compile and run using Lazarus, which is OK for desktop applications).|
Create an installable package with your application.
--target options to specify target operating system/processor. By default, we package for current standalone platform.
--compiler to override compiler for building, just as for
What exactly is produced by this command depends on the target platform and the
--package-format option used.
--package-format=default (used also when no
--package-format=... was specified):
For the standalone platforms, we package to a simple
tar.gz archive containing the executable, libraries and data. For Windows, we create
For the Android (when
--os=android --cpu=arm/aarch64), we create a complete apk with your application, ready to be installed and uploaded to Google Play!
For iOS (when
--target=ios), we create an Xcode project, that you can run and publish using Xcode.
--package-format=zip: Pack files into a zip file.
--package-format=tar.gz: Pack files into a tar.gz file.
--package-format=deb: Pack files into a Debian Package (deb).
--package-format=directory: Put files into a directory. This is useful if you plan to further process this directory, e.g. pack it with your own scripts.
--package-format=android-apk: Create an APK file. This is right now the equivalent to
--package-format=default and it is just the default behavior when target/OS is Android. It’s the standard way to build applications for Android. It also allows you to manually install the app on your Android device.
--package-format=android-app-bundle: Create an Android App Bundle (AAB). This is a new format recommended for submitting a release to Google Play Store. Android App Bundle may contain multiple precompiled versions of the app and assets, and Google Play Store internally generates an installable APK for every specific user depending on user device configuration (such as Android version or screen resolution). AAB format is strictly required to upload a project larger than 100Mb to Play Store.
--package-format=ios-xcode-project: Create the Xcode project. This is the default package method for iOS. You can open the resulting project in Xcode and build/deploy the application for iOS device or AppStore.
--package-format=ios-archive-ad-hoc: Archive and export using the ad-hoc method, which results in an IPA file of the application. To install on designated devices, upload to TestFairy etc.
--package-format=ios-archive-development: Archive and export using the development method. See the Xcode documentation (and try these options from Xcode interactively) for details.
--package-format=ios-archive-app-store: Archive and export for the TestFlight and the AppStore. See the Xcode documentation (and try these options from Xcode interactively) for details. Note that this does not upload to the TestFlight / AppStore (although we’d like to extend this someday to do it).
--package-format=mac-app-bundle-zip: Application bundle on macOS, packed into
zip. Default format for macOS.
--package-format=mac-app-bundle: Application bundle on macOS, not packed (so it is just a directory like
Nintendo Switch format:
When target is
iOS you can also use
--ios-simulator option to include iOS simulator support (see iOS).
By default output filename contains a version number. Sometimes this is not comfortable, use
--package-name-no-version to avoid it.
You can use
--mode=xxx option when packaging, just like when compiling. Use
--mode=release for a specific compilation mode. By default, it is "release". You can use
--mode=debug to package a debug release, which may be useful to distribute to users interested in beta-testing.
In some cases, the
--mode also affects the packaging wrapper. For example, on Android, a debug apk is generated. Also, only a debug apk may use a debug signing key (our build tool will automatically fallback from release apk to debug apk if you did not provide a release key in AndroidSigningProperties.txt).
To make sure that we recompile everything in the current mode (e.g. a release mode), this does
clean, and then
compile, and only then actually packages the result. You can change this behavior:
--fast to make the compilation step faster — we will recompile only what changed.
By default, without
package command first cleans all the compilation results, and then builds from scratch (engine and your code). This is safest (makes sure that everything is rebuild with latest compilation options) but slow, and usually not necessary (Pascal compilers are generally excellent at detecting what needs to be recompiled, FPC even handles changes to include files reliably). For the final release builds, we advise to not use this option.
--fast is suitable during the development, if you call the
package command often.
--assume-compiled to say that you already compiled the application in proper mode before calling the
package action. We will not do
compile in this case at all. This is obviously much faster, but you need to make sure to call
compile beforehand yourself.
Another (independent) way to make packaging faster is to use
--update-only-code. For now this is meaningful only for iOS. If specified, it means that the build tool can assume that only the Pascal code have changed (so you did not change e.g.
data/ directory, or project settings in
CastleEngineManifest.xml). We can then recompile the code (and update the relevant file in the project, like
libxxx.a) without changing anything else. This means that the
package command will finish much faster. It will also be more comfortable — e.g. no need to close and reopen the project in Xcode, Visual Studio or whatever other software is used to handle the final project.
Install the application created by previous "package" call.
This is useful when OS is "android", it installs and runs the apk package created by previous "package" call for Android. Useful for quick testing of your app on a device connected through USB. Note: it’s best to first test do you see your device using SDK tools, for example execute
adb devices and see is your device listed.
Use --plugin to install a web browser plugin. We install the compiled plugin such that it should be visible by all web browsers supporting NPAPI. (On Windows, this means installing proper registry entries. On Unix, it means copying the library to special directory.)
Pass also additional options reflecting the OS/architecture, mode and package name format. In general, pass to
install exactly the same values as you used for
package, so that we know which package to install:
--target to specify target operating system/processor (by default, we install for the current standalone platform).
--mode=xxx to specify debug or release package.
--package-name-no-version to determine the package name.
Run the application.
The log of the application (whatever you write using WritelnLog, WritelnWarning) will be the output of this command. On some platforms, you can also use regular
Writeln, but to be cross-platform better stick to CGE
WritelnWarning, they will work in all cases (Android, iOS, Windows GUI applications etc.).
As usual, use
--target options to specify target operating system/processor. By default, we run the normal (exe) application on the current platform.
On some platforms, it requires packaging and installing the application first. This applies to Android: we install and run on a device connected through USB. Use the "package" and "install" commands before this. For example, on Android you can package and install and run your application like this:
castle-engine package --target=android castle-engine install --target=android castle-engine run --target=android
On other platforms (e.g. standalone Windows, Linux, macOS…), this simply runs the last compiled application. So just "compile" the application first, like this:
castle-engine compile castle-engine run
You can specify parameters to pass to the application after the special "--" parameter. For example,
castle-engine run -- --fullscreen
This will run your application with command-line parameters
--fullscreen. In your application, you can read command-line parameters with the help of
CastleParameters unit. (The
--fullscreen option, used as an example here, is actually handled automatically, if only your program calls
Application.ParseStandardParameters.) The command-line parameters are not supported in non-desktop environments (e.g. there’s no way to pass them to an Android or iOS application).
On Unix desktop platforms (like Linux, FreeBSD..), we can run your game through a "wrapper script". This is useful e.g. to set
LD_LIBRARY_PATH before running the application. The build tool simply looks for
<application_name>_run.sh script in the project directory, and executes it if found (instead of executing the compiled binary directly).
Package source code, which means just to package whole project directory (cleaned up first).
It creates xxx-VERSION-src.tar.gz archive, with VERSION obtained following the <version> element in the CastleEngineManifest.xml.
It accepts the
--package-name-no-version options, just like the
package command. By default we just pack to zip (that is,
--package-format=zip is equivalent to
Clean compilation and packaging temporary stuff. This does not remove final packaging files.
Compile the Object Pascal file (unit/program/library) given as a parameter. This does not search for the Castle Game Engine project’s manifest in the
CastleEngineManifest.xml file. It merely calls "fpc" with proper command-line options for units/programs/libraries using our engine.
Use this instead of "compile" only if there’s some good reason you don’t want to use
CastleEngineManifest.xml to manage your project.
Create GPU-compressed versions of textures, and downscaled textures, for the textures mentioned in
<auto_generated_textures> inside the file
data/material_properties.xml. Such GPU-compressed and downscaled textures can then be automatically used in your application. See instructions how to use it and example
If the output textures are already created, they are updated only if the output timestamp is earlier than input. This usually allows to automatically do only the necessary work, similar to how Makefiles operate. To force recreating all textures, just call
castle-engine auto-generate-clean --all first.
The information about created textures is stored in
data/CastleAutoGenerated.xml file. If you use version control, you should either:
data/CastleAutoGenerated.xml file and ignore all
or commit both the
data/CastleAutoGenerated.xml file and all
auto_generated subdirectories. They should contain only the output created by
castle-engine auto-generate-textures target. In the future, it is possible that more things will be placed there (for example, modern GPUs allow mesh data compression).
Run without any arguments to only clean the unused files in
auto_generated subdirectories. This may be useful after moving/renaming some subdirectories, as the
castle-engine auto-generate-textures command never removes previous files, it only adds new files. Having unused files is not a problem — but they waste disk space, and can be safely removed.
--all argument to clean all files from the
auto_generated subdirectories. This is useful e.g. if you want to force regenerating them all by next
castle-engine auto-generate-textures command.
standalone (desktop) Pascal program code in the file
xxx_standalone.dpr. It uses the
game_units defined in the CastleEngineManifest.xml to determine the correct
uses clause of the program file.
You can use this program code to compile the project using any tool you want, not necessarily our build tool. E.g. maybe you like using Lazarus or
fpmake. You can use it as a
standalone_source in the
CastleEngineManifest.xml to make sure build tool also uses it (in case you will modify it), although build tool can also generate such source code automatically.
standalone_source is specified in CastleEngineManifest.xml, then we overwrite it, regardless if it is called
xxx_standalone.dpr or not.
Lazarus project information in the file
xxx_standalone.dpr, this allows you to open this project in Lazarus to edit, compile, debug and run it from Lazarus. You can also compile it using
standalone_source is specified in CastleEngineManifest.xml, then we overwrite the respective LPI file, regardless if it is called
xxx_standalone.lpi or not.
Delphi project information in the file
xxx_standalone.dpr, this allows you to open this project in Delphi to edit, compile, debug and run it from Delphi.
standalone_source is specified in CastleEngineManifest.xml, then we overwrite the respective DPROJ file, regardless if it is called
xxx_standalone.dproj or not.
CastleAutoGenerated unit in
castleautogenerated.pas unit. It is used by the program file created above (
xxx_standalone.dpr) and also by all program or library files created automatically by the build tool to build project on all platforms. It defines some project properties, to parse standard command-line properties, to initialize logging.
Run the Castle Game Engine Editor within this project. The executed editor will include possible project-specific components.
In simple cases, this is just a shortcut for running
castle-editor and opening the current project, which can also be done by calling
If your CastleEngineManifest.xml contains
editor_units attribute, then this automatically builds and runs a custom CGE editor (a fork of the CGE editor, for use in your project), with your custom components included.
The custom editor is compiled and present inside
castle-engine-output/editor/, so it is tied to your project, cleared with
castle-engine clean and so on. You should always execute it using
castle-engine editor command. Or using the "Project -> Restart Editor (may rebuild editor with custom controls)" menu from the CGE editor (vanilla build or custom build, doesn’t matter, the "Restart editor" will always build custom editor if project uses
Precompile CGE units, to speed up future compilation of all projects (with the current compiler and engine version).
By default we prepare cache for compilation on the current platform. The options
--target switch the platform, as usual. E.g. you can use
castle-engine cache --target android to speedup future Android compilations.
The precompiled units are stored in user files, and will be reused by all subsequent compilations of any CGE project for matching platform. The precompiled units from cache are simply copied over (as a starting point) to your project’s compilation directory. The precompiled units do not overwrite the existing ones, moreover the compiler will overwrite them (in the project) if e.g. you have changed CGE since making the cache. So the cache tries hard not to conflict with what you’re doing.
The cache is always prepared for all possible modes:
valgrind. This command ignores the
--compiler option is taken into account, but for now for Delphi we merely answer with an error. The code to use cache is now only for FPC. In the future we plan to extend this to Delphi.
--ios-simulator option is honored, it changes what
castle-engine cache --target=iOS does (for what platforms does it prepare cache).
Remove all the cached files created by
cache (for all platforms).
This reclaims the disk space used by cache and it implies that future compilations will be done without using the cache.