/work Mobile Games

A Decade of Mobile Games — Retrospective

What I learned shipping casual, hypercasual, and cooking games across Unity and native mobile platforms.

Role
Game Developer
Period
2014 — 2018
Status
Archived
Unity (C#) Native iOS Native Android Mobile

Scope

A retrospective on shipping loops, device constraints, live operations, and transferable systems judgment

Owned

  • Gameplay and client architecture
  • Mobile performance and device debugging
  • Release, analytics, and live-ops integration

Constraints

  • Wide device and operating-system variation
  • Store release cycles make recovery slower than web deployment
  • Player experience is sensitive to frame time, memory, network, and battery

Decisions

  • Event-driven client boundaries over scene-level coupling
  • Measure on target devices rather than relying on editor performance
  • Treat release and telemetry as part of feature design

Outcome

  • Shipped multiple mobile titles and built the operating discipline used in later platform work

Case study narrative

The systems education hidden inside game development

Mobile games taught me to reason from what the player experiences backward into the system. A frame hitch, a lost purchase, a corrupted save, or a network retry is not an implementation detail to the player—it is the product.

Across casual games, cooking games, platformers, and 3D titles, the technology varied but the engineering loop stayed stable: establish a measurable player experience, build a small vertical slice, test on real devices, instrument failure paths, and release in a form that can be safely observed.

Timeline

Capabilities that compounded

  1. Gameplay foundations

    Unity scenes, input, animation, UI state, persistence, and store integration.

    Learned to ship complete loops, not isolated features.
  2. Reusable client architecture

    Event boundaries, content configuration, analytics, and live tuning across multiple titles.

    Reduced scene coupling and made releases easier to reason about.
  3. Authoritative and transactional systems

    Multiplayer, real-money flows, fairness, retries, and operational evidence.

    Moved from client correctness to distributed invariants.
  4. Platform abstractions

    Shared multiplayer contracts consumed by different game teams.

    Learned to design for other engineers, not only end users.
  5. AI and immersive commerce

    Evaluation, model serving, real-time tracking, and cross-team product contracts.

    Applied the same production discipline around probabilistic systems.
The dates group the main technical chapters rather than listing every individual title.

A practical mobile game architecture

The most maintainable clients separated domain state from scene objects. Scenes were a presentation and lifecycle boundary; game rules, persistence, analytics, and service integrations used explicit interfaces.

System architecture

Event-driven mobile game client

  1. Input/UI Translates touch and interface actions into domain commands Experience boundary
  2. Game state Deterministic rules, progression, timers, and score Domain boundary
  3. Presentation Scene objects, animation, audio, and effects react to state Rendering boundary
  4. Persistence Versioned local state plus recoverable cloud sync Durability boundary
  5. Services Store, analytics, ads, remote config, and backend APIs Integration boundary
Illustrative architecture distilled from shipped game work. It is not source code from a specific title.

An event boundary prevents a purchase callback, animation state, and progression rule from mutating one another directly. It also creates a test seam: domain commands can be replayed without loading a Unity scene.

// Illustrative reducer-style domain boundary.
GameState Apply(GameState state, GameCommand command) {
    return command switch {
        CompleteLevel c => state.With(
            coins: state.Coins + RewardFor(c.LevelId),
            nextLevel: UnlockAfter(c.LevelId)),
        SpendCoins s when state.Coins >= s.Amount => state.With(coins: state.Coins - s.Amount),
        _ => state
    };
}

Device performance and debugging

The Unity editor is not a target device. Real performance work used frame-time distribution, allocation tracking, texture and asset memory, load times, and thermal behavior on representative hardware.

A useful investigation order was:

  1. Reproduce on the slow device class, not only a flagship phone.
  2. Separate CPU, GPU, memory, I/O, and network symptoms.
  3. Inspect spikes by frame phase rather than averaging FPS.
  4. Remove per-frame allocation and accidental asset churn.
  5. Validate the improvement in the same gameplay sequence.
  6. Keep a device-specific regression capture for future releases.

The most common “graphics problem” was often content lifecycle: loading too many assets, retaining objects after scene transition, or allocating in a hot update loop.

Save data and synchronization

Local storage needs a schema version, migration path, and atomic replacement strategy. Cloud synchronization needs conflict policy rather than “last write wins” by accident. For progression systems, commands or monotonic achievements can be safer to merge than complete mutable snapshots.

Tradeoff matrix

Client state synchronization

OptionStrengthsCostsDecision
Local snapshot only Fast, simple, and offline-firstDevice loss and weak cross-device continuityAcceptable for low-value state
Cloud last-write-wins Easy synchronization modelSilent progress loss during concurrent playUse only with explicit constraints
Versioned commands + snapshotChosen Replay, conflict visibility, and recoverable projectionMore schema and migration workPreferred for important progression
The right choice depends on whether the state is cosmetic, recoverable progression, or transaction-sensitive.

Release and live operations

Store release cycles make observability part of feature design. A broken configuration can be fixed remotely; a broken binary may wait through review. Features therefore need kill switches, backward-compatible remote configuration, and analytics that can distinguish discovery, attempt, success, failure, and abandonment.

Analytics events were treated as product contracts. Event names, required fields, and versioning belong in review alongside UI and code because an ambiguous event cannot answer a live-ops question later.

What transferred into AI systems

  • Frame budgets became inference budgets. User perception cares about end-to-end freshness, not one benchmark.
  • Save migrations became model and schema migrations. Version ownership and rollback remain the hard part.
  • Gameplay telemetry became evaluation and observability. Measure the behavior the product depends on.
  • Authoritative state became stable model contracts. Downstream systems should not infer hidden implementation details.
  • Live-ops discipline became staged release discipline. Ship changes in a way that can be observed and reversed.

Bounded proof

The durable output

Shipping
Multiple titles

Worked across complete mobile product loops and store releases.

Constraints
Real devices

Performance, memory, network, and lifecycle were tested where users experienced them.

Transfer
Games → AI

Budgeting, contracts, migrations, telemetry, and rollback carried forward.

The value of the game chapter is the operating discipline it created, not a list of engines and APIs.

The retrospective is not a claim that games and AI are the same domain. It is evidence that disciplined systems work transfers: identify the user-visible invariant, make ownership explicit, measure the difficult path, and build recovery before the first incident demands it.


Want to discuss this work in more detail? Get in touch.

Back to all work