odin_root := `odin root` project := "thanatograph" game_pkg := "src/game" sim_pkg := "src/sim" hot_loader_pkg := "src/lib/hot_reload" release_pkg := "src/lib/release" headless_pkg := "src/lib/headless" hot_dir := "build/hot_reload" release_dir := "build/release" headless_dir := "build/headless" dll_ext := if os() == "windows" { ".dll" } else if os() == "macos" { ".dylib" } else { ".so" } exe_ext := if os() == "windows" { ".exe" } else { ".bin" } hot_exe := project + "_hot_reload" + exe_ext release_exe := release_dir + "/" + project + exe_ext headless_exe := headless_dir + "/" + project + "_headless" + exe_ext raylib_dir := if os() == "macos" { odin_root + "/vendor/raylib/macos" } else if os() == "linux" { odin_root + "/vendor/raylib/linux" } else { odin_root + "/vendor/raylib/windows" } linker_flags := if os() == "windows" { "" } else { "-Wl,-rpath " + raylib_dir } # List available recipes default: @just --list # Check all template packages check: test-sim odin check {{ sim_pkg }} -strict-style -vet -no-entry-point odin check {{ game_pkg }} -strict-style -vet -no-entry-point odin check {{ hot_loader_pkg }} -strict-style -vet odin check {{ release_pkg }} -strict-style -vet odin check {{ headless_pkg }} -strict-style -vet # Run deterministic simulation tests without Raylib test-sim: odin test {{ sim_pkg }} -strict-style -vet # Build the game shared library used by the hot reload loader build-game: @mkdir -p {{ hot_dir }} odin build {{ game_pkg }} \ -extra-linker-flags:"{{ linker_flags }}" \ -define:RAYLIB_SHARED=true \ -build-mode:dll \ -out:{{ hot_dir }}/game_tmp{{ dll_ext }} \ -strict-style -vet -debug @mv {{ hot_dir }}/game_tmp{{ dll_ext }} {{ hot_dir }}/game{{ dll_ext }} # Alias for the hot-reload game library build build: build-game # Build the hot reload loader executable build-loader: odin build {{ hot_loader_pkg }} -out:{{ hot_exe }} -strict-style -vet -debug # Build the headless simulation harness build-headless: @mkdir -p {{ headless_dir }} odin build {{ headless_pkg }} -out:{{ headless_exe }} -strict-style -vet -debug # Run a deterministic simulation fixture without Raylib headless fixture="fixtures/headless/basic_run.txt": build-headless ./{{ headless_exe }} {{ fixture }} # Build and run the hot reload template run: build-game build-loader ./{{ hot_exe }} # Rebuild the shared game library for a running loader reload: build-game @printf "Hot reloaded.\n" # Launch the loader and rebuild the game library on source changes. Requires watchexec or fswatch. dev: build-game build-loader @if command -v watchexec >/dev/null 2>&1; then \ ./{{ hot_exe }} & \ watchexec -w {{ game_pkg }} -w {{ sim_pkg }} -e odin -- just reload; \ elif command -v fswatch >/dev/null 2>&1; then \ ./{{ hot_exe }} & \ fswatch -o {{ game_pkg }} {{ sim_pkg }} | while read -r _event; do just reload; done; \ else \ printf "watchexec or fswatch is required for 'just dev'. Install one or use 'just run' + 'just reload'.\n"; \ exit 1; \ fi # Optimized release build without hot reload release: @mkdir -p {{ release_dir }} odin build {{ release_pkg }} \ -out:{{ release_exe }} \ -strict-style -vet -no-bounds-check -o:speed # Clean build artifacts clean: rm -rf build/ {{ hot_exe }} {{ hot_exe }}.dSYM