Backend. Buffer.
Simulation.
Dependency injection in clear C#, combined with DOTS simulation. Two systems running on different clocks, with different rules, both communicating. Buttr is the stack that connects them. And its CoreCLR compatible.
I'm going to make a quick note here as Buttr thus far has only been Dependency Injection (DI). This page is a sample of the full Buttr stack. You do not have to use the full stack. Use only the DI if you don't care about DOTS. I won't lie you will need to install the full stack to setup the DOTs Buffer. The documentation that follows will outline each system individually. They're all packaged separately so you can pull in only what you need. Have fun.
Where it came from
Buttr started as a frustration with how Unity wants you to build. The default workflow - scripts reaching into scripts, one manager that quietly knows about everything. It runs fine, but it always felt structurally wrong. It's like fighting the engine to hold onto any real architecture. Monobehaviours felt like a bottleneck and heavy. A few years of chasing that down through various design patterns and other languages later, this is the shape that finally felt right. The rest of this page is how it works, explained through one small sample game that runs on it.
Unity gives you two worlds and they don't talk.
Services, saves, storefronts, UI. It allocates freely. It holds references. It runs when something happens. Comfortable, productive, let's make it event-driven.
Burst-compiled jobs over raw data which runs every tick across multiple threads. A managed reference here won't compile. Why use it? For speed of course.
Most projects end being built one way. Either the simulation is built entirely in managed code, or the whole backend gets rewritten into DOTS. The point of Buttr is to say why can't we use both? Two layers and an explicit transport between them makes this possible.
Backend. Buffer. Simulation. The Buffer relaying events between either end.
The Backend never reaches into the simulation. The simulation never holds a managed reference. Anything that crosses travels through the Buffer as a small envelope, at a set point in the frame. When a payload is too big to fit inline, it rides alongside in a side arena the envelope points into.
- Services & repositories
- Persistence & save/load
- Platform / web / Steam SDKs
- UI logic
- Double-buffered queues + arenas
- Blittable envelopes only
- Signal Domains & codecs
- Drain systems
- Systems, jobs, Burst
- Entities & components
- No managed references
- The hot loop stays hot
The point here is Buttr provides a full stack for building large scale simulations. The best part; if backend code is built right it can become core packages that can be shared between projects. Then the entire focus of building a game only needs to be on the simulation. The DI of Backend Buttr makes this possible.
Meet Wave Survivor.
Every snippet on this page comes from one small worked example we built called Wave Survivor. It's simple, straight to the point, and compiles/runs on Buttr's real APIs. In a survivor game thousands of enemies want you dead, the textbook case for Burst; its XP, inventory and progression stay ordinary C#, which is exactly what the Backend is for.
Each layer gets its own tab up top. Follow the beat through them in order, or jump straight to the one you came for.