What's New in v0.9.5-beta¶
Release Date: 2026 Target Framework: .NET 10
v0.9.5-beta is a comprehensive API refinement pass. Startup, hosting, ECS, and the asset pipeline have been reworked for consistency and simplicity. The package model has been consolidated into a single Brine2D package.
Highlights¶
Single Package Model¶
The Brine2D and Brine2D.SDL packages have been consolidated into a single Brine2D package. SDL3 backends are registered automatically — no manual AddSDL3Rendering(), AddSDL3Input(), or AddSDL3Audio() calls.
<!-- Before (v0.9.0) -->
<PackageReference Include=""Brine2D"" Version=""0.9.0-beta"" />
<PackageReference Include=""Brine2D.SDL"" Version=""0.9.0-beta"" />
<!-- After (v0.9.5) -->
<PackageReference Include=""Brine2D"" Version=""0.9.5-beta"" />
Simplified Builder API¶
// Before (v0.9.0)
builder.Services.AddSDL3Rendering(options =>
{
options.WindowTitle = ""My Game"";
options.WindowWidth = 1280;
options.VSync = true;
});
builder.Services.AddSDL3Input();
builder.Services.AddSDL3Audio();
builder.Services.AddScene<GameScene>();
// After (v0.9.5)
builder.Configure(options =>
{
options.Window.Title = ""My Game"";
options.Window.Width = 1280;
options.Rendering.VSync = true;
});
builder.AddScene<GameScene>();
Nested Options¶
Configuration is now organized into nested option classes:
| Before (flat) | After (nested) |
|---|---|
options.WindowTitle |
options.Window.Title |
options.WindowWidth |
options.Window.Width |
options.WindowHeight |
options.Window.Height |
options.VSync |
options.Rendering.VSync |
options.PreferredGPUDriver |
options.Rendering.PreferredGPUDriver |
Framework Properties¶
Scene framework services are now automatic properties instead of constructor-injected:
// Before (v0.9.0)
public class GameScene : Scene
{
private readonly IRenderer _renderer;
private readonly IInputContext _input;
public GameScene(IRenderer renderer, IInputContext input, ILogger<GameScene> logger)
: base(logger)
{
_renderer = renderer;
_input = input;
}
}
// After (v0.9.5)
public class GameScene : Scene
{
// Logger, Renderer, Input, Audio, Game, World — all automatic properties
// Only inject YOUR services
public GameScene(IAssetLoader assets) => _assets = assets;
protected override void OnUpdate(GameTime gameTime)
{
if (Input.IsKeyPressed(Key.Escape)) Game.RequestExit();
}
}
Reworked Asset Pipeline¶
IAssetLoader is now the unified service for all asset types with ref-counted caching and scoped lifetime:
GetOrLoadTextureAsync/GetOrLoadSoundAsync/GetOrLoadMusicAsync/GetOrLoadFontAsyncAssetManifestwithPreloadAsyncfor parallel loading- Scoped per scene — assets released automatically on unload
- Reference counting for shared assets across manifests
ECS Refinements¶
Componentnow only hasOnAdded/OnRemovedhooks (noOnUpdate)Behaviorhandles per-entity logic with DI supportEntity.Idislong(notGuid)- Systems are optional — recommended only when profiling shows a need
Scene Lifecycle¶
- Removed
OnInitializeAsync/OnInitialize OnLoadAsyncnow acceptsIProgress<float>?parameter for loading screen progressOnExitis now the correct place for main-thread cleanup (notOnUnloadAsync)Renderer,Input,Audioare not available duringOnUnloadAsync
Breaking Changes¶
| Area | Before (v0.9.0) | After (v0.9.5) |
|---|---|---|
| Packages | Brine2D + Brine2D.SDL |
Single Brine2D package |
| Builder | builder.Services.AddSDL3Rendering(...) |
builder.Configure(...) |
| Scenes | builder.Services.AddScene<T>() |
builder.AddScene<T>() |
| Options | Flat (options.WindowTitle) |
Nested (options.Window.Title) |
| Scene ctor | base(logger) required |
No base call needed |
| Scene services | Constructor-injected IRenderer, etc. |
Automatic framework properties |
| Lifecycle | OnInitializeAsync existed |
Removed — use OnLoadAsync |
| Lifecycle | OnLoadAsync(ct) |
OnLoadAsync(ct, progress?) |
| Input enum | Keys |
Key |
| Component | Had OnUpdate(GameTime) |
Only OnAdded / OnRemoved |
| Entity.Id | Guid |
long |
| Scene transition | LoadSceneAsync (async) |
LoadScene (void, fire-and-forget) |
Migration Guide¶
1. Update Package Reference¶
<!-- Remove Brine2D.SDL, keep only Brine2D -->
<PackageReference Include=""Brine2D"" Version=""0.9.5-beta"" />
2. Update Program.cs¶
// Replace AddSDL3* calls with builder.Configure
builder.Configure(options =>
{
options.Window.Title = ""My Game"";
options.Window.Width = 1280;
options.Window.Height = 720;
options.Rendering.VSync = true;
});
// Replace builder.Services.AddScene with builder.AddScene
builder.AddScene<GameScene>();
// Add await using
await using var game = builder.Build();
3. Update Scene Constructors¶
Remove IRenderer, IInputContext, ILogger, IAudioPlayer, IGameContext from constructors. Remove : base(logger) calls. Use framework properties instead.
4. Replace Keys with Key¶
Find and replace Keys. with Key. throughout.
5. Replace IInputService with IInputContext¶
If referencing the input interface directly, update to IInputContext.
6. Update Component Subclasses¶
Move any OnUpdate logic from components into Behavior subclasses.