CLI (safi)

The safi CLI lets you create standalone game projects that use the engine without cloning the full engine repository. The engine is installed once to ~/.safi-engine/, and each game project contains only your game code.

Install the Engine

Run this once from the engine repository root:

make install

This builds the engine and copies everything to ~/.safi-engine/:

~/.safi-engine/
  bin/safi              # CLI script (symlinked to /usr/local/bin/safi)
  lib/                  # Engine.dll, librenderer.dylib, libjoltc.dylib
  shaders/              # Compiled .spv shader files
  assets/fonts/         # RobotoMono-Regular.ttf
  templates/            # Viewer.cs, HotReload.cs, starter game_logic/
  version               # Engine version

After install, the safi command is available globally via /usr/local/bin/safi.

Create a New Project

safi new my-game
cd my-game

This scaffolds a game project:

my-game/
  game_logic/           # Your game code
    Game.cs             # Scene setup entry point
    GameConstants.cs    # Debug flags, camera settings
    systems/            # One file per ECS system
  models/               # Place 3D models here
  assets/               # Game-specific assets
  .safi                 # Project marker (engine version, project name)
  .gitignore
  GameLogic.csproj      # IDE IntelliSense only

The starter Game.cs includes a sun light, ground plane, and a red box with camera controls — a working scene out of the box.

Commands

CommandDescription
safi installBuild engine and install to ~/.safi-engine/ (run from engine repo)
safi new <name>Create a new game project
safi runCompile and run the game
safi devCompile and run with hot reload
safi buildBuild a macOS .app bundle
safi cleanRemove build/ directory
safi helpShow available commands

safi run

Compiles your game code against the installed engine and launches it:

safi run

Behind the scenes:

  1. Symlinks engine libraries, shaders, and fonts into build/
  2. Compiles game_logic/**/*.cs + Viewer.cs against Engine.dll
  3. Runs with mono using the correct DYLD_LIBRARY_PATH and Vulkan ICD

safi dev

Hot reload mode — edit game_logic/ files and see changes live without restarting:

safi dev

This uses the same three-assembly split as make dev in the engine repo:

AssemblyContentsReloadable?
Engine.dllWorld, Components, NativeBridgeNo
GameLogic.dllGame.cs, systems/*.csYes
ViewerDev.exeViewer + HotReloadNo

Save any .cs file in game_logic/ and the engine auto-recompiles and reloads your game code.

safi build

Creates a macOS .app bundle named after your project:

safi build
open build/my-game.app

The bundle includes all engine libraries, shaders, fonts, and models — self-contained and ready to distribute.

safi clean

Removes the build/ directory and all compiled artifacts:

safi clean

How It Works

The CLI avoids modifying the C++ renderer by using symlinks. When you run safi run or safi dev, it creates symlinks from your project's build/ directory to the installed engine resources:

build/Engine.dll          -> ~/.safi-engine/lib/Engine.dll
build/librenderer.dylib   -> ~/.safi-engine/lib/librenderer.dylib
build/libjoltc.dylib      -> ~/.safi-engine/lib/libjoltc.dylib
build/shaders/*.spv       -> ~/.safi-engine/shaders/*.spv
assets/fonts/*.ttf        -> ~/.safi-engine/assets/fonts/*.ttf

The renderer loads shaders and fonts from relative paths (build/shaders/, assets/fonts/), so symlinks make everything resolve correctly with zero C++ changes.

IDE IntelliSense

Each generated project includes a GameLogic.csproj that references the symlinked Engine.dll. For C# autocomplete in your editor:

safi run          # creates build/ symlinks first
dotnet restore    # generates project assets for the language server

Engine Updates

When you update the engine, re-run make install from the engine repo. All existing projects will pick up the new engine automatically since they symlink to ~/.safi-engine/.

If a project was created with an older engine version, safi run will print a warning:

Warning: Project was created with engine v0.1.0, installed engine is v0.2.0

Engine Repo Still Works

The CLI is additive — all existing make commands (make run, make dev, make app) continue to work from the engine repository as before.