Asset Manifests
Asset manifests let you declare all assets a scene needs upfront, then load them all in parallel with a single call. This is the recommended approach for scenes with multiple assets.
Quick Start
C#
public class LevelAssets : AssetManifest
{
public readonly AssetRef<ITexture> Player = Texture("assets/images/player.png", TextureScaleMode.Nearest);
public readonly AssetRef<ITexture> Tileset = Texture("assets/images/tileset.png", TextureScaleMode.Nearest);
public readonly AssetRef<ISoundEffect> Jump = Sound("assets/audio/jump.wav");
public readonly AssetRef<IMusic> Theme = Music("assets/audio/theme.ogg");
public readonly AssetRef<IFont> HUD = Font("assets/fonts/ui.ttf", size: 20);
}
C#
public class GameScene : Scene
{
private readonly IAssetLoader _assets;
private readonly LevelAssets _manifest = new();
public GameScene(IAssetLoader assets) => _assets = assets;
protected override async Task OnLoadAsync(CancellationToken ct, IProgress<float>? progress = null)
{
// All assets loaded in parallel
await _assets.PreloadAsync(_manifest, cancellationToken: ct);
}
protected override void OnEnter()
{
// Implicit conversion - no .Value needed
_player.Sprite.Texture = _manifest.Player;
Audio.PlayMusic(_manifest.Theme);
}
}
Defining a Manifest
A manifest is a class extending AssetManifest with AssetRef<T> fields:
C#
public class MenuAssets : AssetManifest
{
public readonly AssetRef<ITexture> Logo = Texture("assets/images/logo.png");
public readonly AssetRef<ITexture> Background = Texture("assets/images/menu-bg.png");
public readonly AssetRef<IFont> Title = Font("assets/fonts/title.ttf", size: 48);
public readonly AssetRef<IFont> Body = Font("assets/fonts/body.ttf", size: 16);
public readonly AssetRef<IMusic> MenuTheme = Music("assets/audio/menu.ogg");
}
Static helpers: Texture(), Sound(), Music(), Font()
Preloading
- Loads all
AssetRef<T>fields in parallel - Reports progress as each asset completes
- Assets are safe to use from
OnEnteronwards - Partial failures throw
AggregateException- successfully loaded assets are still cached
AssetRef
AssetRef<T> wraps a loaded asset with implicit conversion:
C#
AssetRef<ITexture> playerRef = Texture("assets/images/player.png");
// After PreloadAsync completes:
ITexture texture = playerRef; // Implicit conversion
ITexture texture = playerRef.Value; // Explicit access
bool loaded = playerRef.IsLoaded; // Check state
Unloading
C#
// Unload a specific manifest (decrements reference counts)
_assets.Unload(_manifest);
// Or let scoped IAssetLoader handle it - automatic on scene unload
Combining with Brine2D.Build
If you use the optional Brine2D.Build package, asset paths are generated as compile-time constants:
C#
public class LevelAssets : AssetManifest
{
public readonly AssetRef<ITexture> Player = Texture(Assets.Images.Player);
public readonly AssetRef<IMusic> Theme = Music(Assets.Audio.Music.Theme);
}
Next Steps
- Loading Assets - Direct loading API reference
- Brine2D.Build - Compile-time asset path generation