Engineering case study

Pro Golf — Progressive Personalisation Loading for a Live Unity Product

Architecture and asset-lifecycle work for a content-heavy personalisation system where responsiveness, memory residency, and download size competed with one another.

Project role
Senior Software Engineer
Scope
Personalisation module
Team context
Architecture reviewed by my lead
Platform
Mobile (iOS)
Context
Live Unity product

Architected a production personalisation module that balanced large animated avatar content, API-driven inventory state, Addressables, progressive loading, memory residency, and perceived responsiveness across a live Unity product.

  • Architecture
  • Addressables
  • Memory
  • Progressive Loading
Context

Heavy identity content in a live mobile product

Pro Golf included a substantial personalisation experience around avatars and other player identity content. The system had to connect API/inventory state with Unity UI and large visual assets while remaining responsive on mobile hardware.

Animated avatar content was particularly expensive: an avatar could have multiple idle, win, and lose animations. Treating all of that content as an always-loaded package would increase download time and memory residency.

Ownership

My responsibility

I architected and implemented the Personalisation module, with the architecture reviewed by my lead. My ownership included the Unity-side UI architecture, services/data flow, API/DTO integration, asset catalog and Addressables behavior, and the progressive loading strategy for heavy animated content.

What I owned

  • Personalisation module architecture and implementation
  • Unity-side UI architecture
  • Services/data flow and API/DTO integration
  • Asset catalog and Addressables behavior
  • Progressive loading strategy for heavy animated content

Review

  • The module architecture was reviewed by my lead.
Architecture

Separating presentation, state, and assets

The module has two related paths: a code path that keeps UI independent of API details, and an asset path that decides what content is resident at any time.

Conceptual code path
  1. UI / View
  2. Presenter
  3. Facade
  4. Services / DTO data
  5. API / backend integration
Conceptual asset path
  1. Personalisation metadata
  2. Preview imageshown immediately
  3. First playable animation
  4. Progressive background downloadsremaining animations
  5. Release / unloadbased on navigation

Architecture themes

  • MVP, interfaces, and a facade over services
  • Dependency injection to supply dependencies; services, interfaces, facades, and events provide the collaboration boundaries
  • DTO/API integration
  • ScriptableObject-authored/catalog data where appropriate
  • Addressables
Engineering problem 01

Make heavy personalisation feel immediate

Waiting for every animation asset before showing the selected avatar would create a poor user experience. Keeping every animation resident would create a memory problem.

The loading strategy therefore prioritized perceived responsiveness. A lightweight preview/still image could appear immediately. The system then downloaded enough content to begin animation playback, while additional animations continued loading progressively in the background.

Key tradeoff

First-use responsiveness vs. content completeness vs. memory/download cost.

Engineering problem 02

Use navigation time as preload time

The product flow gave the system opportunities to prepare content before the user reached Personalisation. During navigation such as Home → Wallet → Personalisation, the intermediate screen could be used as a background preload window.

The reverse path was also meaningful: moving away from Personalisation toward Home provided a point where heavy content could be released rather than allowed to accumulate in memory.

Navigation-aware preloading
  1. Home
  2. Walletbackground preload window
  3. Personalisationcontent ready or arriving

On the way back toward Home, heavy content can be released instead of accumulating in memory.

This made asset lifecycle part of navigation architecture rather than a collection of isolated LoadAssetAsync calls.

Engineering problem 03

Keep API/player state separate from presentation

Personalisation state depended on player inventory, purchases, catalog metadata, and backend/API responses. The module used presenters, a facade, services, interfaces, and DTO boundaries so that UI behavior did not become tightly coupled to API implementation details.

That separation also made the system easier to integrate into other product surfaces such as tournaments and leaderboards.

Implementation

Implementation highlights

  • Player inventory/purchase state
  • DTO/API communication
  • Avatar/banner/title-style personalisation content
  • Addressables-based asset loading
  • Preview-first rendering
  • Progressive animation loading
  • Navigation-aware preloading
  • Explicit release/unload behavior
  • Cross-product integration
  • MVP / facade / services / interfaces / DI
Outcome

Outcome

The system provided a production architecture for content-heavy personalisation while balancing responsiveness, memory residency, and asset download cost.

Reflection

Asset loading is a product decision

The important lesson was that asset loading is a product-design problem as much as a technical one. The best loading strategy depended on where the user was going, what they needed to see immediately, and what content could safely arrive later or leave memory entirely.

Media

Media & external evidence

Pro Golf promotional artwork
Pro Golf product artwork.