About This Page

This page covers mobile game development — touch input, platform-specific features, optimization, monetization, and publishing for iOS and Android. For engine setup see Godot, Unity, Unreal Engine. For game design patterns see Game Design. For audio see Game Audio.

History

  • How: Mobile gaming began with Snake on Nokia phones (1997), exploded with the App Store launch (2008), and became the world’s largest gaming market by revenue by 2016.
  • Who: Key players — Apple (iOS/App Store), Google (Android/Play Store), Unity Technologies (dominant mobile engine), and studios like Supercell, King, Niantic, and miHoYo.
  • Why: 3.6 billion mobile gamers worldwide (2024). Mobile is the most accessible gaming platform — no console required, always in pocket.

Mobile Gaming Timeline

timeline
    title Mobile Gaming Evolution
    1997 : Snake on Nokia
         : First mainstream mobile game
    2003 : Java ME Games
         : Basic 2D games on feature phones
    2008 : App Store Launch
         : iPhone changes everything
         : Touch-first design begins
    2010 : Angry Birds Era
         : Casual gaming explosion
         : Free-to-play model emerges
    2013 : Clash of Clans
         : Gacha and live service dominance
         : Mobile surpasses console revenue
    2016 : Pokemon GO
         : AR gaming goes mainstream
    2019 : Call of Duty Mobile
         : AAA quality on mobile
         : 120Hz displays arrive
    2023 : Genshin Impact Era
         : Console-quality mobile games
         : Cross-platform standard

Introduction

  • Mobile game development requires a fundamentally different mindset from PC/console development.
  • Constraints are severe — limited CPU, GPU, RAM, battery, and storage. Touch input replaces keyboard/mouse/controller.
  • But the audience is massive and the distribution is global and instant.

Mobile vs PC/Console

AspectMobilePC / Console
InputTouch, gyroscope, accelerometerKeyboard, mouse, controller
Session length2–10 minutes (casual)30–120 minutes
CPU4–8 cores, low clock speed8–16 cores, high clock speed
GPUTile-based (PowerVR, Mali, Adreno)Immediate mode (NVIDIA, AMD)
RAM2–8 GB (shared with OS)16–64 GB
Storage64–512 GB (shared)500 GB–4 TB
BatteryCritical constraintNot a concern
DistributionApp Store / Play StoreSteam, Epic, direct
MonetizationF2P dominantPremium dominant
Screen size4–7 inches24–55 inches

Mobile Game Knowledge Map

mindmap
  root((Mobile Game Dev))
    Input
      Touch Controls
      Gestures
      Gyroscope
      Accelerometer
    Platform
      iOS Specifics
      Android Specifics
      Cross-Platform
    Optimization
      CPU Performance
      GPU Performance
      Memory Management
      Battery Life
    Monetization
      Free-to-Play
      In-App Purchases
      Ads
      Battle Pass
    Publishing
      App Store
      Google Play
      Certification
      ASO

Touch Controls

Touch Input Types

Input TypeDescriptionGame Use Case
TapSingle finger touch and releaseJump, shoot, select
Double tapTwo taps quicklySpecial action, zoom
Long pressHold finger downCharge attack, context menu
SwipeDrag in a directionSlice, scroll, dodge
PinchTwo fingers moving togetherZoom out
SpreadTwo fingers moving apartZoom in
RotateTwo fingers rotatingRotate object
Multi-touchMultiple simultaneous touchesVirtual joystick + button
DragMove finger while heldMove character, drag UI
  • end ```

Virtual Controls Design

graph TD
    subgraph Good["✅ Good Virtual Control Design"]
        G1["Large touch targets\n(min 44x44 points / 88x88 px)"]
        G2["Transparent overlays\ndon't block gameplay"]
        G3["Customizable position\nplayer sets layout"]
        G4["Visual + haptic feedback\non every press"]
        G5["Dead zone on joystick\nprevents drift"]
    end
    subgraph Bad["❌ Bad Virtual Control Design"]
        B1["Tiny buttons\nfinger misses constantly"]
        B2["Opaque controls\nblock important gameplay"]
        B3["Fixed layout\ndoesn't fit all hand sizes"]
        B4["No feedback\nplayer unsure if pressed"]
Control TypeMin SizePlacementNotes
Movement joystick120×120 dpBottom-leftAllow repositioning
Action buttons60×60 dpBottom-right3–4 max visible
Jump button80×80 dpBottom-rightMost used — make largest
Menu/pause44×44 dpTop cornerSmall, out of the way

Touch Input in Unity

using UnityEngine;
using UnityEngine.InputSystem;
 
public class TouchInputHandler : MonoBehaviour
{
    void Update() {
        // New Input System — recommended
        if (Touchscreen.current == null) return;
 
        var touches = Touchscreen.current.touches;
        foreach (var touch in touches) {
            if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began) {
                Vector2 pos = touch.position.ReadValue();
                HandleTap(pos);
            }
        }
    }
 
    // Legacy Input — still widely used
    void UpdateLegacy() {
        for (int i = 0; i < Input.touchCount; i++) {
            Touch touch = Input.GetTouch(i);
 
            switch (touch.phase) {
                case TouchPhase.Began:
                    HandleTouchStart(touch.position, touch.fingerId);
                    break;
                case TouchPhase.Moved:
                    HandleTouchMove(touch.position, touch.deltaPosition, touch.fingerId);
                    break;
                case TouchPhase.Ended:
                case TouchPhase.Canceled:
                    HandleTouchEnd(touch.fingerId);
                    break;
            }
        }
    }
 
    void HandleTap(Vector2 screenPos) {
        // Convert screen position to world position
        Ray ray = Camera.main.ScreenPointToRay(screenPos);
        if (Physics.Raycast(ray, out RaycastHit hit)) {
            Debug.Log("Tapped: " + hit.collider.name);
        }
    }
 
    void HandleTouchStart(Vector2 pos, int id) { }
    void HandleTouchMove(Vector2 pos, Vector2 delta, int id) { }
    void HandleTouchEnd(int id) { }
}

Touch Input in Godot

extends Node2D
 
var touch_positions: Dictionary = {}  # finger_id → position
 
func _input(event: InputEvent) -> void:
    if event is InputEventScreenTouch:
        if event.pressed:
            touch_positions[event.index] = event.position
            _on_touch_start(event.index, event.position)
        else:
            touch_positions.erase(event.index)
            _on_touch_end(event.index, event.position)
 
    elif event is InputEventScreenDrag:
        touch_positions[event.index] = event.position
        _on_touch_drag(event.index, event.position, event.relative)
 
func _on_touch_start(finger_id: int, pos: Vector2) -> void:
    print("Touch started: finger %d at %s" % [finger_id, pos])
 
func _on_touch_drag(finger_id: int, pos: Vector2, delta: Vector2) -> void:
    # Virtual joystick logic
    if finger_id == 0:  # left thumb
        var joystick_input = (pos - joystick_origin).normalized()
        player.velocity = joystick_input * player_speed
 
func _on_touch_end(finger_id: int, pos: Vector2) -> void:
    if finger_id == 0:
        player.velocity = Vector2.ZERO

Gesture Recognition

# Simple swipe detection in Godot
extends Node
 
var touch_start: Vector2
var touch_start_time: float
const SWIPE_MIN_DISTANCE: float = 50.0
const SWIPE_MAX_TIME: float = 0.3
 
func _input(event: InputEvent) -> void:
    if event is InputEventScreenTouch:
        if event.pressed:
            touch_start = event.position
            touch_start_time = Time.get_ticks_msec() / 1000.0
        else:
            var elapsed = Time.get_ticks_msec() / 1000.0 - touch_start_time
            var delta = event.position - touch_start
            if delta.length() > SWIPE_MIN_DISTANCE and elapsed < SWIPE_MAX_TIME:
                _on_swipe(delta.normalized())
 
func _on_swipe(direction: Vector2) -> void:
    if abs(direction.x) > abs(direction.y):
        if direction.x > 0: print("Swipe RIGHT")
        else: print("Swipe LEFT")
    else:
        if direction.y > 0: print("Swipe DOWN")
        else: print("Swipe UP")

Gyroscope & Accelerometer

// Unity — gyroscope and accelerometer
void Start() {
    // Enable gyroscope
    Input.gyro.enabled = true;
}
 
void Update() {
    // Accelerometer — tilt controls
    Vector3 tilt = Input.acceleration;
    // tilt.x = left/right tilt (-1 to 1)
    // tilt.y = forward/back tilt
    // tilt.z = face up/down
 
    float steerInput = Mathf.Clamp(tilt.x * 2f, -1f, 1f);
    car.Steer(steerInput);
 
    // Gyroscope — rotation rate
    Vector3 rotationRate = Input.gyro.rotationRate;
    // Use for aiming, camera control in FPS
}

Mobile Optimization

Mobile GPU Architecture

graph TD
    subgraph Desktop["🖥️ Desktop GPU — Immediate Mode"]
        D1["Draw call submitted"]
        D2["Entire frame rendered immediately"]
        D3["Results written to VRAM"]
        D1 --> D2 --> D3
    end
    subgraph Mobile["📱 Mobile GPU — Tile-Based Deferred Rendering"]
        M1["Draw call submitted"]
        M2["Screen divided into tiles\n(16x16 or 32x32 pixels)"]
        M3["Each tile rendered\ncompletely in on-chip memory"]
        M4["Tile written to RAM\nonly when complete"]
        M1 --> M2 --> M3 --> M4
    end
    Mobile -->|"Benefit"| Benefit["Lower memory bandwidth\nBetter power efficiency"]
    Mobile -->|"Implication"| Impl["Avoid reading framebuffer mid-frame\nDeferred rendering is expensive"]

Performance Targets

TargetFPSFrame BudgetUse Case
Minimum30 FPS33.3msCasual, strategy
Standard60 FPS16.6msAction, platformer
High refresh90 FPS11.1msCompetitive, premium
Ultra120 FPS8.3msFlagship devices only

CPU Optimization

TechniqueDescriptionImpact
Object poolingReuse objects instead of instantiate/destroyHigh — eliminates GC spikes
Update throttlingDon’t update AI/physics every frameHigh — reduces CPU load
Job systemMultithreaded work (Unity Jobs, Godot threads)High — uses all cores
Avoid string operationsString allocation causes GCMedium
Cache component referencesDon’t call GetComponent every frameMedium
Reduce physics bodiesSleep inactive rigidbodiesMedium
LOD for AIDistant enemies use simplified logicMedium

GPU Optimization

TechniqueDescriptionImpact
Reduce draw callsBatch/instancing — fewer API callsVery High
Texture compressionETC2 (Android), ASTC (modern), PVRTC (iOS)Very High
MipmapsPre-generated lower-res textures for distanceHigh
Reduce overdrawSort transparent objects, use depth prepassHigh
Shader complexityUse mobile-optimized shaders (mediump)High
Avoid post-processingBloom, DOF, SSAO are expensive on mobileHigh
Texture atlasesCombine textures to reduce bindsMedium
Reduce polygon countMobile needs lower poly than PCMedium

Texture Compression for Mobile

FormatPlatformQualityNotes
ETC2Android (OpenGL ES 3.0+)GoodUniversal Android support
ASTCModern Android + iOS (A8+)ExcellentBest quality/size ratio
PVRTCiOS (older devices)GoodPower of 2 textures only
BC (DXT)Desktop onlyExcellentNot for mobile

Memory Management

graph TD
    Budget["📱 Mobile Memory Budget\n~1.5–3 GB total app limit"]
    Code["Code + Engine\n~100–300 MB"]
    Textures["Textures\n~200–500 MB"]
    Audio["Audio\n~50–150 MB"]
    Meshes["Meshes + Animations\n~50–200 MB"]
    Runtime["Runtime + GC\n~100–300 MB"]
    Budget --> Code
    Budget --> Textures
    Budget --> Audio
    Budget --> Meshes
    Budget --> Runtime
StrategyDescription
Addressables / Asset BundlesLoad/unload assets on demand
Texture streamingLoad lower mip levels first
Audio streamingStream music from disk, load SFX into memory
Scene streamingLoad only visible areas
Avoid texture duplicationShare materials and atlases

Battery Optimization

TechniqueBattery SavingNotes
Cap FPS to 30 or 60Very HighDon’t render at 120 FPS if 60 is fine
Reduce CPU wake-upsHighDon’t poll every frame if not needed
Disable GPS/camera when unusedHighSensors drain battery
Reduce network callsMediumBatch server requests
Lower resolution on low batteryMediumDetect battery level
Pause background processesMediumStop AI when app backgrounded

iOS Platform Features

iOS-Specific Capabilities

FeatureDescriptionUse Case
Game CenterApple’s social gaming platformLeaderboards, achievements, multiplayer matchmaking
Sign in with AppleAuthenticationUser accounts without email
StoreKit 2In-app purchases and subscriptionsMonetization
ARKitAugmented reality frameworkAR games
CoreMotionAccelerometer, gyroscope, pedometerMotion controls
Haptic EnginePrecise haptic feedbackGame feel, UI feedback
MetalApple’s GPU APIHigh-performance rendering
ProMotion120Hz adaptive refreshSmooth gameplay on Pro devices
App ClipsInstant mini-app experienceGame demos without install

iOS Device Tiers (2024)

TierDevicesGPURAMTarget
BudgetiPhone SE 2nd genA133 GBMinimum spec
MidiPhone 13A154 GBStandard target
HighiPhone 15A166 GBHigh quality
ProiPhone 15 ProA17 Pro8 GBMaximum quality
  • }

iOS Haptics (Unity)

    // Trigger haptic via native iOS API
    [System.Runtime.InteropServices.DllImport("__Internal")]
    private static extern void _TriggerHapticFeedback(int style);
    // style: 0=light, 1=medium, 2=heavy, 3=soft, 4=rigid

    public void MediumImpact() => _TriggerHapticFeedback(1);
    public void HeavyImpact()  => _TriggerHapticFeedback(2);
}
#endif
```
// iOS Haptic Feedback — Unity
#if UNITY_IOS
using UnityEngine.iOS;
 
public class HapticManager : MonoBehaviour
{
    // Light tap — UI interactions
    public void LightImpact() {
        Handheld.Vibrate(); // basic
        // For precise haptics use iOS native plugin

Game Center Integration (Unity)

using UnityEngine.SocialPlatforms;
using UnityEngine.SocialPlatforms.GameCenter;
 
public class GameCenterManager : MonoBehaviour
{
    void Start() {
        // Authenticate with Game Center
        Social.localUser.Authenticate(success => {
            if (success) Debug.Log("Game Center: Authenticated");
            else Debug.Log("Game Center: Failed");
        });
    }
 
    // Report score to leaderboard
    public void ReportScore(long score, string leaderboardID) {
        Social.ReportScore(score, leaderboardID, success => {
            Debug.Log("Score reported: " + success);
        });
    }
 
    // Unlock achievement
    public void UnlockAchievement(string achievementID) {
        Social.ReportProgress(achievementID, 100.0, success => {
            Debug.Log("Achievement unlocked: " + success);
        });
    }
 
    // Show leaderboard UI
    public void ShowLeaderboard() {
        Social.ShowLeaderboardUI();
    }
}

Android Platform Features

Android-Specific Capabilities

FeatureDescriptionUse Case
Google Play GamesSocial gaming platformLeaderboards, achievements, cloud saves
Play BillingIn-app purchasesMonetization
ARCoreAugmented realityAR games
Android Game Development KitPerformance toolsProfiling, frame pacing
AGDK Frame PacingSmooth frame deliveryEliminate jank
VulkanLow-level GPU APIHigh-performance rendering
OpenGL ES 3.2Standard GPU APIBroad compatibility
Android Adaptive PerformanceDynamic quality scalingBattery + thermal management
Google Play InstantPlay without installingGame demos

Android Device Fragmentation

TierExample DevicesGPURAMTarget
Low-endSamsung A03, Redmi 9Mali-G522–3 GBMinimum spec
Mid-rangeSamsung A54, Pixel 6aAdreno 6424–6 GBStandard target
High-endSamsung S24, Pixel 8Adreno 7508–12 GBHigh quality
FlagshipSamsung S24 UltraAdreno 75012 GBMaximum quality

Android Frame Pacing (AGDK)

// Android Game Development Kit — Frame Pacing
// Eliminates jank caused by irregular frame delivery
#include "swappy/swappyGL.h"
 
// Initialize Swappy
SwappyGL_init(env, activity);
SwappyGL_setSwapIntervalNS(1000000000L / 60); // 60 FPS
 
// In render loop — replace eglSwapBuffers with:
SwappyGL_swap(display, surface); // handles frame pacing automatically

Android Adaptive Performance (Unity)

using UnityEngine.Android;
 
public class AdaptivePerformanceManager : MonoBehaviour
{
    IAdaptivePerformance ap;
 
    void Start() {
        ap = Holder.Instance;
        if (ap == null || !ap.Active) return;
 
        // Subscribe to thermal warnings
        ap.ThermalStatus.ThermalEvent += OnThermalEvent;
    }
 
    void OnThermalEvent(ThermalMetrics metrics) {
        switch (metrics.WarningLevel) {
            case WarningLevel.NoWarning:
                SetQuality(QualityLevel.High);
                break;
            case WarningLevel.ThrottlingImminent:
                SetQuality(QualityLevel.Medium);
                break;
            case WarningLevel.Throttling:
                SetQuality(QualityLevel.Low);
                break;
        }
    }
 
    void SetQuality(QualityLevel level) {
        switch (level) {
            case QualityLevel.High:
                QualitySettings.SetQualityLevel(2);
                Application.targetFrameRate = 60;
                break;
            case QualityLevel.Medium:
                QualitySettings.SetQualityLevel(1);
                Application.targetFrameRate = 30;
                break;
            case QualityLevel.Low:
                QualitySettings.SetQualityLevel(0);
                Application.targetFrameRate = 30;
                break;
        }
    }
}

Mobile Monetization

Monetization Models

graph TD
    subgraph F2P["💰 Free-to-Play Models"]
        IAP["In-App Purchases\nCosmetics, currency, items"]
        Ads["Advertising\nBanner, interstitial, rewarded"]
        BP["Battle Pass\nSeasonal progression"]
        Sub["Subscription\nMonthly premium access"]
    end
    subgraph Premium["💵 Premium Models"]
        Paid["Paid Download\n$0.99 – $9.99"]
        DLC["DLC / Expansion\nAdditional content"]
        Demo["Free Demo\nPaid full version"]
    end
ModelRevenue PotentialPlayer FrictionBest For
Rewarded adsMediumLow (optional)Casual, hyper-casual
Interstitial adsLow-MediumHigh (forced)Hyper-casual only
Banner adsLowMediumCasual
IAP — cosmeticsHighLowAny genre
IAP — pay-to-winVery HighVery High (ethical issues)Avoid
Battle passHighLowMid-core, live service
SubscriptionMediumLowPremium content
Premium ($2.99+)Low volume, high qualityNoneCore gamers

In-App Purchases (Unity IAP)

using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
 
public class IAPManager : MonoBehaviour, IDetailedStoreListener
{
    IStoreController storeController;
 
    // Product IDs — must match App Store / Play Store
    const string PRODUCT_GEMS_100    = "com.mygame.gems100";
    const string PRODUCT_NO_ADS      = "com.mygame.noads";
    const string PRODUCT_MONTHLY_SUB = "com.mygame.monthly";
 
    void Start() {
        var builder = ConfigurationBuilder.Instance(
            StandardPurchasingModule.Instance());
 
        // Add products
        builder.AddProduct(PRODUCT_GEMS_100,    ProductType.Consumable);
        builder.AddProduct(PRODUCT_NO_ADS,      ProductType.NonConsumable);
        builder.AddProduct(PRODUCT_MONTHLY_SUB, ProductType.Subscription);
 
        UnityPurchasing.Initialize(this, builder);
    }
 
    // Buy a product
    public void BuyGems() {
        storeController.InitiatePurchase(PRODUCT_GEMS_100);
    }
 
    // Called on successful purchase
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
        if (args.purchasedProduct.definition.id == PRODUCT_GEMS_100) {
            GivePlayerGems(100);
        }
        else if (args.purchasedProduct.definition.id == PRODUCT_NO_ADS) {
            DisableAds();
        }
        return PurchaseProcessingResult.Complete;
    }
 
    public void OnInitialized(IStoreController controller,
                               IExtensionProvider extensions) {
        storeController = controller;
    }
 
    public void OnInitializeFailed(InitializationFailureReason error,
                                    string message) {
        Debug.LogError("IAP Init failed: " + error);
    }
 
    public void OnPurchaseFailed(Product product,
                                  PurchaseFailureDescription failure) {
        Debug.LogError("Purchase failed: " + failure.reason);
    }
 
    void GivePlayerGems(int amount) { /* add gems to player */ }
    void DisableAds() { /* set no-ads flag */ }
}

Rewarded Ads (Unity Ads)

using UnityEngine;
using UnityEngine.Advertisements;
 
public class AdsManager : MonoBehaviour, IUnityAdsLoadListener,
                                          IUnityAdsShowListener
{
    [SerializeField] string androidGameID = "1234567";
    [SerializeField] string iosGameID     = "7654321";
    const string REWARDED_AD_UNIT = "Rewarded_Android"; // or iOS
 
    void Start() {
        string gameID = Application.platform == RuntimePlatform.IPhonePlayer
            ? iosGameID : androidGameID;
        Advertisement.Initialize(gameID, testMode: false);
        LoadRewardedAd();
    }
 
    void LoadRewardedAd() {
        Advertisement.Load(REWARDED_AD_UNIT, this);
    }
 
    public void ShowRewardedAd(System.Action onRewardGranted) {
        this.onRewardGranted = onRewardGranted;
        Advertisement.Show(REWARDED_AD_UNIT, this);
    }
 
    System.Action onRewardGranted;
 
    // IUnityAdsShowListener
    public void OnUnityAdsShowComplete(string adUnitId,
        UnityAdsShowCompletionState completionState) {
        if (completionState == UnityAdsShowCompletionState.COMPLETED) {
            onRewardGranted?.Invoke(); // grant reward
        }
        LoadRewardedAd(); // preload next ad
    }
 
    public void OnUnityAdsAdLoaded(string adUnitId) { }
    public void OnUnityAdsFailedToLoad(string id, UnityAdsLoadError e, string msg) { }
    public void OnUnityAdsShowFailure(string id, UnityAdsShowError e, string msg) { }
    public void OnUnityAdsShowStart(string adUnitId) { }
    public void OnUnityAdsShowClick(string adUnitId) { }
}

Ethical Monetization for Mobile

EthicalPredatory
✅ Rewarded ads (optional)❌ Forced interstitials every 2 minutes
✅ Cosmetics only IAP❌ Pay-to-win in competitive modes
✅ Clear pricing❌ Confusing currency conversion
✅ Pity system on gacha❌ Loot boxes targeting children
✅ No-ads purchase option❌ Energy systems forcing waits or payment
✅ Battle pass with earnable currency❌ FOMO timers on purchases

Publishing & App Stores

App Store vs Google Play

AspectApple App StoreGoogle Play Store
Review time1–3 daysHours to 3 days
Review strictnessVery strictModerate
Revenue cut30% (15% for small devs)30% (15% for small devs)
PlatformiOS onlyAndroid only
SideloadingVery restricted (EU exception)Allowed
Developer fee$99/year$25 one-time
Crash reportingXcode OrganizerPlay Console
A/B testingProduct Page OptimizationStore Listing Experiments

App Store Optimization (ASO)

ElementBest Practice
App nameInclude primary keyword (max 30 chars)
Subtitle (iOS)Secondary keywords (max 30 chars)
Keywords field (iOS)Comma-separated, no spaces, no repeats
DescriptionFirst 3 lines most important (above fold)
IconBold, simple, recognizable at small size
ScreenshotsShow gameplay in first 2 screenshots
Preview video15–30 seconds, show core gameplay loop
RatingsPrompt at right moment (after win, not after fail)
LocalizationTranslate to top 5 markets for 3x more downloads

Build & Export Settings

Unity iOS Build Settings:
  Target SDK: Device SDK (not Simulator)
  Architecture: ARM64 (required for App Store)
  Scripting Backend: IL2CPP (required for App Store)
  API Compatibility: .NET Standard 2.1
  Strip Engine Code: Enabled (reduces binary size)
  Managed Stripping Level: Medium

Unity Android Build Settings:
  Target API Level: 34+ (required by Play Store 2024)
  Minimum API Level: 22 (Android 5.1)
  Scripting Backend: IL2CPP
  Target Architecture: ARM64 (required), ARMv7 (optional)
  Build Format: AAB (Android App Bundle) — required by Play Store
  Keystore: Sign with release keystore (never lose this!)

Performance Profiling Tools

ToolPlatformWhat It Profiles
Unity ProfilerAllCPU, GPU, memory, audio, physics
Xcode InstrumentsiOSCPU, GPU, memory, energy
Android GPU InspectorAndroidGPU frame analysis
Android Studio ProfilerAndroidCPU, memory, network, energy
RenderDocAndroid (Vulkan)GPU frame capture
Snapdragon ProfilerQualcomm AndroidAdreno GPU deep analysis
Mali Graphics DebuggerARM AndroidMali GPU analysis

Cross-Platform Development

Engine Export Comparison

EngineiOS ExportAndroid ExportNotes
Unity✅ Excellent✅ ExcellentIndustry standard for mobile
Godot✅ Good✅ GoodFree, improving rapidly
Unreal✅ Good✅ GoodHeavy — best for high-end mobile
Flutter (Flame)✅ Good✅ GoodDart-based, good for 2D
React Native (Expo)✅ Good✅ GoodJS-based, casual games

Platform Detection (Unity)

// Detect platform and adjust behavior
void Start() {
    #if UNITY_IOS
        InitGameCenter();
        SetIOSQuality();
    #elif UNITY_ANDROID
        InitGooglePlayGames();
        SetAndroidQuality();
    #endif
 
    // Runtime detection
    if (Application.isMobilePlatform) {
        EnableTouchControls();
        DisableMouseControls();
        Application.targetFrameRate = 60;
    }
 
    // Screen orientation
    Screen.orientation = ScreenOrientation.LandscapeLeft;
    Screen.sleepTimeout = SleepTimeout.NeverSleep; // prevent screen sleep
}
 
void SetIOSQuality() {
    // iPhone 15 Pro — high quality
    if (SystemInfo.graphicsMemorySize >= 4096) {
        QualitySettings.SetQualityLevel(3);
        Application.targetFrameRate = 60;
    }
    // iPhone SE — low quality
    else {
        QualitySettings.SetQualityLevel(1);
        Application.targetFrameRate = 30;
    }
}

Safe Area (Notch / Dynamic Island)

// Handle iPhone notch, Dynamic Island, Android punch-hole cameras
using UnityEngine;
 
public class SafeAreaHandler : MonoBehaviour
{
    RectTransform rectTransform;
    Rect lastSafeArea;
 
    void Awake() {
        rectTransform = GetComponent<RectTransform>();
        ApplySafeArea();
    }
 
    void ApplySafeArea() {
        Rect safeArea = Screen.safeArea;
        if (safeArea == lastSafeArea) return;
        lastSafeArea = safeArea;
 
        // Convert safe area to anchor min/max
        Vector2 anchorMin = safeArea.position;
        Vector2 anchorMax = safeArea.position + safeArea.size;
        anchorMin.x /= Screen.width;
        anchorMin.y /= Screen.height;
        anchorMax.x /= Screen.width;
        anchorMax.y /= Screen.height;
 
        rectTransform.anchorMin = anchorMin;
        rectTransform.anchorMax = anchorMax;
    }
}

Logseq Graph Connections

  • Related pages:
    • Game Development — core game dev concepts applicable to mobile
    • Game Design — mobile-specific design patterns (session length, core loops, monetization)
    • Game Audio — mobile audio optimization and FMOD/Wwise mobile integration
    • Unity — Unity mobile export, URP mobile, Unity IAP
    • Godot — Godot mobile export and touch input
    • Unreal Engine — Unreal mobile rendering and optimization
    • Advanced Graphics — mobile GPU architecture (tile-based rendering)
    • Free Assets — free mobile game assets and UI kits

More Learn

Official Documentation

Free Learning Resources

Tools

  • GameAnalytics — Free mobile game analytics. Track retention, sessions, revenue.
  • Firebase — Free analytics, crash reporting, A/B testing for mobile games.
  • Adjust — Mobile attribution and analytics.
  • AppFollow — App store review monitoring and ASO tools.