Design Pattern / Game Programming

[Game Programming] Service Locator Pattern

A pattern that gathers access to shared services into a central registry to reduce coupling at the call site.

  • Design Pattern
  • Game Programming
Contents

One-line pattern summary

A pattern that gathers access to shared services into a central registry to reduce coupling at the call site.

Typical Unity use cases

  • When referencing audio, save, or analytics services globally.
  • When you want to simplify DI in the early stage of development.

Parts (roles)

  • Service Interface
  • Locator Registry
  • Bootstrap Registration

Unity example (C#)

The code below is a simplified Unity example based on the scenario described above.

public interface IAudioService
{
    void PlaySfx(string clipId);
}

public static class GameServices
{
    public static IAudioService AudioService { get; private set; }

    public static void RegisterAudioService(IAudioService audioService)
    {
        AudioService = audioService;
    }
}

public sealed class DamageFeedbackSystem
{
    public void OnHit()
    {
        GameServices.AudioService?.PlaySfx("Hit");
    }
}

Advantages

  • Shared services can be replaced or injected from one place, which speeds up early development.
  • Since callers no longer own creation responsibilities, usage code becomes simpler.

Things to watch out for

  • Hidden global dependencies make test isolation and dependency tracking harder.
  • If initialization order is wrong, runtime null-reference errors can easily occur.

Interaction diagram

This shows the flow where the client looks up a service by interface key and uses it.

flowchart LR

  client["Gameplay System"]
  locator["Service Locator"]
  registry["Service Registry"]
  service["IAudioService Implementation"]
  result["Play SFX"]

  client -- "Resolve<IAudioService>()" --> locator
  locator -->|lookup key| registry
  registry -->|return instance| service
  service -- "Play(soundId)" --> result
  result -->|done| client

Comments