If you want to build the GDExtension or a custom-module Godot Engine yourself, or to develop the plugin in parallel with SpriteStudio-SDK, follow these steps.
The flow for producing Godot binaries from this repository is as follows:
- Prepare
libssruntime— Obtain the SpriteStudio-SDK release artifacts and place them underss_player/runtime/. - Depending on how you want to consume the plugin, run 2-A. Build the GDExtension or 2-B. Build the Custom-Module Godot Engine to link the runtime above and produce Godot binaries.
Clone this repository, and clone Godot Engine / godot-cpp depending on your build target.
git clone https://github.com/cri-middleware/SSPlayerForGodot.git
cd SSPlayerForGodot
git clone https://github.com/godotengine/godot.git -b 4.7
git clone https://github.com/godotengine/godot-cpp.git -b masterThe godot directory is required when building a custom-module Godot Engine.
The godot-cpp directory is required when building the GDExtension.
Note
For typical builds that consume SDK release artifacts, the ss_player/SpriteStudio-SDK/ submodule does not need to be initialized (a non-recursive clone is fine). Only when developing/building SpriteStudio-SDK itself, follow For SpriteStudio-SDK Developers below and initialize the submodule with git submodule update --init --recursive.
For build tools (compiler, Python, SCons, etc.) on each platform, follow the official Godot compilation guides:
Godot 4.7 links two prebuilt SDKs that are not part of the engine source tree: AccessKit (screen reader support) and ANGLE (the OpenGL ES rendering driver). If they are missing, scons prints a warning and silently disables those drivers, producing binaries that lack features the official Godot builds ship with.
build.sh / build.ps1 download them on the first desktop build (using the installers in the godot/ checkout, so the versions always match the engine revision) into godot/bin/build_deps/ — or %LOCALAPPDATA%\Godot\build_deps on Windows. Pass deps=no to skip the download and build without those drivers:
./scripts/build.sh deps=noThe mobile and web platforms do not use either dependency, so nothing is downloaded for them.
The molten-vk package distributed via Homebrew only provides binaries for the host architecture, so linking fails when building with arch=universal. Install the universal-capable Vulkan SDK for MoltenVK instead.
Fetches and extracts the SDK package version pinned in scripts/SDK_VERSION.txt.
macOS / Linux
./scripts/download-sdk.shWindows (PowerShell)
.\scripts\download-sdk.ps1
libssconverter(the.sspj→.ssabconverter library) is bundled only for desktop platforms. The iOS / Android / Weblibssruntimepackages do not include it.
To build libssruntime from the SpriteStudio-SDK source yourself, see For SpriteStudio-SDK Developers.
Requires godot-cpp to be cloned at the master branch.
macOS / Linux
./scripts/build-extension.shWindows (PowerShell)
$env:PYTHONUTF8=1
.\scripts\build-extension.ps1Output is placed under bin/<platform>/, and the GDExtension package (including misc/spritestudio.gdextension) is installed into the sample projects (examples/*/addons/spritestudio/).
Requires godot to be cloned at the 4.7 branch.
build.sh / build.ps1 invoke scons with custom_modules=../ss_player.
macOS / Linux
./scripts/build.shWindows (PowerShell)
$env:PYTHONUTF8=1
.\scripts\build.ps1Output is placed under godot/bin/. On macOS, godot/Godot.app is also created.
Per-platform scripts under scripts/ build editor / template_debug / template_release in one shot.
Internally they invoke build.sh / build-extension.sh repeatedly with different target values.
These scripts do not fetch or build libssruntime, so 1. Prepare libssruntime must be completed first.
| Platform | Script | Notes |
|---|---|---|
| Windows | .\scripts\release-gdextension-windows.ps1 |
arch = host |
| macOS | ./scripts/release-gdextension-macos.sh |
Fixed at arch=universal |
| Linux | ./scripts/release-gdextension-linux.sh |
arch = host |
| iOS | ./scripts/release-gdextension-ios.sh |
Only template_debug / template_release |
| Android | ./scripts/release-gdextension-android.sh |
Three architectures: arm32 / arm64 / x86_64 |
| Web | ./scripts/release-gdextension-web.sh |
wasm32 (threads=yes / threads=no) |
| Platform | Script | Notes |
|---|---|---|
| Windows | .\scripts\release-windows.ps1 |
arch = host |
| macOS | ./scripts/release-macos.sh |
Fixed at arch=universal |
| iOS | ./scripts/release-ios.sh |
arch=arm64 (device) and arch=universal (simulator) |
| Android | ./scripts/release-android.sh |
Three architectures: arm32 / arm64 / x86_64 |
No batch release script is provided for the Linux custom module. Invoke
./scripts/build.sh platform=linux target=...directly for each ofeditor/template_debug/template_release.
If you want to debug the C++ code (ss_player/) of the plugin embedded as a custom module, follow these steps:
-
Verify the Debug Binary Godot binaries built with
target=editorortarget=template_debugcontain debug symbols by default.- macOS:
godot/Godot.app/Contents/MacOS/Godot - Windows:
godot/bin/godot.windows.editor.x86_64.exeetc. - Linux:
godot/bin/godot.linuxbsd.editor.x86_64etc.
- macOS:
-
Attach Debugger and Launch Arguments Specify the above binary as the launch program in your debugger (e.g., VSCode, Visual Studio, Xcode, LLDB/GDB). By passing the path to the target project as an argument (e.g.,
--path examples/dev_module), you can open the project directly without the project manager screen and start debugging.
VSCode (launch.json) Example (macOS / LLDB):
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Godot Custom Module",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/godot/Godot.app/Contents/MacOS/Godot",
"args": [
"--path",
"${workspaceFolder}/examples/dev_module"
],
"cwd": "${workspaceFolder}"
}
]
}To verify and debug whether the custom module or GDExtension works correctly in the exported application, using the headless export from the CLI is convenient.
Important
Common export pitfalls (all platforms):
- Build the exact
targetyou export with. Aneditorbuild alone is not enough —--export-debugneeds thetemplate_debuglibrary and--export-releaseneedstemplate_release. If those were never built, the export still "succeeds" but ships an empty/missing extension library (on macOS this surfaces as aCodeSign: Invalid binary formaterror on the embedded framework). - The extension architecture is bounded by the runtime slices you have. The GDExtension links
libssruntimefromss_player/runtime/libs/<platform>/; you can only build the architectures present there. For example, with anarm64-only macOS runtime you cannot produce auniversal/x86_64extension — set the preset'sbinary_format/architectureto match (e.g.arm64). The engine template can still beuniversal; a single-arch extension just won't load on the missing arch. - Enable ETC2/ASTC for
universal/arm64/ mobile exports. Setrendering/textures/vram_compression/import_etc2_astc=truein the project (project.godot→[rendering]), otherwise the export aborts with "Cannot export … with the ETC2/ASTC texture format disabled." - Export templates must match the editor version. Setting
custom_template/debug/custom_template/releasebypasses the version check (this is how a template built from the bundledgodot/source can be reused). Set both debug and release paths even for a debug-only export — Godot validates both and otherwise reports the release template as missing.
The following is the flow for building/installing templates and exporting a sample project. (The example below uses macOS)
-
Build the runtime and templates Prepare
libssruntimebeforehand, then run the release script for the target platform.# Prepare the runtime in release build (if necessary) ./scripts/build-runtime.sh build=release platform=macos # Build the export templates ./scripts/release-macos.sh
-
Install templates Install the built templates into the local directory recognized by Godot. macOS / Linux:
./scripts/install-template.sh macos
Windows (PowerShell):
.\scripts\install-template.ps1 windows -
Run export from CLI Use the built Godot editor (in headless mode) to invoke the export process directly from the command line. macOS / Linux:
# Example: Export the dev_module project for macOS (outputs directly as .app) ./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless --export-debug "macOS" output.app
Windows (PowerShell):
.\godot\bin\godot.windows.editor.x86_64.exe --path .\examples\dev_module\ --headless --export-debug "Windows Desktop" output.exe
Note: To run the export, the target project's
export_presets.cfgmust contain the preset for the specified platform name (e.g.,"macOS"), and required identifiers (such as Bundle ID) must be properly configured.
Exporting for the Web produces multiple files (e.g., .html, .wasm, .pck), so create a dedicated directory for the export. Additionally, a local server is required to bypass browser security restrictions.
# 1. Create an output directory and export for Web
mkdir -p build_web
./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless --export-debug "Web" ../../build_web/index.html
# 2. Start a local HTTP server
cd build_web
python3 -m http.server 8000After starting the server, access http://localhost:8000 in your browser to verify it works.
(Since this plugin operates with nothread on the Web, it can be launched with a simple HTTP server without requiring special CORS headers.)
The official Godot Web export templates do not support GDExtension libraries. If you export the GDExtension build variant for the Web with a stock template, the page fails at startup with:
GDExtension libraries are not supported by this engine version. Enable "Extensions Support" for your export preset and/or build your custom template with "dlink_enabled=yes".
To load a GDExtension on the Web, you need an engine template built with dynamic linking enabled (dlink_enabled=yes). Build one from the bundled godot/ source, matching the threads mode of your extension (this plugin ships nothread, so use threads=no):
# Build dlink-enabled Web templates from source (nothreads)
cd godot
scons platform=web target=template_debug dlink_enabled=yes threads=no
scons platform=web target=template_release dlink_enabled=yes threads=no
# → godot/bin/godot.web.template_debug.wasm32.nothreads.dlink.zip
# → godot/bin/godot.web.template_release.wasm32.nothreads.dlink.zipThen install the built templates so Godot can resolve them by name:
./scripts/install-template.sh web
# installs → <export_templates>/<version>/web_nothreads_dlink_debug.zip
# web_nothreads_dlink_release.zipOnce these are installed, exporting only requires turning on Extensions Support in the Web preset — Godot auto-selects the matching ..._dlink_... template by name, so no custom_template is needed. The preset side (from a plugin user's perspective) is covered in Exporting Your Project → Web.
If you would rather not install them into Godot's templates folder, you can instead point
custom_template/debug/custom_template/releasein theWebpreset directly at the built*.dlink.zipfiles.
A dlink template splits the engine into a small main module plus a large godot.side.wasm; after export you will see a corresponding index.side.wasm alongside index.wasm, which confirms the dlink template was used.
Note
dlink / Extensions Support is required only for the GDExtension build variant. The custom module variant compiles the plugin into the engine, so its Web template is the ordinary (non-dlink) web_nothreads_{debug,release}.zip produced by release-web.sh (via build.sh) and installed the same way — with no dlink_enabled and no Extensions Support in the preset.
Android export templates are template APKs packaged by the engine's Gradle project. Unlike the desktop platforms, the template build therefore has three stages (runtime → per-ABI engine libraries → Gradle packaging) before install-template.sh.
Prerequisites
- Android SDK and NDK, with
cargo-ndkand the Rust Android targets installed (aarch64-linux-android,armv7-linux-androideabi,x86_64-linux-android). - Export the SDK/NDK paths so the build scripts can find them (adjust to your environment):
export ANDROID_HOME="$HOME/Library/Android/sdk" export ANDROID_NDK_ROOT="$ANDROID_HOME/ndk/<ndk-version>"
- In the Godot editor settings, configure the Android SDK path and a debug keystore (
export/android/android_sdk_path,export/android/debug_keystore,export/android/debug_keystore_pass).
-
Build the runtime and templates Build the Rust runtime once, then build the engine shared library for each ABI/target, and package them into the template APKs with Gradle.
# Rust runtime (a single release build is reused by both template targets) ./scripts/build-runtime.sh platform=android build=release # Alternatively, fetch the prebuilt runtime for all platforms instead of building it: # ./scripts/download-sdk.sh # Engine .so per ABI. arch: arm64 / arm32 / x86_64, target: template_release / template_debug ./scripts/build.sh platform=android arch=arm64 target=template_release ./scripts/build.sh platform=android arch=arm32 target=template_release ./scripts/build.sh platform=android arch=x86_64 target=template_release ./scripts/build.sh platform=android arch=arm64 target=template_debug # add other ABIs as needed # Package into android_release.apk / android_debug.apk / android_source.zip (cd godot/platform/android/java && ./gradlew generateGodotTemplates)
The
archvalues follow Godot's names (arm64,arm32,x86_64,x86_32), while the runtime libraries are placed under the matching Android ABI directories (arm64-v8a,armeabi-v7a,x86_64,x86). You only need the ABI of the device/emulator you intend to run on. -
Install templates
./scripts/install-template.sh android
-
Run export from CLI
mkdir -p bin_export ./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless --export-debug "Android" "$(pwd)/bin_export/dev_module_debug.apk"
Note: Android export requires ETC2/ASTC texture import to be enabled. Otherwise the export aborts with a configuration error whose message is empty. Set
rendering/textures/vram_compression/import_etc2_astc=truein the project settings (already enabled inexamples/dev_module). -
Install and run on a device / emulator
adb install -r bin_export/dev_module_debug.apk adb shell am start -n com.crimw.devmodule/com.godot.game.GodotAppLauncher adb logcat -s godot # check the engine log / errors adb exec-out screencap -p > screen.png # capture the rendered frame
The
dev_modulesample plays theKnight_arrowanimation onSpriteStudioPlayer2Dwith autoplay, so a successful run renders the character on screen.
iOS export requires macOS with Xcode. Godot generates an Xcode project (not a ready-to-run app) and then auto-runs xcodebuild archive for a device, which needs an Apple Developer account — so an App Store Team ID must be set in the preset, and the device-archive step fails without valid signing. For a quick, unsigned check, build the generated project for the iOS Simulator yourself.
Important
Self-built iOS templates do not bundle MoltenVK. Godot's iOS engine is built with Vulkan, so the app binary hard-links @rpath/MoltenVK.framework/MoltenVK (confirm with otool -L). This is a property of the engine build, not the project's renderer — a GL Compatibility project links it too. The official Godot iOS templates ship MoltenVK.xcframework; the template produced by release-ios.sh does not. When testing a self-built template you must supply it yourself, or the app crashes at launch with Library not loaded: @rpath/MoltenVK.framework/MoltenVK.
Simulator smoke-test of a self-built template (custom module shown; the GDExtension flow is identical with dev_gdextension):
# 1. Export the Xcode project (Godot's device-archive step will fail on signing — that's expected)
mkdir -p bin_export/ios
./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless \
--export-debug "iOS" "$(pwd)/bin_export/ios/dev_module.xcodeproj" || true
# 2. Place MoltenVK where the Xcode project expects it (e.g. from the Vulkan SDK)
MVK="$HOME/VulkanSDK/<ver>/iOS/lib/MoltenVK.xcframework"
cp -R "$MVK" bin_export/ios/MoltenVK.xcframework
# 3. Build for the Simulator, unsigned
cd bin_export/ios
xcodebuild -project dev_module.xcodeproj -scheme dev_module \
-sdk iphonesimulator -configuration Debug -derivedDataPath ./DerivedData \
CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build
APP="DerivedData/Build/Products/Debug-iphonesimulator/dev_module.app"
# 4. Embed MoltenVK into the app and ad-hoc re-sign (the simulator rejects the SDK's own signature)
cp -R "$MVK/ios-arm64_x86_64-simulator/MoltenVK.framework" "$APP/Frameworks/"
codesign --force --sign - "$APP/Frameworks/MoltenVK.framework"
codesign --force --sign - "$APP"
# 5. Boot a simulator, install, launch, screenshot
DEV=$(xcrun simctl list devices available | grep -m1 -oE '\([0-9A-F-]{36}\)' | tr -d '()')
xcrun simctl boot "$DEV" && xcrun simctl install "$DEV" "$APP"
xcrun simctl launch "$DEV" com.crimw.devmodule
xcrun simctl io "$DEV" screenshot screen.pngNote: The proper fix is to bundle
MoltenVK.xcframeworkinto the iOS template itself (install-template.sh/misc/dist/apple_embedded_xcode) so the export embeds and signs it automatically, matching the official templates. The manual steps above are only needed for self-built templates — end users on the official Godot editor and official export templates are unaffected.
For GDExtensions (e.g., dev_gdextension), rebuilding the engine itself or installing custom templates is unnecessary. You can export as-is using the standard Godot editor and official export templates distributed by Godot.
-
Release build of the GDExtension plugin Run the build script for the target platform beforehand to output the libraries (e.g.,
.so,.xcframework,.dll) into the project'saddons/directory. macOS / Linux:./scripts/release-gdextension-macos.sh
Windows (PowerShell):
.\scripts\release-gdextension-windows.ps1
-
Run export from CLI Export the project using the official Godot binary (or your own Godot command). macOS / Linux:
# * Here, "godot" refers to the official Godot editor executable in your path. godot --path ./examples/dev_gdextension/ --headless --export-debug "macOS" output.app
Windows (PowerShell):
# * "godot.exe" refers to the official Godot executable. godot.exe --path .\examples\dev_gdextension\ --headless --export-debug "Windows Desktop" output.exe
During export, Godot will automatically bundle the plugin files (
.so,.framework,.dll, etc.) into the exported artifacts.Android note: Android needs a few extra steps beyond the desktop flow above:
- Build the Android plugin libraries with
./scripts/release-gdextension-android.sh(requires the Android SDK/NDK,cargo-ndk, the Rust Android targets, and the Android runtime — build it with./scripts/build-runtime.sh platform=android build=releaseor fetch the prebuilt one with./scripts/download-sdk.sh). Thearchvalues are Godot's names (arm64,arm32,x86_64), while the runtime is linked from the matching Android ABI directory (arm64-v8a,armeabi-v7a,x86_64). - Also build the host plugin (e.g.
./scripts/release-gdextension-macos.sh). During export the.ssabresources are loaded on the host machine, so without a working host library the export drops them with aFailed loading resourceerror and the resulting APK ships without animation data. - Install the official Android export templates for the official Godot version you are using (via Manage Export Templates in the editor, or by placing the
.tpzcontents under.../export_templates/<version>/). - Enable
rendering/textures/vram_compression/import_etc2_astc=truein the project settings (already set inexamples/dev_gdextension); otherwise the export aborts with a configuration error whose message is empty. - Then export and run on a device / emulator:
mkdir -p bin_export godot --path ./examples/dev_gdextension/ --headless --export-debug "Android" "$(pwd)/bin_export/dev_gdextension_debug.apk" adb install -r bin_export/dev_gdextension_debug.apk adb shell am start -n com.crimw.devgdext/com.godot.game.GodotAppLauncher adb logcat -s godot
- Build the Android plugin libraries with
You can debug the C++ code for GDExtensions using almost the same steps as a custom module. The only difference is that the launch program is the "official Godot editor".
-
Verify the GDExtension debug build The normal build scripts (like
build-extension.sh) usetarget=template_debugby default, so the output libraries (.dll,.dylib) include debug symbols. -
Attach Debugger and Launch Arguments Specify the official Godot binary as the launch program in your debugger (e.g., VSCode, Visual Studio), and pass the project path as an argument (
--path examples/dev_gdextension). The breakpoint will be hit once Godot dynamically loads the plugin at startup.
VSCode (launch.json) Examples:
macOS / Linux (LLDB):
{
"name": "Debug GDExtension (macOS)",
"type": "lldb",
"request": "launch",
"program": "/Applications/Godot.app/Contents/MacOS/Godot", // Path to official binary
"args": [ "--path", "${workspaceFolder}/examples/dev_gdextension" ],
"cwd": "${workspaceFolder}"
}Windows (Visual Studio Debugger):
{
"name": "Debug GDExtension (Windows)",
"type": "cppvsdbg",
"request": "launch",
"program": "C:\\path\\to\\Godot_v4.x-stable_win64.exe", // Path to official binary
"args": [ "--path", "${workspaceFolder}\\examples\\dev_gdextension" ],
"cwd": "${workspaceFolder}"
}The sections below are required only when developing/customizing SpriteStudio-SDK itself in parallel with the Godot side. General Godot builders using the SpriteStudio-SDK release artifacts can skip them.
For setting up the environment to build libssruntime yourself (Rust toolchain, etc.), refer to the SpriteStudio-SDK README.
If you also need to regenerate FlatBuffers headers, install flatc (the FlatBuffers compiler).
Requires the SpriteStudio-SDK submodule (ss_player/SpriteStudio-SDK/) to be initialized. If it is not initialized yet, run:
git submodule update --init --recursiveThen run the script below to build the Rust runtime/converter; the artifacts are placed under ss_player/runtime/ automatically.
macOS / Linux
./scripts/build-runtime.sh [platform=<platform>] [arch=<arch>] [build=<build>] [ios_simulator=<yes|no>]Windows (PowerShell)
.\scripts\build-runtime.ps1 [platform=<platform>] [arch=<arch>] [build=<build>] [ios_simulator=<yes|no>]| Option | Values | Default |
|---|---|---|
platform |
windows, macos, linux, android, ios, web |
Host OS |
arch |
x86_64, arm64, universal, wasm32, etc. |
Host Arch |
build |
debug, release |
debug |
ios_simulator |
yes, no |
no |
When .fbs files in SpriteStudio-SDK have changed, regenerate the headers under ss_player/format/ (requires flatc).
macOS / Linux
./scripts/generate-runtime-code.shWindows (PowerShell)
.\scripts\generate-runtime-code.ps1The sample projects under examples/ load .ssab assets converted from the SpriteStudio-SDK test projects. Regenerate them whenever an ssab_generated/ directory is missing or the SDK version has changed. Each sample carries a .ssplayer_sources.cfg pointing at the source .sspj, so opening it in the Godot Editor regenerates the assets through the import dock; the script below does the same thing headlessly.
macOS / Linux
./scripts/deploy-examples.shWindows (PowerShell)
.\scripts\deploy-examples.ps1The
examples/dev_*projects are excluded: they are developer-only scratch projects, so both their sources config andssab_generated/are gitignored and set up by hand in the editor.
Once the submodule is initialized, internal runtime specifications and porting notes are available at:
ss_player/SpriteStudio-SDK/libs/ssruntime/docs/README.ja.md