/mobile-development
Use when targeting Android/iOS — export and signing, permissions, plugins, in-app purchases, ads, app lifecycle, device features, and mobile performance
$ npx -y skills add jame581/GodotPrompter --skill mobile-development --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/mobile-development
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when targeting Android/iOS — export and signing, permissions, plugins, in-app purchases, ads, app lifecycle, device features, and mobile performance
SKILL.md
mobile-development.SKILL.mdname: mobile-development
description: Use when targeting Android/iOS — export and signing, permissions, plugins, in-app purchases, ads, app lifecycle, device features, and mobile performance
Mobile Development
Ship a Godot 4.x game to Android and iOS. This covers the platform-specific deltas beyond a generic export: signing, lifecycle, permissions, plugins, IAP, device features, and the mobile renderer/perf budget.
> **Related skills:** **export-pipeline** for the generic export flow and CI/CD, **responsive-ui** for safe-area layout, **input-handling** for touch, **godot-optimization** for mobile performance, **csharp-godot** for C# mobile caveats.
---
1. Export & signing
**Android:** OpenJDK 17 and the Android SDK; set `Java SDK Path` + `Android SDK Path` in **Editor Settings** (per-user, not per-project). Generate a release keystore:
keytool -v -genkey -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000
Preset fields: **Release / Release User / Release Password** (keystore and key passwords must currently match); uncheck **Export With Debug**. **AAB is mandatory for new Play uploads.** CI env overrides: `GODOT_ANDROID_KEYSTORE_RELEASE_{PATH,USER,PASSWORD}`.
**iOS:** macOS + Xcode. Export needs an **App Store Team ID** + a reverse-DNS bundle **Identifier**; Godot generates an `.xcodeproj` you build from Xcode. The iOS **simulator supports the Compatibility renderer only**.
A **custom Gradle build** (*Project → Install the Gradle Build template*) is **required for v2 plugins and IAP** (Godot 4.2+). Since Godot 4.7 the **Use Gradle Build** export option is no longer marked experimental ([GH-119172](https://github.com/godotengine/godot/pull/119172)) — treat it as the standard path when you need plugins or IAP.
> ⚠️ **Changed in Godot 4.7:** Deprecated Google Play OBB expansion-file support was removed from the Android export. Projects still relying on APK expansion files must migrate to Play Asset Delivery or PCK patching. See [GH-118283](https://github.com/godotengine/godot/pull/118283).
---
2. App lifecycle
Real `Node` notification constants: `NOTIFICATION_APPLICATION_PAUSED` (2015), `NOTIFICATION_APPLICATION_RESUMED` (2014), `NOTIFICATION_APPLICATION_FOCUS_IN`/`_OUT` (2016/2017), `NOTIFICATION_WM_GO_BACK_REQUEST` (1007, Android Back). **There is no `WM_CLOSE_REQUEST` on mobile.** Autosave on PAUSED; **iOS gives ~5 s** after pause to finish work before it kills the app.
GDScript
func _notification(what: int) -> void:
match what:
NOTIFICATION_APPLICATION_PAUSED:
SaveManager.save_game() # App backgrounded — persist now.
NOTIFICATION_WM_GO_BACK_REQUEST:
_confirm_quit() # Android Back button.C# Equivalent
The docs only show `NotificationWMCloseRequest` verbatim; these PascalCase names follow the same convention.
public override void _Notification(int what)
{
switch ((long)what)
{
case NotificationApplicationPaused:
SaveManager.SaveGame(); // App backgrounded — persist now.
break;
case NotificationWMGoBackRequest:
ConfirmQuit(); // Android Back button.
break;
}
}Picture-in-Picture (Android, Godot 4.7+)
`DisplayServer.pip_mode_enter(window_id = 0)` enters picture-in-picture mode; `is_in_pip_mode(window_id = 0)` reports the current state; `pip_mode_set_aspect_ratio(numerator, denominator, window_id = 0)` sets the PiP window's aspect ratio; `pip_mode_set_auto_enter_on_background(auto_enter_on_background, window_id = 0)` enters PiP automatically when the app goes to the background. Transitions arrive as `Node` notifications: `NOTIFICATION_APPLICATION_PIP_MODE_ENTERED` (2019) / `NOTIFICATION_APPLICATION_PIP_MODE_EXITED` (2020). All Android-only.
func _ready() -> void:
DisplayServer.pip_mode_set_aspect_ratio(16, 9)
DisplayServer.pip_mode_set_auto_enter_on_background(true)
func _notification(what: int) -> void:
match what:
NOTIFICATION_APPLICATION_PIP_MODE_ENTERED:
_set_minimal_hud(true) # PiP window is tiny — hide non-essential UI.
NOTIFICATION_APPLICATION_PIP_MODE_EXITED:
_set_minimal_hud(false)public override void _Ready()
{
DisplayServer.PipModeSetAspectRatio(16, 9);
DisplayServer.PipModeSetAutoEnterOnBackground(true);
}
public override void _Notification(int what)
{
switch ((long)what)
{
case NotificationApplicationPipModeEntered:
SetMinimalHud(true); // PiP window is tiny — hide non-essential UI.
break;
case NotificationApplicationPipModeExited:
SetMinimalHud(false);
break;
}
}---
3. Permissions
Declare each permission in the export preset as `permissions/<name>`; request it at runtime with `OS.request_permission(name)`. The result arrives via `MainLoop`'s `on_request_permissions_result(permission, granted)`. The permission **must also be enabled in the preset**, not just requested.
GDScript
func _ready():
if "android.permission.POST_NOTIFICATIONS" not in OS.get_granted_permissions():
OS.request_permission("android.permission.POST_NOTIFICATIONS")
get_tree().on_request_permissions_result.connect(_on_perm_result)
func _on_perm_result(permission: String, granted: bool):
print("%s granted: %s" % [permission, granted])C# Equivalent
public override void _Ready()
{
if (!OS.GetGrantedPermissions().Contains("android.permission.POST_NOTIFICATIONS"))
OS.RequestPermission("android.permission.POST_NOTIFICATIONS");
GetTree().OnRequestPermissionsResult += OnPermResult;
}
private void OnPermResult(string permission, bool granted)
=> GD.Print($"{permission} granted: {granted}");---
4. Calling Android APIs (JavaClassWrapper) — Godot 4.4+
**Godot 4.4+ only.** `JavaClassWrapper.wrap("<java.class>")` calls
Read more
name: mobile-development description: Use when targeting Android/iOS — export and signing, permissions, plugins, in-app purchases, ads, app lifecycle, device features, and mobile performance
Mobile Development
Ship a Godot 4.x game to Android and iOS. This covers the platform-specific deltas beyond a generic export: signing, lifecycle, permissions, plugins, IAP, device features, and the mobile renderer/perf budget.
> **Related skills:** **export-pipeline** for the generic export flow and CI/CD, **responsive-ui** for safe-area layout, **input-handling** for touch, **godot-optimization** for mobile performance, **csharp-godot** for C# mobile caveats.
---
1. Export & signing
**Android:** OpenJDK 17 and the Android SDK; set `Java SDK Path` + `Android SDK Path` in **Editor Settings** (per-user, not per-project). Generate a release keystore:
keytool -v -genkey -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000
Preset fields: **Release / Release User / Release Password** (keystore and key passwords must currently match); uncheck **Export With Debug**. **AAB is mandatory for new Play uploads.** CI env overrides: `GODOT_ANDROID_KEYSTORE_RELEASE_{PATH,USER,PASSWORD}`.
**iOS:** macOS + Xcode. Export needs an **App Store Team ID** + a reverse-DNS bundle **Identifier**; Godot generates an `.xcodeproj` you build from Xcode. The iOS **simulator supports the Compatibility renderer only**.
A **custom Gradle build** (*Project → Install the Gradle Build template*) is **required for v2 plugins and IAP** (Godot 4.2+). Since Godot 4.7 the **Use Gradle Build** export option is no longer marked experimental ([GH-119172](https://github.com/godotengine/godot/pull/119172)) — treat it as the standard path when you need plugins or IAP.
> ⚠️ **Changed in Godot 4.7:** Deprecated Google Play OBB expansion-file support was removed from the Android export. Projects still relying on APK expansion files must migrate to Play Asset Delivery or PCK patching. See [GH-118283](https://github.com/godotengine/godot/pull/118283).
---
2. App lifecycle
Real `Node` notification constants: `NOTIFICATION_APPLICATION_PAUSED` (2015), `NOTIFICATION_APPLICATION_RESUMED` (2014), `NOTIFICATION_APPLICATION_FOCUS_IN`/`_OUT` (2016/2017), `NOTIFICATION_WM_GO_BACK_REQUEST` (1007, Android Back). **There is no `WM_CLOSE_REQUEST` on mobile.** Autosave on PAUSED; **iOS gives ~5 s** after pause to finish work before it kills the app.
GDScript
func _notification(what: int) -> void:
match what:
NOTIFICATION_APPLICATION_PAUSED:
SaveManager.save_game() # App backgrounded — persist now.
NOTIFICATION_WM_GO_BACK_REQUEST:
_confirm_quit() # Android Back button.C# Equivalent
The docs only show `NotificationWMCloseRequest` verbatim; these PascalCase names follow the same convention.
public override void _Notification(int what)
{
switch ((long)what)
{
case NotificationApplicationPaused:
SaveManager.SaveGame(); // App backgrounded — persist now.
break;
case NotificationWMGoBackRequest:
ConfirmQuit(); // Android Back button.
break;
}
}Picture-in-Picture (Android, Godot 4.7+)
`DisplayServer.pip_mode_enter(window_id = 0)` enters picture-in-picture mode; `is_in_pip_mode(window_id = 0)` reports the current state; `pip_mode_set_aspect_ratio(numerator, denominator, window_id = 0)` sets the PiP window's aspect ratio; `pip_mode_set_auto_enter_on_background(auto_enter_on_background, window_id = 0)` enters PiP automatically when the app goes to the background. Transitions arrive as `Node` notifications: `NOTIFICATION_APPLICATION_PIP_MODE_ENTERED` (2019) / `NOTIFICATION_APPLICATION_PIP_MODE_EXITED` (2020). All Android-only.
func _ready() -> void:
DisplayServer.pip_mode_set_aspect_ratio(16, 9)
DisplayServer.pip_mode_set_auto_enter_on_background(true)
func _notification(what: int) -> void:
match what:
NOTIFICATION_APPLICATION_PIP_MODE_ENTERED:
_set_minimal_hud(true) # PiP window is tiny — hide non-essential UI.
NOTIFICATION_APPLICATION_PIP_MODE_EXITED:
_set_minimal_hud(false)public override void _Ready()
{
DisplayServer.PipModeSetAspectRatio(16, 9);
DisplayServer.PipModeSetAutoEnterOnBackground(true);
}
public override void _Notification(int what)
{
switch ((long)what)
{
case NotificationApplicationPipModeEntered:
SetMinimalHud(true); // PiP window is tiny — hide non-essential UI.
break;
case NotificationApplicationPipModeExited:
SetMinimalHud(false);
break;
}
}---
3. Permissions
Declare each permission in the export preset as `permissions/<name>`; request it at runtime with `OS.request_permission(name)`. The result arrives via `MainLoop`'s `on_request_permissions_result(permission, granted)`. The permission **must also be enabled in the preset**, not just requested.
GDScript
func _ready():
if "android.permission.POST_NOTIFICATIONS" not in OS.get_granted_permissions():
OS.request_permission("android.permission.POST_NOTIFICATIONS")
get_tree().on_request_permissions_result.connect(_on_perm_result)
func _on_perm_result(permission: String, granted: bool):
print("%s granted: %s" % [permission, granted])C# Equivalent
public override void _Ready()
{
if (!OS.GetGrantedPermissions().Contains("android.permission.POST_NOTIFICATIONS"))
OS.RequestPermission("android.permission.POST_NOTIFICATIONS");
GetTree().OnRequestPermissionsResult += OnPermResult;
}
private void OnPermResult(string permission, bool granted)
=> GD.Print($"{permission} granted: {granted}");---
4. Calling Android APIs (JavaClassWrapper) — Godot 4.4+
**Godot 4.4+ only.** `JavaClassWrapper.wrap("<java.class>")` calls
Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

