2dog.android
4.7.2.192
See the version list below for details.
dotnet add package 2dog.android --version 4.7.2.192
NuGet\Install-Package 2dog.android -Version 4.7.2.192
<PackageReference Include="2dog.android" Version="4.7.2.192" />
<PackageVersion Include="2dog.android" Version="4.7.2.192" />
<PackageReference Include="2dog.android" />
paket add 2dog.android --version 4.7.2.192
#r "nuget: 2dog.android, 4.7.2.192"
#:package 2dog.android@4.7.2.192
#addin nuget:?package=2dog.android&version=4.7.2.192
#tool nuget:?package=2dog.android&version=4.7.2.192
2dog.android
Initial, experimental Android host support. Godot's Java Activity owns the surface,
render thread, input, pause/resume and shutdown; the .NET app registers its runtime
before launching it. Do not use the desktop Engine.Start() loop on Android.
dnx 2dog add --android scaffolds such a host. By hand: reference 2dog.engine,
this package, and the 2dog.android-arm64 and/or 2dog.android-x64 meta packages.
Choose Debug or Release with TwoDogVariant and an explicit Android RID. Both native variants retain the JNI name
libgodot_android.so; exactly one belongs in each ABI directory of the APK.
Set GodotProjectDir to the Godot project, and dotnet publish -r android-arm64
produces a signed package. dotnet publish builds Release, for which .NET Android
makes an app bundle (.aab) unless the host sets
<AndroidPackageFormats>apk</AndroidPackageFormats> (the showcase does) or you publish
with -c Debug. The build:
- imports the project and exports its pck with the project's
Androidexport preset (TwoDogAndroidExportPreset), using the same capability as desktop publish: the build machine's editor libgodot from the2dog.<rid>.editorand2dog.toolspackages that2dog.enginebrings, orGodotEditor.TwoDogAndroidPacksupplies a pre-exported pck instead; - puts every Android library and dependency that the project's
.gdextensionfiles list for the APK's ABIs and variant intolib/<abi>/, where the engine loads it (TwoDogAndroidGdExtensions=falseopts out); - adds the pck as the APK asset
game.pck, whichTwoDogActivityloads.
Only android-arm64 and android-x64 are supported; any other RID fails with
TDGA013. Mark the Android preset runnable=false: a runnable Android preset starts the
editor's ADB device poll during the headless export, which logs an EditorSettings
error when it exits.
Signing follows established conventions only:
- .NET Android's
AndroidKeyStore=truewithAndroidSigningKeyStore,AndroidSigningKeyAlias,AndroidSigningStorePassandAndroidSigningKeyPassalways wins (env:andfile:password prefixes keep secrets out of logs); - otherwise Godot's export variables
GODOT_ANDROID_KEYSTORE_RELEASE_PATH,_USER(the key alias) and_PASSWORD(GODOT_ANDROID_KEYSTORE_DEBUG_*for debug builds). 2dog maps them onto the .NET properties and hands the password over as anenv:reference, so it never reads the secret; - otherwise the Android SDK's debug keystore,
debug.keystoreinANDROID_USER_HOMEor~/.android(aliasandroiddebugkey, passwordandroid), which Android Studio and Gradle sign debug builds with, so 2dog builds install as updates over theirs; - otherwise .NET's own debug key (in its
Xamarin/Mono for Androidsettings directory).
Release builds that fall back to a debug key say so.
TwoDogAndroidSigning=false turns the variable mapping off.
demos/showcase/showcase.android is the complete example; tests/android/host is
the minimal one. Both include the Java
dependencies Godot needs (AndroidX Fragment, DocumentFile, Kotlin standard library)
and extracts the game DLL into private app storage before AndroidHost.Register.
Registration happens in Application.OnCreate, including when Android recreates
the Godot Activity directly after process death.
Release builds trim and AOT-compile with .NET for Android's defaults (TrimMode=partial,
profiled AOT); TrimMode=full and AndroidEnableProfiledAot=false work too. The package
roots GodotSharp, GodotPlugins, twodog and TwoDogAndroidGameAssembly for the trimmer.
Native AOT (PublishAot), experimental in .NET for Android, links with the NDK
(AndroidNdkDirectory); 2dog then roots only GodotSharp and the game assembly. CoreCLR
(UseMonoRuntime=false), also experimental there, fails with TDGA006.
Host code reaches the scene through TwoDogActivity.addMainLoopStartedListener(Runnable):
Godot runs each listener on its render thread (the engine's main thread) once the main
loop has started and the main scene is in the tree. Register from Application.OnCreate
via JNI. A listener that throws is logged (tag TwoDogActivity) and the others still run;
handle exceptions in the listener to report them your own way.
demos/showcase/showcase.android uses it to drive scene nodes once per frame
(SceneTree.ProcessFrame) and to run the showcase's API smoke.
Build prerequisites: .NET 10 with the android workload, JDK 17, Android SDK 36,
build tools 36.1.0, and NDK 29.0.14206865 (see the pinned Godot submodule config).
CI builds the Android natives (arm64/x64, debug/release) and the Java AARs into the
godot-<hash> natives release; its pack job packs the 2dog.android* packages
from them. Neither build needs Mono glue. The pinned Godot submodule includes the
Android native-symbol resolver changes; rebuild the managed bindings from that
source before testing. To build everything locally:
uv run build-godot.py # desktop editor and managed bindings
uv run build-godot.py --platform android --arch arm64
uv run build-godot.py --platform android --arch x86_64
uv run scripts/build_android_java.py
uv run poe pack-android
uv run poe build # pack desktop dependencies and the managed engine with AndroidHost
Then publish a host and run it:
dotnet publish tests/android/host/android-smoke.csproj -c Debug -r android-x64 -o artifacts/android
uv run scripts/test_android_device.py artifacts/android/dev.twodog.smoke-Signed.apk --serial emulator-5554
scripts/publish_android.py wraps the same publish: --format aab builds an app
bundle, --pack supplies a pre-exported pck, and signing properties can be passed
using repeated --property NAME=VALUE arguments; use normal .NET Android keystore
configuration for distributable builds. No store upload or NuGet push is performed.
Run uv run poe test-android-build for Android build and package tests.
The APK smoke test validates C# callbacks, signals, node disposal and a rendered
pixel on an Android 36 x64 emulator. The showcase APK adds the main-loop hook, a
3D scene and a plain C GDExtension loaded from the APK's native library directory.
Input, pause/resume, restart, broader GDExtension coverage and physical-device
validation remain gates before production support.
The Android workload and emulator are not required for the build and package tests.
The separate tests/android/android.slnx keeps Android workload requirements out
of ordinary desktop solution builds. The Android packages ship to NuGet with the
others, and the Android Smoke job gates deploy. ForcePackAllPlatforms cannot pack
empty Android packages.
APK implementation milestones
- Build both native variants for one ABI, build both Java AARs, pack a private local NuGet feed, and publish a signed smoke APK (the publish exports the C# scene). Inspect the final APK for the exact selected native libraries, one ABI, the PCK and the extracted game-assembly asset. The private feed also contains desktop dependency stubs and must never be published.
- Run that APK on an x64 emulator. The scene verifies signals, native node
lookup, deferred disposal, 32 C# frame callbacks and a green rendered pixel before
reporting success. CI's Android Smoke job builds this APK and the showcase's
against the packed packages and runs both; the showcase must report
2DOG_ANDROID_SHOWCASE_SMOKE_PASSED. It uploads them asandroid-apks, with an arm64 showcase APK for devices. - Add Android engine tests for touch input, background/resume, Activity
recreation, process death and repeated launches, with per-test results and
crash diagnostics. Use Android-owned lifecycle fixtures and the existing
*Testsnaming convention. - Validate Debug/Release on physical arm64 hardware, AAB-derived APKs and a 16 KB page-size environment before expanding the supported RID list.
With source-matched GodotSharp/editor release outputs staged, an installed
Android workload, and ANDROID_HOME/JAVA_HOME pointing to the SDK/JDK,
build-android-apk packs a private feed from the staged payloads, publishes a host
against it exactly like dotnet publish above, and inspects the APK:
uv run poe build-android-apk
The pck export uses the editor libgodot packed from godot/bin, or --editor <godot mono editor>. Use --rid android-arm64 or --configuration Release for the other
target. --skip-native --skip-java reuses already staged payloads. --feed <dir>
publishes against already packed packages instead of packing them (CI passes its
nuget-packages, with its android-natives staged in godot/bin/android/ for the
APK inspection). The resulting APK and inspection report
are written to artifacts/android-apk/. --app showcase publishes the showcase host
instead (into artifacts/android-showcase-apk/); its GDExtension needs an Android NDK
(ANDROID_NDK_ROOT, or one under the Android SDK).
References: Godot Android library, .NET Android build items.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.8.0.195 | 0 | 11/13/2026 |
| 4.8.0.193 | 0 | 11/13/2026 |
| 4.8.0.190 | 0 | 11/13/2026 |
| 4.8.0.188 | 0 | 11/13/2026 |
| 4.8.0.176 | 0 | 11/12/2026 |
| 4.8.0.163 | 0 | 11/12/2026 |
| 4.8.0.160 | 2 | 11/10/2026 |
| 4.7.2.197 | 0 | 11/13/2026 |
| 4.7.2.192 | 0 | 11/13/2026 |
| 4.7.2.175 | 0 | 11/12/2026 |
| 4.7.2.162 | 8 | 11/10/2026 |
| 4.7.2.159 | 0 | 11/10/2026 |
| 4.7.2.158 | 0 | 11/9/2026 |
| 4.7.2.154 | 0 | 11/8/2026 |