StarFluxGames.PlateUp.ModBuildUtilities
1.0.0
dotnet add package StarFluxGames.PlateUp.ModBuildUtilities --version 1.0.0
NuGet\Install-Package StarFluxGames.PlateUp.ModBuildUtilities -Version 1.0.0
<PackageReference Include="StarFluxGames.PlateUp.ModBuildUtilities" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="StarFluxGames.PlateUp.ModBuildUtilities" Version="1.0.0" />
<PackageReference Include="StarFluxGames.PlateUp.ModBuildUtilities"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add StarFluxGames.PlateUp.ModBuildUtilities --version 1.0.0
#r "nuget: StarFluxGames.PlateUp.ModBuildUtilities, 1.0.0"
#:package StarFluxGames.PlateUp.ModBuildUtilities@1.0.0
#addin nuget:?package=StarFluxGames.PlateUp.ModBuildUtilities&version=1.0.0
#tool nuget:?package=StarFluxGames.PlateUp.ModBuildUtilities&version=1.0.0
StarFluxPlateUpUtilities
MSBuild build utilities for PlateUp! mod projects.
Add the package and the game's assemblies become references — no hard-coded paths, no DLLs copied into the repository, and nothing to change when the game or Steam moves.
<PackageReference Include="StarFluxGames.PlateUp.ModBuildUtilities" Version="1.0.0" PrivateAssets="all" />
What it does
At the start of every build the package locates PlateUp! and adds references with Private=false,
so everything is compiled against but never copied to the output. Three sources are searched:
| Source | Where | PlateUpSource |
|---|---|---|
| The game | PlateUp_Data/Managed |
Game |
| Locally installed mods | <game>/Mods, recursively |
Mods |
| Subscribed Workshop items | steamapps/workshop/content/1599600, recursively |
Workshop |
So a mod compiles against KitchenLib, Harmony and anything else you have installed without a single path in the project file.
The search runs in this order, stopping at the first hit:
- The
PlateUpDirorPlateUpManagedDirproperty, if set. - The
PLATEUP_DIRenvironment variable. - Any
PlateUpSearchDirectoryitems. - Steam. The client's install path comes from the registry (
HKCU\Software\Valve\Steamand bothHKLMviews) with the usual install locations as a fallback, every library folder is read out ofsteamapps/libraryfolders.vdf, andappmanifest_1599600.acfgives the game's folder name.
Linux and macOS Steam paths are probed too, though the registry step is Windows-only.
Mod and Workshop folders are searched recursively, because mods nest their files (<Mod>/content/ <Mod>.dll). Files without assembly metadata are skipped, so native libraries shipped next to managed
ones don't produce resolution warnings.
What gets excluded
Base class library assemblies that Unity ships alongside the game (mscorlib, netstandard,
System.*, Mono.*) are dropped — referencing them next to the SDK's own reference assemblies
causes duplicate type errors. This filter applies only to the game's folder, so a mod's
Mono.Cecil is still referenced normally.
The project's own assembly is never referenced back, whether it builds into the Mods folder or you
are subscribed to your own published Workshop item. The match is on $(AssemblyName).
When the same assembly name appears in more than one source, the first one wins in the order game → mods → Workshop — the same order the game resolves them in. Skipped duplicates are reported at low log verbosity.
Properties
| Property | Default | Meaning |
|---|---|---|
ReferencePlateUpAssemblies |
true |
Set to false to turn the whole thing off. |
PlateUpDir |
discovered | The folder containing PlateUp.exe. Also set as an output. |
PlateUpManagedDir |
discovered | The folder containing Assembly-CSharp.dll. Also set as an output. |
PlateUpSteamAppId |
1599600 |
The Steam app id to look for. |
ReferencePlateUpModAssemblies |
true |
Reference mods in the game's Mods folder. |
ReferencePlateUpWorkshopAssemblies |
true |
Reference subscribed Workshop items. |
PlateUpModsDir |
<game>/Mods |
The mods folder. Also set as an output. |
IncludePlateUpFrameworkAssemblies |
false |
Also reference the Mono base class library. |
PlateUpReferencesCopyLocal |
false |
Copy the game assemblies to the output folder. |
PlateUpInstallRequired |
true |
Set to false to warn instead of failing when the game is missing. |
SuppressPlateUpAssemblyVersionWarnings |
true |
Hides MSB3277. The game ships assemblies built against different versions of the same dependency, and Unity's Mono runtime ignores assembly versions when binding, so the conflict is unfixable and harmless. Set to false to see them. |
Two more properties are set as outputs and are free to use in the rest of the build:
PlateUpUnityVersion (for example 2020.3.48f1), PlateUpSteamBuildId and PlateUpExe. The
PlateUpWorkshopDirectory item holds the resolved Workshop content folders.
Items
| Item | Meaning |
|---|---|
PlateUpAssembly |
Simple assembly names to reference. When any are given, only those are referenced, from any source. |
PlateUpAssemblyExclude |
Simple assembly names to leave out. |
PlateUpSearchDirectory |
Extra folders to probe for the game before falling back to Steam. |
PlateUpModSearchDirectory |
Extra mod folders to search alongside the game's Mods folder. |
Referencing only what a mod actually uses:
<ItemGroup>
<PlateUpAssembly Include="Assembly-CSharp" />
<PlateUpAssembly Include="KitchenMods" />
<PlateUpAssembly Include="Kitchen.Common" />
<PlateUpAssembly Include="UnityEngine.CoreModule" />
</ItemGroup>
Deploying into the game
Every build copies its output into the game. This happens by default — a project using this package is a mod, and building a mod is meant to put it in the game:
<game>/Mods/<PlateUpModName>/content/YourMod.dll
YourMod.pdb (with DeployPlateUpModSymbols)
YourMod.assets (when an asset bundle is found)
Symbols are the exception and stay opt-in, since they are large and most builds have no use for them in the game folder:
<PropertyGroup>
<DeployPlateUpModSymbols>true</DeployPlateUpModSymbols>
</PropertyGroup>
Deploying replaces any installed mod that shares the folder name, so a project that is a shared
library rather than a mod should opt out with <DeployPlateUpMod>false</DeployPlateUpMod>. A project
that cannot work out where to deploy — ReferencePlateUpAssemblies is off, so no Mods folder was
discovered — warns as SFPU0004 and carries on rather than failing the build.
Files are copied, not moved. Taking the assembly out of the output folder would break incremental
builds, packing, and anything else reading $(TargetPath) afterwards. Unchanged files are skipped,
so a rebuild with no source change does no work.
Deployed assemblies do not get referenced back on the next build — the self-exclusion described above covers exactly this case.
| Property | Default | Meaning |
|---|---|---|
DeployPlateUpMod |
true |
Copy the build output into the game's Mods folder. |
DeployPlateUpModSymbols |
false |
Also copy the .pdb alongside the assembly. |
PlateUpModName |
$(MSBuildProjectName) |
The folder name under Mods. |
PlateUpModDeployDir |
<Mods>/<PlateUpModName>/content |
The exact destination, if you need to override the shape. |
DeployPlateUpModAssets |
true |
Deploy the mod's asset bundle. |
PlateUpModAssets |
discovered | Full path to the asset bundle. Set it when the template layout doesn't apply. |
PlateUpModAssetsFileName |
mod.assets |
The file name looked for in the template location. |
PlateUpModAssetsDeployName |
$(PlateUpModName).assets |
The file name the bundle is deployed as. |
The asset bundle
The Unity project that builds the bundle sits beside the C# project in the standard mod template, so that location is probed automatically — no configuration in the common case:
YourMod/
YourMod.csproj
UnityProject - YourMod/
content/
mod.assets <-- found automatically
The folder is matched on $(PlateUpModName), falling back to $(MSBuildProjectName) when you have
overridden the mod name. Change the file name looked for with PlateUpModAssetsFileName.
When the bundle lives somewhere else, point at it directly — this wins over the template location:
<PropertyGroup>
<PlateUpModAssets>$(MSBuildProjectDirectory)\..\Bundles\mod.assets</PlateUpModAssets>
</PropertyGroup>
The bundle is renamed on copy — the template's generic mod.assets is deployed as
<PlateUpModName>.assets, so the game can tell one mod's bundle from another's:
UnityProject - YourMod/content/mod.assets -> <game>/Mods/YourMod/content/YourMod.assets
Override the deployed name with PlateUpModAssetsDeployName if you need something else.
A project with no bundle deploys just the assembly and says nothing; setting PlateUpModAssets to a
path that does not exist warns as SFPU0005, since that is almost always a typo rather than an
intent.
Extra files — assets, a manifest, anything else the mod ships — go in the PlateUpModContent item
and are copied into content/ alongside the assembly, preserving their folder structure:
<ItemGroup>
<PlateUpModContent Include="Assets\**" />
</ItemGroup>
Nothing is removed on Clean; the deployed folder is left alone so a clean never touches your game
installation.
Diagnostics
| Code | Meaning |
|---|---|
SFPU0001 |
PlateUp! was not found. An error, unless PlateUpInstallRequired is false. |
SFPU0002 |
A directory given as a hint holds no installation; the search continued past it. |
SFPU0003 |
A PlateUpAssembly name is not in the game's managed folder. |
SFPU0004 |
Deployment was skipped because the Mods folder is unknown, usually because discovery was turned off. |
SFPU0005 |
PlateUpModAssets points at a file that does not exist. |
Checking what was found
dotnet msbuild -t:ShowPlateUpInstall
Prints the resolved game, mods and Workshop folders, the Unity version, the Steam build id, and the reference count broken down by source.
Testing changes to this package locally
Bump the version every time you re-pack. Two things make overwriting in place unreliable:
- NuGet caches by version, so a project that already restored the old number silently keeps it — the build looks like it ignored your change, because it did.
- Rider and Visual Studio load the task assembly into a long-lived process and hold a lock on it, so re-packing over an already-restored version fails outright with an access error.
After bumping, update the consuming project's PackageReference and restore before building. In
Rider that means a solution reload or an explicit restore; its cached restore will otherwise keep
resolving the previous version. dotnet msbuild -t:ShowPlateUpInstall reports what the currently
resolved package sees, so a missing line there is a good sign you are still on an older version.
Notes for consuming projects
PlateUp! runs on Unity 2020.3 with the .NET 4.x scripting backend, so mod projects should target
net472 or netstandard2.0. Set <CopyLocalLockFileAssemblies> and <Private> carefully on your
own package references: anything the game already ships must not be copied next to the mod.
The package contains no game files. It reads them from the local installation at build time, so each developer needs their own copy of PlateUp!.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 108 | 9/3/2026 |