Project Structure
File Layout
The project uses a two-folder structure separating engine code from game code:
Solution & Project Files
SaFiEngine.sln (repo root) and managed/SaFiEngine.csproj provide C# IntelliSense in VS Code and other IDEs. They are not used by the Makefile build. After cloning, run dotnet restore once to enable autocomplete and go-to-definition.
Adding New .cs Files
The Makefile uses two separate file lists — one for engine code, one for game logic:
- Game files go in
game_logic/(orgame_logic/systems/for systems) — add the path toGAMELOGIC_CS_FILESin the Makefile - Engine files go in the appropriate
managed/subdirectory (core/,rendering/,physics/, orruntime/) — add the path toMANAGED_CSin the Makefile
The .csproj uses EnableDefaultCompileItems so it discovers new files automatically — no project file changes needed. Only the Makefile needs updating.
Adding New Components
- Create a class in
managed/core/Components.cs(or a new file in the appropriatemanaged/subdirectory) - Add fields with default values
- If in a new file, add it to
MANAGED_CSin the Makefile
Adding New Systems
- Create a new file in
game_logic/systems/using thepartial class Systemspattern (or add to an existing system file) - Add the path to
GAMELOGIC_CS_FILESin the Makefile - Register it with
world.AddSystem()ingame_logic/Game.cs - Place it before
RenderSyncSystemin the registration order
Scene Setup
game_logic/Game.cs is the entry point for all game-specific setup. The engine calls Game.Setup(world) after initializing the renderer. This is where you spawn entities, configure components, and register systems:
Hot Reload (Dev Mode)
make dev watches game_logic/ for .cs changes and live-reloads without restarting. On save, the engine recompiles all game logic files, resets the world (despawns all entities, clears lights), and re-runs Game.Setup(world) from the new assembly. This means any change to Game.cs, GameConstants.cs, or systems/*.cs takes effect immediately — including new entities, changed lights, updated constants, and re-ordered systems.
Limitations:
- Only
game_logic/files are hot-reloadable. Engine changes (managed/) require a restart. - Old assemblies leak memory (Mono can't unload). Restart after many reloads.
- Static fields in
systems/*.csandGameConstants.csvalues reset on each reload.