| name | feature-flags-and-configuration |
| description | Feature flags, features registry, and app arguments. Use when gating features behind remote flags (FeatureFlagsConfiguration), feature gating, conditional features, runtime configuration, command-line flags, launch arguments, registering features in FeaturesRegistry, checking or adding app arguments (AppArgs), or implementing feature providers. |
| user-invocable | false |
Feature Flags & Configuration
Sources
docs/feature-flags.md — Runtime feature flag system
docs/features-registry.md — Centralized feature state management
docs/app-arguments.md — Command-line flags and arguments
When to Use Each Mechanism
| Need | Mechanism |
|---|
| Simple remote flag | FeatureFlagsConfiguration.IsEnabled() |
| Flag + app args combined | FeaturesRegistry |
| Runtime-dependent check | IFeatureProvider + FeaturesRegistry |
| Launch-time configuration only | AppArgs.HasFlag() / TryGetValue() |
Feature Flags (Remote)
Fetching
IFeatureFlagsProvider.GetAsync() calls the remote endpoint with:
- User address
- Debug flag
- Referer header
Default endpoint: https://feature-flags.decentraland.org/explorer.json
Naming Convention
- Server side:
explorer-alfa-your-feature
- Codebase:
alfa-your-feature (prefix explorer- is stripped automatically)
Checking Feature Flags
bool enabled = featureFlagsCache.Configuration.IsEnabled("alfa-your-feature");
bool enabled = featureFlagsCache.Configuration.IsEnabled("alfa-your-feature", "my-variant");
bool enabled = FeatureFlagsConfiguration.Instance.IsEnabled(FeatureFlagsStrings.CUSTOM_MAP_PINS_ICONS);
Code Example — Feature Flag Gating
From MapPinLoaderSystem.cs:
public partial class MapPinLoaderSystem : BaseUnityLoopSystem, IFinalizeWorldSystem
{
private readonly bool useCustomMapPinIcons;
public MapPinLoaderSystem(World world, ) : base(world)
{
useCustomMapPinIcons = FeatureFlagsConfiguration.Instance.IsEnabled(
FeatureFlagsStrings.CUSTOM_MAP_PINS_ICONS);
}
protected override void Update(float t)
{
LoadMapPinQuery(World);
UpdateMapPinQuery(World);
HandleComponentRemovalQuery(World);
HandleEntityDestructionQuery(World);
if (useCustomMapPinIcons)
ResolveTexturePromiseQuery(World);
}
}
Variants
Feature flags can carry payload data in three formats:
if (config.TryGetTextPayload("alfa-feature", "variantId", out string? text))
UseText(text);
if (config.TryGetCsvPayload("alfa-feature", "variantId", out List<List<string>>? csv))
UseValues(csv);
if (config.TryGetJsonPayload<MyConfigDto>("alfa-feature", "variantId", out MyConfigDto? dto))
UseConfig(dto);
Configuration Options
var options = new FeatureFlagOptions
{
UserId = userAddress,
URL = flagsEndpoint,
AppName = "explorer",
Hostname = hostname
};
Overridable via app arguments:
--feature-flags-url — Custom endpoint URL
--feature-flags-hostname — Custom hostname
Features Registry (Local)
FeaturesRegistry is a singleton that consolidates feature enable/disable logic from multiple sources: feature flags, app arguments, editor mode, and runtime conditions.
Why FeaturesRegistry exists alongside FeatureFlagsConfiguration: FeatureFlagsConfiguration only handles remote flags. FeaturesRegistry consolidates all sources (remote flags, app args, editor mode, runtime checks) into a single query point, so systems don't need to check multiple sources.
Declaring Features
public enum FeatureId
{
YOUR_FEATURE = 42,
}
Registering Feature States
public void SetFeatureStates(FeatureFlagsCache cache, AppArgs args)
{
SetFeatureState(FeatureId.YOUR_FEATURE,
cache.Configuration.IsEnabled("alfa-your-feature") || args.HasFlag("--enable-feature"));
}
FeaturesRegistry.Instance.SetFeatureState(FeatureId.YOUR_FEATURE, true);
Checking Features
bool enabled = FeaturesRegistry.Instance.IsEnabled(FeatureId.YOUR_FEATURE);
Feature Providers
For runtime-dependent features (e.g., user-specific checks):
public class MyFeatureProvider : IFeatureProvider
{
public FeatureId FeatureId => FeatureId.MY_FEATURE;
public async UniTask<bool> IsFeatureEnabledAsync(CancellationToken ct)
{
return await CheckIfEnabledAsync(ct);
}
}
FeaturesRegistry.Instance.RegisterFeatureProvider(new MyFeatureProvider());
Feature providers should cache values and reset on condition change.
App Arguments
Command-line flags that configure application behavior. Work via command line or deep links.
Usage
# Command line
--flag-name value
# Deep link
decentraland://?flag-name=value
Key Flags by Category
| Category | Flag | Purpose |
|---|
| General | --debug | Enable debug mode |
| General | --hub | Hub mode |
| Environment | --realm | Target realm |
| Environment | --local-scene | Local scene development |
| Environment | --position | Starting position |
| Auth | --skip-auth-screen | Skip authentication |
| Performance | --disable-disk-cache | Disable disk cache |
| Performance | --simulateMemory | Simulate memory pressure |
| Development | --use-log-matrix | Custom log matrix JSON file |
| Development | --launch-cdp-monitor-on-start | Launch CDP monitor |
| Feature Flags | --feature-flags-url | Custom FF endpoint |
| Feature Flags | --feature-flags-hostname | Custom FF hostname |
| Display | --windowed-mode | Force windowed mode |
Accessing in Code
if (appArgs.HasFlag(AppArgsFlags.DEBUG))
EnableDebugMode();
if (appArgs.TryGetValue(AppArgsFlags.REALM, out var realm))
UseRealm(realm);