Skip to content

Building from Source

Zaldaryon edited this page Jul 24, 2026 · 9 revisions

Building from Source

This page is for developers who want to modify Optimum. End users should use the Installation page instead — no build step is needed to use Optimum.

Requirements

  • .NET 10 SDK
  • bash (Linux/WSL/Git Bash)
  • python3, git, curl, perl

Quick Start (Linux / WSL / Git Bash)

git clone https://github.com/Zaldaryon/Optimum.git
cd Optimum
make build    # downloads ~570MB client, decompiles, clones forks, patches, compiles
make test     # runs 178 unit tests (127 Facts + 51 Theories)
make run      # deploys DLLs + shaders to .vanilla/ and launches the client

The first make build takes 2-5 minutes depending on download speed. Subsequent builds take 5-10 seconds.

Quick Start (Windows PowerShell)

git clone https://github.com/Zaldaryon/Optimum.git
cd Optimum
.\scripts\bootstrap.ps1
dotnet build VintageStory.slnx -c Release

The bootstrap script downloads the official Windows installer, extracts it with Inno Setup 6, decompiles with ILSpy, clones the open-source forks at pinned refs, and applies patches.

What Bootstrap Does

  1. Downloads the official Vintage Story 1.22.3 client archive for your platform.
  2. Extracts it into .vanilla/.
  3. Decompiles VintagestoryLib.dll and Vintagestory.dll with ilspycmd into build/.
  4. Runs post-decompile fixup regex (ref-casts, GeneratedRegex, ErrorCallback alias, ambiguous calls).
  5. Creates .baseline/ snapshot (unmodified decompiled source for diff generation).
  6. Clones the open-source forks (vsapi, Cairo, vsessentialsmod, vssurvivalmod, vscreativemod) at the refs pinned in forks.json.
  7. Applies 52 patches from patches/ over both decompiled and fork sources.
  8. Copies Optimum-original sources from sources/ (56 files) into the working tree.

Project Structure

Optimum/
├── Optimum.Launcher/      ← Runtime patcher entry point (outputs Optimum.exe)
├── Optimum.Patcher/       ← Cecil IL patcher (method transplant + injection)
├── Optimum.Tests/         ← 178 xunit tests
├── patches/               ← 52 patch files (generated by extract-patches.sh)
│   └── cecil-owned.list   ← 29 patches that ship via Cecil transplant
├── sources/               ← 56 Optimum-original source files
├── scripts/               ← Build, package, install scripts
├── build/                 ← Decompiled VintagestoryLib + Vintagestory (gitignored)
├── .baseline/             ← Clean decompiled snapshot for diff (gitignored)
├── .vanilla/              ← Vanilla client archives (gitignored)
├── VintagestoryApi/       ← Forked API project (gitignored, populated by bootstrap)
├── VSEssentials/          ← Forked essentials mod (gitignored)
├── VSSurvivalMod/         ← Forked survival mod (gitignored)
└── VSCreativeMod/         ← Forked creative mod (gitignored)

The Patcher

Optimum.Patcher/Program.cs defines:

  • 4 types to inject (OptimumInfo, OptimumUpdateChecker, EntityLightBatchBuffer, OptimumGreedyMeshEmitter)
  • 112 members to inject into existing types (fields, methods, properties)
  • 51 methods to transplant (replace vanilla method body with optimized version)
  • 1 IL hook (inserts a call into GuiCompositeSettings.ComposerHeader)

Deploy and Run

make deploy runs the Cecil IL patcher and copies results into .vanilla/:

make deploy   # patch + copy
make run      # deploy + launch

Tests

make test

Runs 178 xunit tests. Tests verify patch logic, data structures, and IL compatibility without requiring a bootstrapped working tree.

Patch Workflow

To add a new optimization:

  1. Make the change in the appropriate project (VintagestoryApi/, build/VintagestoryLib/, etc.).
  2. make build — verify compilation.
  3. make test — verify tests pass.
  4. If it's a VintagestoryLib change: add the method to Optimum.Patcher/Program.cs targets.
  5. scripts/extract-patches.sh — regenerate patches from working tree vs baseline.
  6. scripts/check-patches.sh — verify 0 conflicts, 0 pending, 0 orphans.
  7. make run — verify in-game.

Makefile Targets

Target Description
make check Report installed tools (installs nothing)
make bootstrap Download, decompile, clone, patch
make build Bootstrap if needed, then compile
make clean Remove obj/ and bin/ from project dirs
make refresh Force full re-bootstrap
make patches Regenerate patches/ from the working tree
make deploy Run Cecil patcher, copy DLLs + shaders into .vanilla/
make run Build, deploy, launch client
make test Run unit tests
make package Build all release archives
make package-linux Linux tar.gz
make package-appimage Linux AppImage
make package-macos macOS .dmg
make package-win Windows zip

Clone this wiki locally