ModManifestBuilder automatically updates your SMAPI's manifest file using your project's properties.
Initially, this project was created so that your manifest would remain in
sync with the <Version>
property in C# project files. That way, the
built assemblies would get versions that match the manifest they're
shipped with.
Now, this project handles considerably more. You can create an entire manifest using nothing but values from your C# project file. Every single manifest value can be set, and most have a form of validation.
There are several reasons you should use ModManifestBuilder:
-
Your project file becomes the sole source of truth. For existing projects, you have some values defined in your project file but you also need to define values, a few of them identical, in the manifest. This takes care of that for you.
This is especially convenient if you develop using a single solution for many mods, as you can put several properties in a shared project file and have all your mods inherit them.
-
No more releasing debug builds by accident. Unless you disable the behavior, ModManifestBuilder will append your build configuration to the version of your mod for anything other than
Release
. This makes it easy to tell that something's off when your.zip
file has-Debug
at the end of the version. -
ModManifestBuilder has validations that are applied to every field of your mod's manifest. Of note,
MinimumApiVersion
is compared to the version of SMAPI you're building against and, by default, you'll receive a warning if it's set to a previous version.ModManifestBuilder also checks for mods that you have references to, and it'll check that the mods are declared in your dependencies, that the
MinimumVersion
is set, and that the dependency is set to required. -
You shouldn't use references if you can avoid it. Using APIs is best. But, if you need to use a reference, ModManifestBuilder makes it easier to add references as is documented below.
- Install the NuGet package..
- Set the appropriate
<Version>
in your mod's.csproj
file. - Optionally, set other supported properties in your
.csproj
file.
Going forward, your manifest.json
file should be updated automatically every
time you rebuild your project.
Property | Description |
---|---|
Manifest Properties | |
<Name> |
Name is saved to your manifest to the If no |
<Authors> |
Authors is saved to your manifest to the This field has no special handling or validation. Changed in 2.0:
|
<Description> |
Description is saved to your manifest to the This field has no special handling or validation. |
<UniqueId> |
UniqueId is saved to your manifest to the This is a required field. If no Additionally, UniqueId can only contain the characters Changed in 2.0:
|
<MinimumApiVersion> |
MinimumApiVersion is saved to your manifest to the Depending on the value of If the behavior is set to
If the behavior is set to If the MinimumApiVersion is older than the installed version of SMAPI, a
warning will be logged. If the behavior is set to Changed in 2.0:
|
<MinimumGameVersion> |
MinimumGameVersion is saved to your manifest to the Depending on the value of If the behavior is set to
If the behavior is set to If the MinimumGameVersion is older than the installed version of Stardew Valley,
a warning will be logged. If the behavior is set to Setting this to Added in 2.3 |
<UpdateKeys> |
UpdateKeys is saved to your manifest to the UpdateKeys should be a comma-separated or semi-colon separated list of update keys, and UpdateKeys should contain at least one value. Each individual update key is validated to ensure it has a valid provider, and that the mod ID is formatted correctly for that provider. See the update checks documentation for more details on update keys. Changed in 2.0:
|
<Version> |
Version is saved to your manifest to the "Version" field. If this value is not a valid semantic version, ModManifestBuilder will return an error and your project will not build.
|
Non-Manifest Properties | |
<AlwaysSetEntryDll> |
When this is enabled, When this is not enabled, Default: Added in 2.0 |
<BaseManifest> |
If BaseManifest is set, the generated manifest will use default values from a file with that name in the project directory. You can use this to load manifest values from a separate file to be saved into your manifest. If this isn't set, the default values will be loaded from
If this is set to the special value Changed in 2.0:
|
<ContentPacks_VersionBehavior> |
This controls how ModManifestBuilder interacts with By default, this is set to You can set this to Default: Added in 2.4 |
<Dependencies_AlwaysIncludeRequire> |
When this is enabled, dependencies in the generated manifest will have
their As dependencies are considered required by default, we usually leave
out
Default: Added in 2.1 |
<Dependencies_VersionBehavior> |
This value controls how version checking is handled for
Dependencies. It works similarly to
When this value is When this value is When this value is Default: Added in 2.0 Changed in 2.2:
|
<ManifestComment> |
When this is enabled, a comment will be included in the generated manifest file indicating that the file is generated/updated automatically and that it should not be modified directly. If you expect to need to parse the manifest using a strict JSON parser that does not allow comments, then this should be disabled. SMAPI allows comments in JSON files, so leaving them enabled will not present any issue using the resulting manifest with SMAPI. Default: Added in 2.1 |
<ManifestName> |
The generated manifest will be saved to a file with this name in the project
directory. By default, this is You should not change this unless you have build steps that copy the file to
|
<ManifestSchema> |
When this is enabled, a You can also set this to a custom URL, and the schema will be set to use that URL instead.
Default: Added in 2.1 |
<ManifestWarningsAsErrors> |
When this is enabled, ModManifestBuilder will emit errors instead of warnings for issues it finds with your project. This can be useful as errors prevent a build from completing, thus forcing you to fix them before you can release your project. This can be used with a condition to only enable errors when building for release by including a line like this in your project file:
Default: Added in 2.2 |
<MinimumApiVersion_Behavior> |
This value controls the behavior of Default: Added in 2.0 |
<MinimumGameVersion_Behavior> |
This value controls the behavior of Default: Added in 2.3 |
<References_VersionBehavior> |
This optional value is similar to Added in 2.1 |
<Version_AppendConfiguration> |
When this is enabled and your build configuration is not set to Release,
the configuration will be appended to Default: |
Starting in version 2.0, ModManifestBuilder has support for managing the
"Dependencies"
field of your manifest.
ModManifestBuilder will automatically check every reference used by your project for a valid SMAPI manifest. It does this by:
- Iterating through every reference in
@(ReferencePathWithRefAssemblies);@(ReferenceDependencyPaths)
- Checking for a
manifest.json
file in the same directory as the reference. - Checking that the manifest's
EntryDll
is the same file as the reference.
Assuming the checks pass, ModManifestBuilder reads the UniqueID
and Version
from the discovered manifest and ensures that:
- Your project has a dependency for the mod with that
UniqueID
. IsRequired
is set totrue
for the dependency. As a reference, the other mod is required for your project to be able to load.- The
MinimumVersion
is set appropriately, as controlled by<Dependencies_VersionBehavior>
.
You can override the
VersionBehavior
of a specific reference by setting aSMAPIDependency_VersionBehavior
on the reference.
As an example, assume you have a reference like this in your mod:
<Reference Include="DynamicGameAssets">
<HintPath>$(GameModsPath)\DynamicGameAssets\DynamicGameAssets.dll</HintPath>
<Private>false</Private>
<SMAPIDependency_VersionBehavior>Update</SMAPIDependency_VersionBehavior>
</Reference>
ModManifestBuilder will end up finding the manifest at $(GameModsPath)\DynamicGameAssets\manifest.json
,
ensure that its EntryDll
is set to DynamicGameAssets.dll
, and then ensure
that your manifest's "Dependencies"
field has an entry similar to:
{
...,
"Dependencies": [
...,
{
"UniqueID": "spacechase0.DynamicGameAssets",
"MinimumVersion": "1.4.4",
"IsRequired": true
}
]
}
Note: If a referenced mod does not have
<Private>
set tofalse
, ModManifestBuilder will log a warning. This is because a potentially private reference can be included in your project's output and you should never bundle another mod's DLLs in your own mod.
Project references are automatically processed in the same way as referenced mods with one difference regarding the discovery of manifest files.
If a manifest.json
file is not located alongside the reference's file, and
the reference has the metadata MSBuildSourceProjectFile
, then we'll check
for a manifest.json
file alongside the project file instead.
For example, if you have a mod project called TestMod
and you compile it, you
might end up with a directory structure like this:
π MySolution/
π TestMod/
π bin/
π Debug/
π net5.0/
π TestMod.dll
π manifest.json
π ModEntry.cs
π TestMod.csproj
π TestModTwo/
π MySolution.sln
After references have been resolved, your hypothetical project would have a
reference to the file MySolution/TestMod/bin/Debug/net5.0/TestMod.dll
but
it's manifest isn't in that folder.
That reference would have MSBuildSourceProjectFile
metadata with the path
to the file MySolution/TestMod/TestMod.csproj
so we can check for a manifest
at that path as well, though we still check that EntryDll
matches the name
of the reference itself.
Finally, ModManifestBuilder adds a new tag that represents a mod that your
project depends on. <SMAPIDependency>
tags should be added as children of
an <ItemGroup>
in your project file.
The <SMAPIDependency>
tag supports the following properties:
Property | Description |
---|---|
Include |
This is required, and should be set to the unique mod ID of the mod you depend on. |
Version |
Optional string. This should be a valid semantic version representing the minimum version of the mod that your project supports.
|
VersionBehavior |
Optional enum value. Setting a Added in 2.1 |
Required |
Optional boolean. Whether or not this mod is required for your project to
function. This is saved to the
|
Reference |
Optional boolean. If this is set to true, a reference will be automatically added to your project for this mod. This presents a slightly easier way to add references to other mods. If this is true, If this is set to true and the required mod cannot be found, or if the required
mod is found but its version is older than the version in |
Assembly |
Optional string. This does nothing if By default, this is set to the name of the mod's |
As an example, the following dependency block will add a reference to the mod SpaceCore and an optional dependency for the mod GenericModConfigMenu:
<ItemGroup>
<SMAPIDependency Include="spacechase0.SpaceCore" Version="1.10" Reference="true" />
<SMAPIDependency Include="spacechase0.GenericModConfigMenu" Version="1.9" Required="false" />
</ItemGroup>
That would result in the following entries being added to your manifest's
"Dependencies"
field:
{
"Dependencies": [
{
"UniqueID": "spacechase0.GenericModConfigMenu",
"MinimumVersion": "1.9",
"IsRequired": false
},
{
"UniqueID": "spacechase0.SpaceCore",
"MinimumVersion": "1.10",
"IsRequired": true
}
]
}
The entry for SpaceCore is also roughly equivalent to adding the following block to your project file:
<ItemGroup>
<Reference Include="SpaceCore">
<HintPath>$(GameModsPath)\SpaceCore\SpaceCore.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
When working on this project, you'll likely find that you're unable to compile
ModManifestBuilder. This is because msbuild
does not close immediately, and
it maintains locks on DLL files that tasks were loaded from.
In order to compile ModManifestBuilder, please first kill all running instances
of msbuild
. If you're on windows, the following command works:
taskkill /f /im msbuild.exe