Table of Contents

Exploring the Assemblies

The API reference on this site tells you what exists. When you need to know how the game does something, you want the method bodies — and for that you decompile locally. This page is the workflow that produced most of this guide.

Install ilspycmd

dotnet tool install -g ilspycmd

The published tool targets .NET Core 3.1, which you almost certainly do not have. Roll it forward instead of installing an ancient runtime:

export DOTNET_ROLL_FORWARD=LatestMajor   # PowerShell: $env:DOTNET_ROLL_FORWARD="LatestMajor"
ilspycmd --version

List the types in an assembly

M="$SPZ2_PATH"
ilspycmd -l c "$M/Game.Core.Map.Simulation.dll"   # classes
ilspycmd -l i "$M/Game.Core.Map.Simulation.dll"   # interfaces
ilspycmd -l s "$M/Game.Core.Map.Simulation.dll"   # structs
ilspycmd -l e "$M/Game.Core.Map.Simulation.dll"   # enums

Pass one kind per invocation — the comma-separated form documented in --help silently produces nothing.

Building one grep-able index of every type across every assembly is the single most useful thing you can do up front:

mkdir -p /tmp/spz2types
for f in "$M"/Game*.dll "$M"/Core*.dll "$M"/SPZGameAssembly.dll; do
  b=$(basename "$f" .dll)
  { ilspycmd -l c "$f"; ilspycmd -l i "$f"; ilspycmd -l s "$f"; ilspycmd -l e "$f"; } \
    2>/dev/null | grep -v '<' | sed "s|^|$b |" > "/tmp/spz2types/$b.txt"
done
cat /tmp/spz2types/*.txt > /tmp/allTypes.txt

That is about 5,200 types. Now "where does efficiency live?" is one command:

grep -iE "efficien|throughput|statistic" /tmp/allTypes.txt

Decompile a single type

ilspycmd -t HUDSidePanelModuleBuildingEfficiency "$M/SPZGameAssembly.dll"

Two failure modes you will hit:

  • "Decompiling types that are not part of the main module is not supported" — the type is forwarded; find its real assembly in your type index.
  • "Could not find type definition … in type system" — you have the namespace wrong. Nested and namespaced types need the full name.

Decompile everything into a source tree

The highest-leverage version. Output is a real project layout you can grep and open in an IDE:

OUT="$HOME/spz2-decompiled"
for n in SPZGameAssembly Game.Content Game.Content.Features Game.Core \
         Game.Core.Map.Model Game.Core.Map.Simulation Game.Core.Coordinates \
         Game.Core.Rendering Game.Orchestration Game.Interaction Core; do
  mkdir -p "$OUT/$n"
  ilspycmd -o "$OUT/$n" -p -r "$M" "$M/$n.dll"
done

-p writes a project, -r supplies the reference path so types resolve. The output directory must already exist — ilspycmd will not create it.

Roughly 4,000 files and 20 MB for the assemblies above. It does not compile, and it is not meant to; it is a searchable answer key.

The questions it answers

Once the tree exists, most API questions become one grep:

# Who calls this, and what do they pass?
grep -rn "UXOverviewModeMapResourcePlaneMaterial" "$OUT"

# What implements this interface?
grep -rn ": IMapSubDrawer" "$OUT"

# How does the game itself do the thing I want to do?
grep -rn "DrawMesh(" "$OUT/SPZGameAssembly" | head -40

The third one is the important habit. Nearly every problem a mod faces — drawing a coloured plane over a chunk, measuring a machine's throughput, caching a combined mesh — is something the game already solves somewhere, and copying its approach is both faster and likelier to keep working than inventing one.

Regenerating this site's API reference

The reference here is generated by DocFX straight from the assemblies — no decompilation involved:

dotnet tool install -g docfx

bash scripts/write-local-config.sh          # substitute your SPZ2_* paths
docfx metadata docfx.metadata.local.json    # assemblies → api/*.yml
docfx build docfx.ci.json                   # → _site/
docfx serve _site                           # http://localhost:8080

docfx.metadata.json lists the assemblies under metadata.src and points references at the whole Managed folder so dependencies resolve; the paths are substitution tokens that write-local-config.sh fills in for your machine. Add an assembly to that list and rerun to extend the reference.

Note

A word on redistribution: signatures are one thing, decompiled method bodies are another. Keep your local decompiled tree local, and out of any repository you publish.