Skip to content

Files

Latest commit

81147f2 · Jan 7, 2025

History

History
82 lines (61 loc) · 3.83 KB

File metadata and controls

82 lines (61 loc) · 3.83 KB

UnityUtil.Configuration.RemoteConfig

< Back to main README

Work in progress!

This repo has been under open-source development since ~2017, but only since late 2022 has it been seriously considered for "usability" by 3rd parties, so documentation content/organization are still in development.

Overview

This project implements a Microsoft.Extensions.Configuration configuration provider for Unity's RemoteConfig service. With it, you can add RemoteConfig settings to your game's configuration with code like the following:

private async Task<IConfigurationRoot> buildConfigurationAsync() {
    IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

    // Add lower-priority configuration sources...

    if (!Application.isEditor || Application.isPlaying) {
        configurationBuilder.AddUnityRemoteConfig(
            new TUser(),
            new TApp(),
            remoteConfigInitializer: remoteCfg => {
                remoteCfg.SetEnvironmentID(/* ... */);
                // Init other RemoteConfig properties
            }
        );
    }

    // Add higher-priority configuration sources...

    return configurationBuilder.Build();
}

Unfortunately, there are some unavoidable issues with the RemoteConfigConfigurationProvider:

  • It cannot load settings by Waiting the Task returned by RemoteConfigService.FetchConfigsAsync, as this would lead to a deadlock with the Unity main thread
  • It cannot load settings in a FetchCompleted listener callback after calling RemoteConfigService.FetchConfigs, as this callback runs at an indeterminate time. The RemoteConfigConfigurationSource constructor could accept a callback and add that as a listener to FetchCompleted, but that breaks the encapsulation/contract of configuration sources. Consumers could also wait for a short time after after building configuration to ensure that FetchCompleted has been triggered, but the amount of time would be arbitrary--either too short or longer than necessary.

As such, development of this package is currently halted until either:

  1. The Microsoft Configuration system supports building configuration asynchronously, or
  2. Unity RemoteConfig supports synchronous fetching without a callback

In the meantime, developers wishing to treat Unity RemoteConfig as an MS configuration source can simply await RemoteConfigService.FetchConfigsAsync() in their initialization logic (e.g., in an async Start method), then pass the fetched configs to IConfigurationBuilder.AddInMemoryCollection() like in the code below. Unity's Task-handling logic will avoid the deadlocks mentioned above.

private async void Start()
{
    IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

    // Add lower-priority configuration sources...

    if (!Application.isEditor || Application.isPlaying) {
        RemoteConfigService.Instance.SetEnvironmentID(/* ... */);
        // Init other RemoteConfig properties
        RuntimeConfig runtimeConfig = await RemoteConfigService.Instance.FetchConfigsAsync(new TUser(), new TApp());
        configurationBuilder.AddInMemoryCollection(
            runtimeConfig.GetKeys().Select(x => KeyValuePair.Create(x, (string?)runtimeConfig.GetString(x)))
        );
    }

    // Add higher-priority configuration sources...

    IConfigurationRoot config = configurationBuilder.Build();
}

Copyright © 2017 - present Dan Vicarel & Contributors. All rights reserved.