Skip to content

v1.1

Release Date: 2026 Target Framework: .NET 10

Brine2D 1.1 folds in fixes and refinements discovered while building the Space Shooter demo, plus a documentation pass covering events, default systems, asset tooling, and render targets. Most changes are additive; two are breaking (see below).


Physics On By Default

PhysicsWorld, Box2DPhysicsSystem, and related physics services are now registered automatically; no more AddPhysics(...) call required just to make physics resolvable. AddPhysics(...) is now purely for configuration (gravity, layers, thresholds); omit it entirely and physics still works with sane defaults.

Verified via Benchmark.NET: an idle physics world (no bodies) costs ~150 ns per fixed tick, negligible against a 16.6 ms frame budget. Don't need physics at all? Remove the (near-zero) cost with builder.ExcludeDefaultSystem<Box2DPhysicsSystem>().


Sprites Load On Demand

SpriteRenderingSystem now lazily loads a sprite's texture the first time it's rendered, if only TexturePath was set. LoadTexturesAsync is no longer required for a sprite to appear; it's now purely an optional "preload to avoid a first-frame hitch" optimization for performance-sensitive scenes.


Fixed-Aspect-Ratio / Letterbox Effect

A first-class, opt-in LetterboxEffect post-processing effect is now available via services.AddLetterbox(designWidth, designHeight, barColor?). It decouples game-world rendering resolution from window resolution and produces centered letterbox/pillarbox bars automatically, replacing the old paired-IRenderSystem workaround pattern some projects used.


Smaller Improvements

  • Behavior now exposes the same ambient framework properties as Scene (Logger, Renderer, Input, Audio, Game), so no more constructor-injecting these into behaviors by hand.
  • VelocityComponent (Vector2 Value) is now a real, shipped component alongside TransformComponent.
  • UICanvas is now registered by default (no AddUICanvas() call needed with AddBrine2D()), and gained an explicit AutoResizeToWindow opt-in for window-resize tracking (previously implicit whenever an IEventBus was present).
  • Default camera now self-centers on the viewport instead of starting at Vector2.Zero.
  • UILabel/UIButton constructors are now defaultable (new UILabel(), new UIButton()) for object-initializer/anchor-driven usage.
  • Brine2D.Build asset generation is now visible to Visual Studio's Fast Up-to-Date Check, so no more manual obj/bin cleans after adding a new asset file.

Breaking Changes

v1.1 includes two narrowly-scoped breaking changes, called out here as an exception to the "no breaking changes without a major bump" policy: both are small, mechanical fixes to bugs discovered during real project use, not API redesigns.

UIAnchorResolver is now size-aware

Center/Right/Bottom anchors previously resolved to a bare screen-space point, requiring a manual compensating negative AnchorOffset to land the component fully on-screen. Anchors now account for the component's own Size automatically.

Action required: remove any manual size-compensating AnchorOffset you added to work around the old behavior; it will now double up.

Behavior.Entity throws instead of returning null

Behavior.Entity is now non-nullable (Entity instead of Entity?). Reading it before attachment, after RemoveBehavior<T>()/Entity.Destroy(), or from a constructor now throws InvalidOperationException instead of returning null.

Action required: replace if (behavior.Entity == null) checks with a try/catch, or track attachment state externally.


Documentation

Alongside the engine changes above, this release includes a documentation pass covering: events (IEventBus, window events), the full list of default systems and how to exclude them, Brine2D.Build visibility from the main install/getting-started flow, mid-frame render-target patterns (e.g. minimaps), and assorted doc-comment cross-references.