Engine Overview
The Softfire engine is a MonoGame-based C# runtime built around an Entity-Component-System (ECS) architecture. It is designed to support a broad range of genres from a single shared core, with genre-specific systems layered on top without modifying the runtime itself.
Entity-Component-System
ECS is the structural pattern that every game built on Softfire uses. The three concepts:
Entities are identifiers — a uint wrapped in an EntityId struct. An entity has no data or behaviour of its own. It is a container key.
Components are plain data structs attached to entities. A TransformComponent holds position, rotation, and scale. A HealthComponent holds hit points and max hit points. Components have no methods other than constructors and factory helpers.
Systems are classes that query the world for entities that have a specific combination of components, then operate on them. A PhysicsSystem queries for entities with both TransformComponent and RigidbodyComponent, integrates velocities, and writes updated positions back.
This separation means you can compose behaviour by combining components, and you can extend the engine for a new genre by writing new systems rather than changing existing ones.
Main projects
| Project | Purpose |
|---|---|
Softfire.MonoGame.Engine.Core | ECS world, game loop, scene management, content pipeline, camera |
Softfire.MonoGame.Engine.Input | InputAction abstraction, device routing, remapping |
Softfire.MonoGame.Engine.Audio | AudioSource, AudioListener, spatial audio, adaptive music |
Softfire.MonoGame.Engine.Save | Save slots, serialisation, cloud sync, backup |
Softfire.MonoGame.Engine.Worldweave | Worldweave client SDK |
Softfire.MonoGame.Engine.Scripting | Lua scripting sandbox (MoonSharp) |
Softfire.MonoGame.Engine.Tools.Editor | Visual editor application |
Softfire.MonoGame.Engine.Test | Engine unit and integration tests |
The game loop
The Softfire game loop follows the standard MonoGame pattern, with the ECS system scheduler driving the work inside each phase:
Initialize() └── Register systems, load scene, initialise services
per frame: Update(GameTime) ├── InputSystem (process device state into InputActions) ├── [Parallel system group] — physics, AI, animation, game logic └── LateUpdateSystem (camera follow, interpolation)
Draw(GameTime) ├── SpriteRenderSystem ├── UIRenderSystem └── DebugRenderSystem (editor / debug builds only)Systems are registered with a priority integer. The scheduler sorts by priority and runs systems in order. Systems marked [Parallel] are grouped and dispatched concurrently where the component write-sets do not overlap. Parallel scheduling is opt-in per system.
Content pipeline
Softfire uses the standard MonoGame Content Builder (MGCB) pipeline for compiling assets at build time. Raw assets (PNG, WAV, OGG, TIFF) are referenced in .mgcb files and compiled to engine-optimised formats. The editor includes an MGCB GUI so you rarely need to edit the .mgcb file by hand.
Softfire adds several custom MGCB processors on top of the MonoGame defaults:
- SceneProcessor — compiles
.sceneJSON files to binary scene archives - PrefabProcessor — compiles
.prefabJSON definitions - SpriteAtlasProcessor — packs loose sprite sheets into atlases
- WorldweaveConfigProcessor — validates and packages
WorldweaveClientConfig
First-party dependency policy
The engine has a strict first-party policy: no third-party libraries are included without extraordinary justification. The current approved exceptions are:
- MoonSharp — C# Lua 5.4 interpreter (MIT); the only practical choice for a sandboxed scripting runtime in a C# MonoGame project
- Steamworks.NET — Steam platform bridge (MIT); required for Steam SDK access and cannot be replicated without the library
- Test frameworks (
NUnit,Moq) — development-only, not included in released packages
This policy keeps the dependency graph shallow and build times fast. It also means there are no transitive licencing surprises in shipped games.