Free Ebook cover Mobile Game Development Essentials: Controls, Performance, and Publishing Readiness

Mobile Game Development Essentials: Controls, Performance, and Publishing Readiness

New course

10 pages

Networking and Offline-Friendly Design for Mobile Games

Capítulo 7

Estimated reading time: 5 minutes

+ Exercise

1) Connectivity Patterns: Choosing the Right Contract

Mobile connectivity is not a binary “online/offline” switch. Players move between Wi‑Fi and cellular, enter elevators, hit data caps, or background the app mid-session. Your networking design should start with an explicit contract: what parts of the game must work without a network, what parts degrade gracefully, and what parts require a trusted server.

Offline-first

Concept: The game is fully playable without a connection; network is used to sync progress, fetch optional content, or upload analytics. The local device is the primary source of truth for moment-to-moment play, and the server reconciles later.

  • Best for: single-player progression, puzzle games, narrative games, idle games with local timers (with anti-tamper considerations).
  • Design implications: you need a local save format, a sync queue, conflict resolution rules, and clear “last synced” indicators.
  • Risk: cheating/tampering is easier if rewards are computed locally; mitigate by validating on sync or limiting competitive impact.

Online-required

Concept: The game requires a connection to start and/or continue. The server is authoritative for gameplay state, matchmaking, and rewards.

  • Best for: real-time competitive multiplayer, games with economy integrity requirements, server-driven events.
  • Design implications: you must handle login/session tokens, reconnect flows, and “cannot play right now” messaging that doesn’t feel like a crash.
  • Risk: players in poor connectivity regions churn quickly unless you provide meaningful offline alternatives (tutorial, practice mode, cosmetics preview).

Hybrid (recommended for many mobile games)

Concept: Core play can continue offline (or in a limited mode), but certain features require online: PvP, cloud saves, leaderboards, store purchases, time-limited events.

  • Best for: most free-to-play and live-ops games.
  • Design implications: define “offline-safe” actions (e.g., play a level, earn soft currency) vs “online-gated” actions (e.g., spend premium currency, claim event rewards).

Step-by-step: Define your connectivity contract

  1. List features (play session, rewards, purchases, social, PvP, events, cloud save).
  2. Assign a mode to each feature: offline-safe, online-optional, online-required.
  3. Define sources of truth: local authoritative, server authoritative, or “local until synced.”
  4. Define failure behavior: what happens if a request fails mid-action (retry, queue, rollback, or block).
  5. Document player-facing rules (e.g., “Progress saves locally; sync happens automatically when online”).

2) Handling Interruptions: Calls, Notifications, Suspend/Resume

On mobile, interruptions are normal: phone calls, notifications, OS permission prompts, switching apps, low-memory kills, and quick lock/unlock cycles. Treat every interruption as a potential “power loss” event: assume you may not get another frame to clean up.

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

Common interruption scenarios

  • Transient overlay: notification shade, quick settings, incoming call UI; app may pause rendering/audio but remain in memory.
  • Backgrounding: user switches apps; OS may suspend updates and network callbacks.
  • Process death: OS kills the app to reclaim memory; you may only get a short callback (or none) before termination.
  • Network drop during background: sockets close; requests fail; session tokens may expire.

State-saving goals

  • Atomicity: saves should not corrupt if interrupted mid-write.
  • Idempotency: replaying queued actions after resume should not double-grant rewards.
  • Minimal critical state: save the smallest set needed to restore the session safely.

Step-by-step: Safe local save pattern (atomic snapshot)

  1. Define a “critical snapshot” struct: level/scene id, player position (if needed), inventory/currencies, pending rewards, pending network operations, timestamp, version.
  2. Serialize to a temporary file (e.g., save.tmp), then fsync/flush if available.
  3. Rename/replace temp to save.dat (atomic replace on most platforms).
  4. Keep a backup (e.g., save.bak) and rotate on successful writes.
  5. On load, validate checksum/version; if corrupted, fall back to backup.
// Pseudocode (engine-agnostic) for atomic save
function SaveSnapshot(snapshot):
  bytes = Serialize(snapshot)
  checksum = CRC32(bytes)
  envelope = { version: 3, checksum: checksum, payload: bytes }

  WriteFile("save.tmp", Serialize(envelope))
  FlushToDisk("save.tmp")
  ReplaceFile("save.tmp", "save.dat")
  CopyFile("save.dat", "save.bak")

function LoadSnapshot():
  for path in ["save.dat", "save.bak"]:
    if FileExists(path):
      env = Deserialize(ReadFile(path))
      if env.version supported and CRC32(env.payload) == env.checksum:
        return Deserialize(env.payload)
  return NewGameSnapshot()

Step-by-step: Pause/resume handling checklist

  • On pause/background:
    • Stop time-sensitive gameplay loops (timers, physics, AI) or switch to deterministic “paused” state.
    • Mute/duck audio appropriately.
    • Trigger immediate snapshot save if the player is mid-level or mid-transaction.
    • Freeze outgoing network actions; mark in-flight requests as “unknown outcome” until confirmed.
  • On resume/foreground:
    • Re-check connectivity and authentication state (token freshness).
    • Reconcile in-flight operations: query server for last known state if needed.
    • Resume gameplay only after critical state is consistent (local + server expectations).

Handling “unknown outcome” transactions

A classic failure: the player taps “Open Chest,” you send a request, then the app backgrounds. On resume, you don’t know if the server granted rewards. The fix is to make reward grants server-confirmed and idempotent.

  • Assign each action a unique operationId (UUID).
  • Server stores processed operationIds and returns the same result if repeated.
  • Client can safely retry after resume without double-granting.
// Client-side operation queue item
{ operationId: "550e8400-e29b-41d4-a716-446655440000",
  type: "OpenChest",
  params: { chestId: "gold_01" },
  state: "Pending" }

3) Data Usage and Latency Awareness

Mobile players notice delays and data drain quickly. Design for high latency, jitter, packet loss, and metered networks. Your goal is to reduce payload size, reduce request frequency, and make failures recoverable.

Lightweight payloads

  • Send deltas, not full state: transmit only what changed (e.g., “+50 coins” rather than full inventory blob).
  • Prefer compact formats: JSON is convenient but verbose; consider binary formats for frequent messages (while keeping debuggability in mind).
  • Batch requests: combine multiple small events into one upload (e.g., end-of-level summary).
  • Avoid chatty polling: use longer intervals, server push where feasible, or “refresh on demand.”

Retry, backoff, and timeouts

Retries must be deliberate: aggressive retries can spike data usage and battery, and can overload your backend during outages.

  • Timeouts: set per-request timeouts; don’t let requests hang indefinitely.
  • Exponential backoff: wait longer after each failure (e.g., 1s, 2s, 4s, 8s) with a max cap.
  • Jitter: randomize wait times slightly to prevent “thundering herd” when many devices reconnect.
  • Retry only safe operations: retries should be limited to idempotent requests or those using operationIds.
// Backoff with jitter (pseudocode)
base = 1.0
cap = 30.0
attempt = n
wait = min(cap, base * (2 ^ attempt))
wait = wait * RandomRange(0.7, 1.3)
ScheduleRetryAfter(wait)

Caching and sync queues

Caching reduces repeated downloads (configs, cosmetics metadata, event definitions). A sync queue stores player actions locally and uploads when connectivity is available.

  • Cache with versioning: store etag/lastModified or a content version number; only refetch when changed.
  • Separate “must be fresh” vs “can be stale”: store prices and entitlements as must-be-fresh; store cosmetic catalogs as can-be-stale.
  • Queue size limits: cap queued events; if exceeded, compress/summarize (e.g., keep only last known state) to avoid unbounded growth.

Latency-aware gameplay patterns

  • Client prediction (carefully): for real-time actions, show immediate feedback locally, then reconcile with server results.
  • Graceful degradation: if ping is high, reduce reliance on tight timing windows or switch to asynchronous modes.
  • Asynchronous confirmations: show “Reward pending sync” states when offline, and finalize when confirmed.
FeatureLatency ToleranceSuggested Pattern
Real-time PvPLowServer authoritative + prediction + reconciliation
Co-op asyncMediumTurn-based / snapshot uploads
Single-player rewardsHighLocal grant + queued validation (or server grant on sync)
Store purchasesMediumServer confirmation + idempotent receipt processing

4) Security Basics (Conceptual): Trust, Tampering, and Authority

Mobile clients are not trusted environments. Players can modify local files, intercept traffic on compromised devices, or automate inputs. Security is not about making cheating impossible; it’s about making it hard enough and ensuring competitive modes remain fair.

Key concepts

  • Client is untrusted: anything computed purely on-device can be forged (currency, cooldowns, win results).
  • Server authority: for competitive or economy-critical actions, the server decides outcomes and stores the canonical state.
  • Defense in depth: combine multiple checks (validation, rate limits, anomaly detection) rather than relying on one trick.

Tampering risks to plan for

  • Save file edits: changing currency amounts, unlocking items.
  • Time manipulation: changing device clock to skip timers.
  • Request replay: resending a “grant reward” request multiple times.
  • Man-in-the-middle on compromised networks/devices: attempting to alter requests/responses.

Practical design responses (without deep crypto)

  • Move critical calculations server-side: PvP results, ranked rewards, premium currency balances, purchase entitlements.
  • Use operationIds and server-side deduplication: prevents replay/double-grant.
  • Validate inputs: server checks that actions are possible (e.g., player owns chest, has enough currency, cooldown elapsed by server time).
  • Prefer server time: treat client time as a hint; use server timestamps for cooldowns/events.
  • Secure transport: use HTTPS/TLS; avoid sending secrets in plaintext; keep tokens short-lived.
  • Rate limiting and anomaly flags: detect impossible progression speed or excessive requests.

Authority model examples

  • Competitive mode: server authoritative simulation or server-validated inputs; client renders and predicts.
  • Offline single-player: local authoritative for fun, but online sync validates and may cap what can be carried into competitive/economy systems.
  • Hybrid economy: soft currency can be earned offline with limits; premium currency and purchases always server authoritative.

5) User Messaging Patterns: Errors Without Breaking Immersion

Network errors are part of the experience; how you communicate them determines whether players feel respected or frustrated. Good messaging is specific, actionable, and in-world when possible, while still being honest.

Principles for network-related UI

  • Separate “can’t reach server” from “server says no”: connectivity vs authorization vs validation errors.
  • Offer a next step: Retry, Play Offline, Reconnect, or Contact Support (with an error code).
  • Don’t punish with sudden loss: if possible, keep the player in a safe state (pause, practice mode, local-only play).
  • Use progressive disclosure: show a simple message first; allow expanding details (ping, status, error code) for troubleshooting.

Immersion-friendly patterns

  • Diegetic framing: “Signal lost” or “Connection unstable” can fit many themes, but avoid misleading roleplay if it hides real constraints.
  • Soft interruptions: small banner/toast for transient issues; modal dialogs only when the player must decide.
  • Stateful indicators: a subtle icon for offline mode, plus “Last synced: 2m ago.”

Error taxonomy and recommended responses

Error TypePlayer MessageRecommended UI Action
Transient timeout“Reconnecting…”Auto-retry with backoff; allow Cancel
No internet“You’re offline. Progress will sync when you’re back online.”Continue offline-safe play; show sync queue count
Auth expired“Session expired. Please sign in again.”Re-auth flow; preserve local state
Server maintenance“Servers are down for maintenance.”Show ETA if available; offer offline modes
Conflict on sync“We found progress from another device.”Guided choice or merge rules; show timestamps
Purchase verification pending“Purchase pending verification.”Lock item until confirmed; background retry

Step-by-step: Designing a “safe retry” dialog

  1. State what happened in one sentence (no jargon): “We couldn’t reach the server.”
  2. State impact: “Your rewards are saved and will sync later.” or “This mode requires online.”
  3. Offer primary action: Retry (with spinner and backoff).
  4. Offer secondary action: Play Offline or Return to Menu.
  5. Include a small error code for support (e.g., NET-102) and log it internally.

Step-by-step: Keeping immersion during disconnects in online-required modes

  1. Freeze gameplay immediately and show a small “Reconnecting” overlay (avoid kicking to menu instantly).
  2. Set a reconnect window (e.g., 10–30 seconds) with visible countdown if appropriate.
  3. Attempt resume using session resumption tokens; rejoin match if supported.
  4. If reconnect fails, transition to a results screen that explains what was preserved (ranked loss policy, rewards policy) and provides a single clear next action.

Now answer the exercise about the content:

When designing mobile game transactions that may be interrupted (e.g., the app backgrounds mid-request), which approach best prevents rewards from being granted twice after the player resumes and retries?

You are right! Congratulations, now go to the next page

You missed! Try again.

Interruptions can create “unknown outcome” requests. Using a unique operationId and server-side deduplication makes the action idempotent, so retrying after resume won’t double-grant rewards.

Next chapter

Mobile Monetization Models: Conceptual Implementation and UX Ethics

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.
  • Read this course in the app to earn your Digital Certificate!
  • Listen to this course in the app without having to turn on your cell phone screen;
  • Get 100% free access to more than 4000 online courses, ebooks and audiobooks;
  • + Hundreds of exercises + Educational Stories.