Skip to content

What's New in v0.9.0-beta

Release Date: January 2026
Target Framework: .NET 10

Brine2D v0.9.0-beta is a major release with significant improvements to architecture, performance, and developer experience. This version introduces package separation, .NET 10 support, track-based audio, and comprehensive performance monitoring.


Highlights

Package Separation

Brine2D is now consolidated into two packages for better modularity:

Brine2D (Core Package) - ECS system - Scene management - Core abstractions - Performance monitoring

Brine2D.SDL (SDL3 Implementation) - SDL3 rendering - SDL3 input - SDL3 audio - SDL3 window management

// Updated package references
<ItemGroup>
  <PackageReference Include="Brine2D" Version="0.9.0-beta" />
  <PackageReference Include="Brine2D.SDL" Version="0.9.0-beta" />
</ItemGroup>

Migration:

// Before (v0.8.0)
using Brine2D;
using Brine2D.Rendering;
using Brine2D.Input;

// After (v0.9.0)
using Brine2D.Core;
using Brine2D.Engine;
using Brine2D.SDL;  // For SDL3 implementations

Track-Based Audio System

New track-based audio API replaces channel-based system:

New Features: - Track handles for precise control - Spatial audio updates - Track lifecycle events - Better memory management

// Play sound and get track handle
nint track = _audio.PlaySoundWithTrack(_shootSound, volume: 0.8f);

// Update spatial audio
_audio.UpdateTrackSpatialAudio(track, volume: 0.6f, pan: 0.5f);

// Stop specific track
_audio.StopTrack(track);

// Track finished event
_audio.OnTrackStopped += (track) => 
{
    Logger.LogInformation("Track {Track} finished", track);
};

Breaking Change: Channel methods removed: - ❌ StopChannel(int) - ❌ PauseChannel(int) - ❌ IsChannelPlaying(int) - ✅ Use PlaySoundWithTrack() and StopTrack(nint) instead


Performance Monitoring

Built-in performance overlay and profiling:

Features: - Real-time FPS counter - Frame time graph - Memory statistics (GC generations) - Rendering statistics - Batch efficiency tracking

// Enable performance monitoring
builder.Services.AddPerformanceMonitoring(options =>
{
    options.EnableOverlay = true;
    options.ShowFPS = true;
    options.ShowFrameTime = true;
    options.ShowMemory = true;
});

Keyboard Shortcuts: - F1 - Toggle overlay visibility - F3 - Toggle detailed stats

See Performance Monitoring guide.


GPU Renderer Improvements

GPU renderer is now the default with major enhancements:

Improvements: - Automatic draw call batching - Better memory management - Improved texture streaming - Render target support - Cross-platform consistency

// GPU renderer is now default (no configuration needed)
builder.Services.AddSDL3Rendering(options =>
{
    options.WindowTitle = "My Game";
    options.VSync = true;
    // Backend = GPU by default
});

// Explicitly use legacy renderer if needed
builder.Services.AddSDL3Rendering(options =>
{
    options.Backend = GraphicsBackend.LegacyRenderer;
});

New Features

ECS Enhancements

Multi-Threading Support - Parallel entity processing - Thread-safe collections - Synchronization primitives - Performance optimizations

// Process entities in parallel
var entities = world.QueryEntities()
    .With<TransformComponent>()
    .ToList();

Parallel.ForEach(entities, entity =>
{
    var transform = entity.GetComponent<TransformComponent>();
    transform.Position += velocity * deltaTime;
});

See ECS Multi-Threading guide.


Query Improvements - Better query caching - Improved performance - Cleaner API

// Cached queries for better performance
var enemyQuery = world.CreateCachedQuery<EnemyComponent, TransformComponent>();

// Use cached query each frame
foreach (var entity in enemyQuery.Execute())
{
    // Process enemy
}

Rendering Enhancements

Post-Processing Effects - Render-to-texture pipeline - Screen shake effect - Vignette effect - Custom shader support

// Render to texture for post-processing
_renderTarget = await _renderer.CreateRenderTargetAsync(1280, 720, ct);

_renderer.SetRenderTarget(_renderTarget);
RenderScene();

_renderer.SetRenderTarget(null);
ApplyPostProcessing(_renderTarget);

See Post-Processing guide.


Texture Atlasing - Automatic sprite batching - Reduced draw calls - Better performance

// Texture atlas support
public class TextureAtlas
{
    private readonly ITexture _atlas;
    private readonly Dictionary<string, Rectangle> _regions;

    public void DrawSprite(string name, Vector2 position)
    {
        if (_regions.TryGetValue(name, out var region))
        {
            _renderer.DrawTexture(_atlas, 
                position.X, position.Y,
                region.Width, region.Height);
        }
    }
}

Input Improvements

Gamepad Support Enhancements - Hot-plug detection - Multiple controller support - Better button mapping - Rumble/vibration support

// Check gamepad connection
if (_input.IsGamepadConnected(0))
{
    var leftStick = _input.GetGamepadLeftStick(0);
    var rightTrigger = _input.GetGamepadRightTrigger(0);

    // Rumble on action
    if (_input.IsGamepadButtonPressed(0, GamepadButton.A))
    {
        _input.RumbleGamepad(0, 0.5f, 0.5f, 200);
    }
}

Mouse Enhancements - Cursor control (show/hide/lock) - Mouse delta for camera control - Scroll wheel support - Better coordinate system

// Lock cursor for FPS games
_input.SetRelativeMouseMode(true);
_input.SetCursorVisible(false);

// Use mouse delta for camera
var delta = _input.GetMouseDelta();
_cameraYaw += delta.X * sensitivity;

Scene Management

Transition Effects - Built-in transition system - Fade in/out - Custom transitions - Async transition support

// Scene transition with fade
await _sceneManager.TransitionToAsync<GameScene>(
    new FadeTransition(duration: 0.5f));

Audio Improvements

Spatial Audio - Stereo panning - Distance attenuation - 3D positional audio - Real-time updates

// Play sound with spatial audio
nint track = _audio.PlaySoundWithTrack(
    _sound,
    volume: 1.0f,
    pan: -0.5f); // Left channel

// Update spatial audio in real-time
_audio.UpdateTrackSpatialAudio(track, volume: 0.8f, pan: 0.2f);

Breaking Changes

Package Structure

Changed: Namespace reorganization

// ❌ Old (v0.8.0)
using Brine2D;
using Brine2D.Rendering;
using Brine2D.Input;

// ✅ New (v0.9.0)
using Brine2D.Core;
using Brine2D.Engine;
using Brine2D.Rendering;
using Brine2D.Input;
using Brine2D.SDL;  // For SDL3 implementations

Migration: Update namespace imports in all files.


Audio System

Removed: Channel-based API

// ❌ Old (v0.8.0)
_audio.StopChannel(5);
_audio.PauseChannel(5);
bool playing = _audio.IsChannelPlaying(5);

// ✅ New (v0.9.0)
nint track = _audio.PlaySoundWithTrack(_sound);
_audio.StopTrack(track);
// Track lifecycle via OnTrackStopped event

Migration: Replace channel calls with track-based API.


Rendering

Changed: Backend enum values

// ❌ Old (v0.8.0)
options.Backend = RenderingBackend.SDL3GPU;
options.Backend = RenderingBackend.SDL3Legacy;

// ✅ New (v0.9.0)
options.Backend = GraphicsBackend.GPU;
options.Backend = GraphicsBackend.LegacyRenderer;

Migration: Update backend configuration.


Service Registration

Changed: Extension method names

// ❌ Old (v0.8.0)
builder.Services.AddSDLRendering();
builder.Services.AddSDLInput();
builder.Services.AddSDLAudio();

// ✅ New (v0.9.0)
builder.Services.AddSDL3Rendering();
builder.Services.AddSDL3Input();
builder.Services.AddSDL3Audio();

Migration: Update service registration calls.


Improvements

Performance

Optimizations: - 30% faster entity queries - 50% reduction in memory allocations - Better sprite batching (10x+ efficiency) - Improved texture management

Benchmarks (10,000 entities):

Operation v0.8.0 v0.9.0 Improvement
Entity Query 2.5ms 1.7ms 32% faster
Sprite Rendering 5.0ms 2.8ms 44% faster
Memory Allocations 500 KB/frame 250 KB/frame 50% less

Developer Experience

Improvements: - Better error messages - Improved logging - More examples and samples - Comprehensive documentation

// Better error messages
// Before: "Failed to load texture"
// After: "Failed to load texture 'assets/sprite.png': File not found"

Documentation

New Guides: - Performance Monitoring - Post-Processing Effects - ECS Multi-Threading - Gamepad Input - Texture Atlasing - Spatial Audio

Updated: - All code examples to v0.9.0 - API references - Migration guides


Bug Fixes

Critical

  • Fixed memory leak in texture loading
  • Fixed race condition in entity destruction
  • Fixed audio crackling on some hardware
  • Fixed gamepad disconnect handling

Important

  • Fixed sprite flickering with VSync disabled
  • Fixed incorrect mouse position on scaled windows
  • Fixed scene transition memory leak
  • Fixed GC pressure from frequent queries

Minor

  • Fixed logging in release builds
  • Fixed window resize events
  • Fixed music looping edge case
  • Fixed keyboard key repeat rate

Deprecations

Deprecated (will be removed in v1.0.0):

// Deprecated channel methods (use track-based API)
[Obsolete("Use PlaySoundWithTrack() instead")]
void PlaySound(ISoundEffect sound, int channel);

// Deprecated rendering backend names
[Obsolete("Use GraphicsBackend.GPU instead")]
RenderingBackend SDL3GPU;

Migration Guide

Step 1: Update Package References

<!-- Before -->
<PackageReference Include="Brine2D" Version="0.8.0-beta" />

<!-- After -->
<PackageReference Include="Brine2D" Version="0.9.0-beta" />
<PackageReference Include="Brine2D.SDL" Version="0.9.0-beta" />

Step 2: Update Namespaces

// Add new namespaces
using Brine2D.Core;
using Brine2D.Engine;
using Brine2D.SDL;  // For SDL3 implementations

// Remove old namespaces if needed
// using Brine2D; // May still work but update to specific namespaces

Step 3: Update Service Registration

// Update extension method names
builder.Services.AddSDL3Rendering(options => { ... });
builder.Services.AddSDL3Input();
builder.Services.AddSDL3Audio();

Step 4: Update Audio Code

// Replace channel-based API with track-based API
// Before:
// _audio.PlaySound(_sound, channel: 5);

// After:
nint track = _audio.PlaySoundWithTrack(_sound);

// Store track handle if you need to stop it later
_activeTracks.Add(track);

// Subscribe to track stopped event
_audio.OnTrackStopped += HandleTrackStopped;

Step 5: Update Rendering Backend

// Update backend enum
builder.Services.AddSDL3Rendering(options =>
{
    options.Backend = GraphicsBackend.GPU;  // Updated enum name
});

Step 6: Test Thoroughly

Test: - Audio playback and control - Rendering and sprite batching - Input handling (keyboard, mouse, gamepad) - Scene transitions - Performance metrics


Known Issues

Windows

  • GPU Renderer: Requires Windows 10 or later for D3D12
  • High DPI: Some scaling issues on 4K displays (workaround available)

Linux

  • Audio: Pulseaudio required for audio playback
  • Gamepad: May require manual controller mapping for some devices

macOS

  • Metal: Requires macOS 10.14 (Mojave) or later
  • Permissions: May need to grant microphone permission for audio

Workarounds available in documentation.


Performance Tips

Enable Performance Monitoring

#if DEBUG
builder.Services.AddPerformanceMonitoring(options =>
{
    options.EnableOverlay = true;
    options.ShowDetailedStats = true;
});
#endif

Use Cached Queries

// Cache queries for better performance
var enemyQuery = world.CreateCachedQuery<EnemyComponent, TransformComponent>();

// Reuse cached query each frame
foreach (var entity in enemyQuery.Execute())
{
    ProcessEnemy(entity);
}

Enable Sprite Batching

// GPU renderer enables batching automatically
// For best results, use texture atlases
builder.Services.AddSDL3Rendering(options =>
{
    options.Backend = GraphicsBackend.GPU;  // Automatic batching
    options.VSync = true;
});

Community

Resources: - GitHub Repository - Documentation - Discord Community - Issue Tracker

Contributing: - Report bugs and issues - Submit pull requests - Improve documentation - Share your games!


What's Next

Planned for v0.10.0-beta

Features: - Physics system improvements - Animation system enhancements - Tilemap editor integration - Level serialization

Improvements: - Better mobile support - Web platform support (WASM) - Additional post-processing effects - Extended shader support


Acknowledgments

Thanks to all contributors who made v0.9.0 possible:

  • Community feedback and bug reports
  • Pull request contributors
  • Documentation improvements
  • Sample game submissions

Special thanks to our beta testers!


Getting Started

New to Brine2D?

Start with the Quickstart Guide:

# Create new project
dotnet new brine2d -n MyGame
cd MyGame

# Add packages
dotnet add package Brine2D --version 0.9.0-beta
dotnet add package Brine2D.SDL --version 0.9.0-beta

# Run
dotnet run

Upgrading from v0.8.0?

Follow the Migration Guide above, then review:


Summary

Major Changes: - ✅ .NET 10 support - ✅ Package separation (Brine2D + Brine2D.SDL) - ✅ Track-based audio system - ✅ Performance monitoring - ✅ GPU renderer improvements - ✅ Post-processing effects - ✅ ECS multi-threading

Breaking Changes: - ⚠️ Namespace reorganization - ⚠️ Audio API changes (channel → track) - ⚠️ Service registration names - ⚠️ Backend enum values

Improvements: - 📈 30% faster queries - 📈 50% fewer allocations - 📈 10x+ sprite batching - 📈 Better developer experience


Download

NuGet Packages:

dotnet add package Brine2D --version 0.9.0-beta
dotnet add package Brine2D.SDL --version 0.9.0-beta

GitHub Release: - v0.9.0-beta Release Notes - Source Code


Ready to upgrade? Follow the Migration Guide!