Rusty Engine is reusable Rust infrastructure for ordinary C# products. A product owns its game and application meaning; the Engine supplies durable mechanisms and the host that makes that product run.
The product decides. The Engine guarantees.
- Architecture overview — ownership, layers, and data flow.
- C# SDK guide — build a product through the current generated safe API.
- C# product style — recommended downstream organization and coding conventions.
- Agent guidance — task-time boundary and verification rules.
| Owner | Location | Responsibility |
|---|---|---|
| Rust ABI declaration | rust/crates/csharp-engine-abi |
The single C ABI/function-table source. |
| Rust Engine bridges | rust/crates/csharp-engine-services |
Concrete named Engine service bridges. |
| Product runtime | rust/crates/csharp-product-runtime |
Loads staged CoreCLR or NativeAOT products and integrates their lifecycle with the host. |
| Binding generation | scripts/generate-csharp-native-bindings.sh and csharp/Rusty.Engine.BindingGenerator |
Generates native declarations, safe contracts/values, and the SDK's internal interop and service implementations. |
| Default managed C# assembly | csharp/Rusty.Engine |
The single runtime assembly containing generated contracts/values, the compiled native bridge, and handwritten managed helpers. |
| Product bootstrap | csharp/Rusty.Engine.ProductGenerator |
Generates each product's safe CoreCLR/NativeAOT bind export and debug command catalog. |
| Managed namespaces | Application, Entities, Mechanics, Persistence, StateMachine |
Optional reusable scheduling, entity, mechanics, persistence, and state-machine helpers inside Rusty.Engine; these are namespace boundaries, not separate runtime assemblies. |
| Working fixture | fixtures/csharp-nativeaot-trial |
Minimal buildable product and direct runtime exercise. |
Ordinary product projects reference one immutable Rusty.Engine package and
declare their product metadata in that project. With the matching runtime pack,
the normal development command is:
/path/to/runtime-pack/bin/rusty dev \
--project /path/to/Product.Game.csproj \
--runtime /path/to/runtime-packrusty dev builds and incrementally stages a loose Product bundle, starts it
through CoreCLR, and restarts it when declared C#, UI, or content inputs change.
The runtime pack supplies the Engine host and browser shell; a Product bundle
contains only managed Product output, Product UI, Product content, and
product.json. The runtime renders the world with render-wgpu and streams
frames to the browser shell; RustyEngineProductRenderOutput=window in the
product project (or rusty dev --output window) presents to a native
desktop window instead. Audio plays on the runtime's
output device.
The SDK package and runtime pack must describe the same generated ABI identity. The bind rejects a mismatch with a rebuild/select-the-matching-pack diagnostic; there is no compatibility negotiation or adjacent-checkout discovery.
NativeAOT is a separate fidelity/release operation:
dotnet msbuild /path/to/Product.Game.csproj -t:VerifyRustyEngineAotEngine contributors may explicitly select source with rusty dev --engine-source /home/dev/rusty-engine; this is an exception, not a downstream
setup requirement. Binding generation, Cargo hosting, and the fixtures in this
repository are provider development and proof infrastructure. Products do not
copy them or check in generated interop/composition code.
- C# owns product state, rules, orchestration, content meaning, and policy.
- Rust owns lifecycle/host integration, input delivery, renderer and presentation infrastructure, spatial mechanisms, resources, persistence primitives, and other named Engine capabilities.
- The generated API is the green path. A missing capability is an upstream request and a valid stopping point—not permission to recreate an Engine mechanism downstream.
- TypeScript is limited to Engine-side DOM UI, accessibility, and explicit host/backend work. It is not a downstream gameplay lane and does not render non-UI game elements.
For details and the product coding lane, use the linked guides rather than duplicating architecture here.
Portable sprite/model content: Engine-owned descriptors load through the packaged Content service from loose files or existing bundles.