For build just run from repository root one of the following scripts:
Todo: finalize API and declare here
Validation scenarios can be run one at a time or batched in a single command:
Engine/BuildTools/validate.sh unit-tests
Engine/BuildTools/validate.sh android-arm64-client linux-client linux-serverBuildTools Python regression tests live under Engine/BuildTools/tests/ and can be run directly:
pytest -q Engine/BuildTools/testsAll internal CMake modules now live under Engine/BuildTools/cmake.
The public entry point kept at the Engine/BuildTools root is Init.cmake; staged CMake implementation lives under Engine/BuildTools/cmake/stages/ and helpers under Engine/BuildTools/cmake/helpers/.
The validation project scaffold continues to live under Engine/BuildTools/validation-project.
Build scripts (sh/bat) can be called both from current directory (e.g. ./linux.sh) or repository root (e.g. BuildTools/linux.sh).
Following environment variables may be set before starting build scripts:
BuildTools consumes only project-specific overrides with the FO_ prefix. Any declared FO_* CMake option can be overridden from an environment variable with the same name. Standard tool variables such as ANDROID_HOME, ANDROID_SDK_ROOT, and ANDROID_NDK_ROOT are reserved for spawned external tools and are not read as BuildTools inputs.
Path to root directory of FOnline repository.
If not specified then taked one level outside directory of running script file (i.e. outside BuildTools, at repository root).
Default: $(dirname ./script.sh)/../
Example: export FO_ENGINE_ROOT=/mnt/d/fonline
Path to directory where all intermediate build files will be stored.
Default behaviour is build in current directory plus Workspace.
Default: $PWD/Workspace
Example: export FO_ENGINE_ROOT=/mnt/d/fonline-workspace
Optional explicit Android SDK and NDK overrides for BuildTools. If not set, BuildTools uses prepared workspace locations and then the system /usr/lib/android-sdk fallback on Linux when available.
Shared workspace parts are prepared through buildtools.py and wrapped by the platform-specific scripts.
- Linux:
Engine/BuildTools/prepare-workspace.sh - macOS:
Engine/BuildTools/prepare-mac-workspace.sh - Windows:
Engine/BuildTools/prepare-win-workspace.ps1
At the moment the shared flow covers:
toolsetemscriptenandroid-ndkdotnetxwin
Linux system package installation is explicit and separate from workspace preparation:
common-packageslinux-packagesweb-packagesandroid-packageswindows-cross-packagesall-packages
Workspace features such as linux, web, android-arm64, and windows-cross do not install apt packages. On a fresh host, pass the matching *-packages feature first.
Host prerequisite checks are also available through the main tool:
buildtools.py host-check linuxbuildtools.py host-check macosbuildtools.py host-check windows
Host wrapper scripts now delegate to the unified workspace preparation command:
buildtools.py prepare-host-workspace linux ...buildtools.py prepare-host-workspace windows ...buildtools.py prepare-host-workspace macos ...
Emscripten version is pinned by Engine/ThirdParty/emscripten and installed into Workspace/emsdk.
Examples:
python3 Engine/BuildTools/buildtools.py prepare-workspace toolset
python3 Engine/BuildTools/buildtools.py prepare-workspace emscripten
python3 Engine/BuildTools/buildtools.py prepare-workspace android-ndk dotnet
python3 Engine/BuildTools/buildtools.py prepare-workspace toolset emscripten android-ndk dotnet --check
python3 Engine/BuildTools/buildtools.py prepare-host-workspace linux web-packages web dotnetLinux hosts can prepare the Windows cross-compilation SDK/CRT through the same wrapper:
bash Engine/BuildTools/prepare-workspace.sh windows-cross-packages windows-cross
bash Engine/BuildTools/prepare-workspace.sh windows-cross
python3 Engine/BuildTools/buildtools.py prepare-workspace xwin
python3 Engine/BuildTools/buildtools.py build win64 client Release
python3 Engine/BuildTools/buildtools.py build win32 client ReleaseThe windows-cross-packages feature installs/checks Linux prerequisites. The windows-cross wrapper feature and direct prepare-workspace xwin command are workspace-only: they use the xwin version pinned in Engine/ThirdParty/xwin, prepare both x86 and x86_64 SDK/CRT trees into Workspace/xwin, and intentionally skip system package installation for pre-provisioned CI hosts. buildtools.py splats the primary architecture first, then merges secondary architecture library directories from isolated splats to avoid the xwin 0.6.6-rc.2 shared-symlink race in one multi-arch invocation. Each splat passes --http-retry 5 so transient Microsoft CDN body-read failures are retried before failing the workspace preparation.
For win32, buildtools.py passes CMAKE_SYSTEM_PROCESSOR=x86; the toolchain keeps the xwin x86 library paths and forces clang-cl --target=i686-pc-windows-msvc so CMake compiler probes do not emit x64 objects for an x86 link.
The local Windows web debug flow uses these shared commands:
buildtools.py build web client RelWithDebInfobuildtools.py package-web-debug
For an optimized browser build use:
buildtools.py build web client Release
The packaged browser build is emitted into Workspace/web-debug/<ProjectDevName>-Client-LocalTest-Web and can be served by the generated web-server.py helper.
The local Android debug flow uses these shared commands:
Supported Android platform identifiers are android-arm32, android-arm64, and android-x86.
Device deployment is built around ADB over Wi-Fi. The target device must have wireless debugging enabled and be paired with this host if Android requests pairing.
buildtools.py build android-arm64 client RelWithDebInfobuildtools.py package-android-debug LF android-arm64 LocalTestbuildtools.py package-android-debug LF android-arm64 RemoteSceneLaunchandroid_device.py --workspace-root Workspace connect
The Android SDK and NDK workspace parts must be prepared first. Use android-packages only on a fresh Linux host that still needs system packages:
bash Engine/BuildTools/prepare-workspace.sh android-arm64bash Engine/BuildTools/prepare-workspace.sh android-packages android-arm64
The packaged Android build is emitted into Workspace/android-debug/<ProjectDevName>-Client-LocalTest-Android as a ready-to-build Gradle project. Build and deploy:
python3 Engine/BuildTools/android_device.py --workspace-root Workspace connect
cd Workspace/android-debug/<ProjectDevName>-Client-LocalTest-Android
./gradlew assembleDebug
python3 Engine/BuildTools/android_device.py --workspace-root Workspace install --apk Workspace/android-debug/<ProjectDevName>-Client-LocalTest-Android/app/build/outputs/apk/debug/app-debug.apk
python3 Engine/BuildTools/android_device.py --workspace-root Workspace launch --activity com.example.game/.FOnlineActivity
# Remote scene launch from host to Android device
python3 Engine/BuildTools/buildtools.py package-android-debug LF android-arm64 RemoteSceneLaunch
cd Workspace/android-debug/<ProjectDevName>-Client-RemoteSceneLaunch-Android
./gradlew assembleDebug
python3 Engine/BuildTools/android_device.py --workspace-root Workspace install --apk Workspace/android-debug/<ProjectDevName>-Client-RemoteSceneLaunch-Android/app/build/outputs/apk/debug/app-debug.apk
python3 Engine/BuildTools/android_device.py --workspace-root Workspace launch-game --activity com.example.game/.FOnlineActivitylaunch-game auto-detects the host LAN IP that reaches the selected Wi-Fi Android device and passes it as a runtime ClientNetwork.ServerHost override, which makes the packaged RemoteSceneLaunch client connect back to the host server without editing baked config files.
At runtime, FOnlineActivity stages assets/Resources into the app files directory on first launch after install or update and then starts the engine with absolute Baking.ClientResources and Baking.CacheResources overrides that point to that runtime location.
Android SDK command-line tools version is pinned by Engine/ThirdParty/android-sdk and installed into Workspace/android-sdk.
Android NDK version is pinned by Engine/ThirdParty/android-ndk and installed into Workspace/android-ndk.
The Gradle project template lives in Engine/BuildTools/android-project/ and uses $PLACEHOLDER$ tokens patched by package.py during packaging. Configuration values come from the project main config Android.* settings, including the launcher icon PNG source and the Android signing settings.
Android release APK packaging signs the artifact. Configure signing through Android.Keystore, Android.KeystorePassword, Android.KeyAlias, and Android.KeyPassword in the project main config. package.py passes Android.KeystorePassword and Android.KeyPassword to Gradle through FO_ANDROID_RELEASE_STORE_PASSWORD and FO_ANDROID_RELEASE_KEY_PASSWORD environment variables instead of writing them into the generated Gradle project. If you build the generated Gradle project manually, set those variables before ./gradlew assembleRelease; if the signing settings are empty, packaging falls back to the Gradle debug signing key so generated package APKs remain installable on development devices. If needed, these settings can use $ENV{...} expressions.
APK packaging runs Gradle with GRADLE_USER_HOME under the current workspace output tree instead of the shared ~/.gradle, so parallel CI package jobs do not contend for global Gradle caches.
android_device.py first tries adb mdns services, shows any discovered Android Wi-Fi endpoints as a numbered list, caches the selected endpoint in Workspace/android-debug/device-endpoint.txt, and falls back to manual IP[:port] entry when discovery returns nothing.
For the maintained staged CMake pipeline guide, see ../Docs/BuildToolsPipeline.md.