KRWCLASSIC.UMK
0.1.4
dotnet tool install --global KRWCLASSIC.UMK --version 0.1.4
dotnet new tool-manifest
dotnet tool install --local KRWCLASSIC.UMK --version 0.1.4
#tool dotnet:?package=KRWCLASSIC.UMK&version=0.1.4
nuke :add-package KRWCLASSIC.UMK --version 0.1.4
UMK — Unity Modding Kit
<div align="center">
A CLI-only, shell-driven project configurator and task runner for Unity mod development.
</div>
Overview
UMK does not implement a custom build system, compiler, or mod templates. Instead, it acts as a lightweight task runner that executes raw system shell commands (cmd or powershell) defined by the user in umk.json.
It standardizes the repetitive Unity mod development loop (compile $\to$ copy DLL to BepInEx\plugins $\to$ kill process $\to$ launch game) into clean, composable scripts with recursive variable interpolation and fail-fast sequential execution.
Installation
Install UMK globally as a .NET tool:
dotnet tool install -g KRWCLASSIC.UMK
To update an existing installation:
dotnet tool update -g KRWCLASSIC.UMK
CLI Reference
# Project initialization wizard (auto-detects Steam libraries, game paths, and outputs)
umk init
# Quick setup after git clone (reconfigures local game path & creates libs\ junctions)
umk setup
# Upgrade umk.json format version to match the installed UMK tool
umk upgrade
# Zero-copy game library linker (creates junctions in libs\ and references in .csproj)
umk linkgamelibs
# Run user-defined scripts from umk.json
umk build
umk run
umk <script>
# Preview resolved shell commands without executing them
umk run --dry-run
umk <script> --dry-run
# Bypass UMK version mismatch check with umk.json
umk build --ignore-umkv
# Inspect available scripts and resolved variables
umk list
# Help & documentation
umk help
umk help variables
umk help scripts
Configuration: umk.json
The manifest defines project variables and executable scripts:
{
"umk": "0.1.0",
"name": "MyMod",
"shell": "cmd",
"variables": {
"configuration": "Release",
"steamId": "123456",
"game": "E:\\SteamLibrary\\steamapps\\common\\MyGame",
"gameExe": "MyGame.exe",
"plugins": "${game}\\BepInEx\\plugins",
"output": "bin\\${configuration}\\netstandard2.1"
},
"scripts": {
"kill": [
"taskkill /F /IM \"${gameExe}\" >nul 2>&1 || ver >nul"
],
"compile": [
"dotnet build MyMod.csproj -c ${configuration}"
],
"copy": [
"copy /Y \"${output}\\MyMod.dll\" \"${plugins}\""
],
"build": [
"@compile",
"@copy"
],
"run": [
"@kill",
"@build",
"start \"\" \"steam://rungameid/${steamId}\""
],
"clean": [
"dotnet clean"
]
}
}
Variables
- Syntax:
${variableName} - Variables can reference other variables (e.g.
${game}\BepInEx\plugins). - On Windows, forward slashes (
/) in path variables are automatically normalized to backslashes (\) for shell compatibility. - Circular variable references are detected and rejected before execution.
Advanced Dynamic Variables & Lazy Evaluation
Variables are resolved on-demand based on the execution cascade: if you run umk clean, dynamic variables required only by umk pack are never triggered.
- Shell Command (
$[command:...]): Runs a shell command and captures its trimmed output."gitHash": "$[command:git rev-parse --short HEAD]" - Script-Backed (
$[script:...]): Executes a user-defined or private script and captures its standard output."version": "$[script:*version-checker]" - File Content (
$[file:...]or${file:...}): Reads raw text directly from disk."notes": "$[file:docs\\changelog.txt]" - Return / Exit Code (
$[exitcode:...]): Captures the return code of a command or script as an integer string ("0","1"):"buildStatus": "$[exitcode:script:*test-build]"
Scripts
- Sequential arrays of ordinary shell commands or references to other script keys.
- Script References (
@prefix): Prefix a step with@to invoke another script inline (e.g."@compile","@copy","@*test"). Lines without@are executed as raw shell commands, eliminating collisions with binaries or system utilities. - Escaping: Use
@@if a literal shell command starts with@. - Private Scripts (
*prefix): Prefixing a script definition with an asterisk (e.g."*modlessrun") marks it as private. Private scripts are hidden fromumk listand cannot be called from the CLI, but can be referenced and chained inside other scripts via@*name. - Execution stops immediately on the first non-zero exit code (fail-fast).
Post-Setup Tasks ("post-setup")
Automate initialization tasks directly after umk setup creates the libs\ junctions (e.g. downloading native binaries, pulling submodules, generating local files, or chaining scripts via @):
{
"umk": "0.1.4",
"name": "MyMod",
"shell": "cmd",
"variables": {
"game": "E:\\Games\\MyGame"
},
"post-setup": [
"echo Preparing additional assets...",
"@*download-extras"
],
"scripts": {
"*download-extras": [
"powershell -Command \"Invoke-WebRequest -Uri 'https://example.com/extras.zip' -OutFile 'extras.zip'\""
]
}
}
When you run umk setup, it configures the game directory, links libs\, and then executes all steps in "post-setup" with full variable interpolation and fail-fast guarantees.
Manifest Versioning & --ignore-umkv
UMK validates that umk.json's "umk" version matches the installed tool version:
- If the project manifest is older than your tool: run
umk upgradeto updateumk.json. - If the project manifest requires a newer tool: run
dotnet tool update -g KRWCLASSIC.UMK. - To bypass the version check entirely: pass
--ignore-umkv(e.g.umk build --ignore-umkv).
Zero-Copy Game Library Linking (umk linkgamelibs)
Instead of copying 100+ MB of game DLLs into every mod project folder:
umk linkgamelibsreads thegamepath fromumk.json.- Creates two Windows directory junctions (
mklink /J) inside./libs/:libs\bepinex$\to$<game>\BepInEx\corelibs\managed$\to$<game>\<Game>_Data\Managed
- Injects a compact wildcard block into your
.csproj:
<ItemGroup Label="UMKGameLibs">
<Reference Include="libs\bepinex\0Harmony.dll" Private="False" />
<Reference Include="libs\bepinex\BepInEx*.dll" Private="False" />
<Reference Include="libs\managed\*.dll" Private="False" />
<Reference Remove="libs\managed\mscorlib.dll" />
<Reference Remove="libs\managed\netstandard.dll" />
<Reference Remove="libs\managed\WindowsBase.dll" />
<Reference Remove="libs\managed\Accessibility.dll" />
<Reference Remove="libs\managed\nunit.framework.dll" />
<Reference Remove="libs\managed\System*.dll" />
<Reference Remove="libs\managed\Mono*.dll" />
<Reference Remove="libs\managed\Microsoft*.dll" />
<Reference Remove="libs\managed\I18N*.dll" />
</ItemGroup>
- 0 MB disk duplicate: Junctions point directly to the game files.
- No local paths in
.csproj: References are purely relative (libs\...), safe for git commits and sharing. - No BCL conflicts: Automatically excludes base class library assemblies (
mscorlib,netstandard,System.*,Mono.*) while linking all game modules,UnityEngine*.dll, andUnity.*.dll.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.