summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/README.md43
-rw-r--r--docs/mod-build-config.md284
-rw-r--r--docs/release-notes.md200
-rw-r--r--docs/technical-docs.md232
-rw-r--r--docs/technical/mod-package.md366
-rw-r--r--docs/technical/screenshots/code-analyzer-example.png (renamed from docs/screenshots/code-analyzer-example.png)bin3473 -> 3473 bytes
-rw-r--r--docs/technical/smapi.md116
-rw-r--r--docs/technical/web.md380
8 files changed, 1073 insertions, 548 deletions
diff --git a/docs/README.md b/docs/README.md
index e4220de2..ddde6b09 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -19,11 +19,14 @@ doesn't change any of your game files. It serves eight main purposes:
_SMAPI detects when a mod accesses part of the game that changed in a game update which affects
many mods, and rewrites the mod so it's compatible._
-5. **Intercept errors.**
- _SMAPI intercepts errors that happen in the game, displays the error details in the console
- window, and in most cases automatically recovers the game. This prevents mods from accidentally
- crashing the game, and makes it possible to troubleshoot errors in the game itself that would
- otherwise show a generic 'program has stopped working' type of message._
+5. **Intercept errors and automatically fix saves.**
+ _SMAPI intercepts errors, shows the error info in the SMAPI console, and in most cases
+ automatically recovers the game. That prevents mods from crashing the game, and makes it
+ possible to troubleshoot errors in the game itself that would otherwise show a generic 'program
+ has stopped working' type of message._
+
+ _SMAPI also automatically fixes save data in some cases when a load would crash, e.g. due to a
+ custom location or NPC mod that was removed._
6. **Provide update checks.**
_SMAPI automatically checks for new versions of your installed mods, and notifies you when any
@@ -38,16 +41,36 @@ doesn't change any of your game files. It serves eight main purposes:
something goes wrong. (Via the bundled SaveBackup mod.)_
## Documentation
-Have questions? Come [chat on Discord](https://discord.gg/KCJHWhX) with SMAPI developers and other
-modders!
+Have questions? Come [ask the community](https://smapi.io/community) to get help from SMAPI
+developers and other modders!
### For players
* [Player guide](https://stardewvalleywiki.com/Modding:Player_Guide)
### For modders
-* [Modding documentation](https://stardewvalleywiki.com/Modding:Index)
-* [Mod build configuration](mod-build-config.md)
+* [Modding documentation](https://smapi.io/docs)
+* [Mod build configuration](technical/mod-package.md)
* [Release notes](release-notes.md)
### For SMAPI developers
-* [Technical docs](technical-docs.md)
+* [Technical docs](technical/smapi.md)
+
+## Translating SMAPI
+SMAPI rarely shows text in-game, so it only has a few translations. Contributions are welcome! See
+[Modding:Translations](https://stardewvalleywiki.com/Modding:Translations) on the wiki for help
+contributing translations.
+
+locale | status
+---------- | :----------------
+default | ✓ [fully translated](../src/SMAPI/i18n/default.json)
+Chinese | ❑ not translated
+French | ❑ not translated
+German | ✓ [fully translated](../src/SMAPI/i18n/de.json)
+Hungarian | ❑ not translated
+Italian | ❑ not translated
+Japanese | ❑ not translated
+Korean | ❑ not translated
+Portuguese | ❑ not translated
+Russian | ❑ not translated
+Spanish | ❑ not translated
+Turkish | ❑ not translated
diff --git a/docs/mod-build-config.md b/docs/mod-build-config.md
index a97c3171..4ec83e93 100644
--- a/docs/mod-build-config.md
+++ b/docs/mod-build-config.md
@@ -1,283 +1 @@
-The **mod build package** is an open-source NuGet package which automates the MSBuild configuration
-for SMAPI mods.
-
-The package...
-
-* detects your game install path;
-* adds the assembly references you need (with automatic support for Linux/Mac/Windows);
-* packages the mod into your `Mods` folder when you rebuild the code (configurable);
-* configures Visual Studio to enable debugging into the code when the game is running (_Windows only_);
-* adds C# analyzers to warn for Stardew Valley-specific issues.
-
-## Contents
-* [Install](#install)
-* [Configure](#configure)
-* [Code analysis warnings](#code-analysis-warnings)
-* [Troubleshoot](#troubleshoot)
-* [Release notes](#release-notes)
-
-## Install
-**When creating a new mod:**
-
-1. Create an empty library project.
-2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
-3. [Write your code](https://stardewvalleywiki.com/Modding:Creating_a_SMAPI_mod).
-4. Compile on any platform.
-
-**When migrating an existing mod:**
-
-1. Remove any project references to `Microsoft.Xna.*`, `MonoGame`, Stardew Valley,
- `StardewModdingAPI`, and `xTile`.
-2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
-3. Compile on any platform.
-
-## Configure
-### Deploy files into the `Mods` folder
-By default, your mod will be copied into the game's `Mods` folder (with a subfolder matching your
-project name) when you rebuild the code. The package will automatically include your
-`manifest.json`, any `i18n` files, and the build output.
-
-To add custom files to the mod folder, just [add them to the build output](https://stackoverflow.com/a/10828462/262123).
-(If your project references another mod, make sure the reference is [_not_ marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).)
-
-You can change the mod's folder name by adding this above the first `</PropertyGroup>` in your
-`.csproj`:
-```xml
-<ModFolderName>YourModName</ModFolderName>
-```
-
-If you don't want to deploy the mod automatically, you can add this:
-```xml
-<EnableModDeploy>False</EnableModDeploy>
-```
-
-### Create release zip
-By default, a zip file will be created in the build output when you rebuild the code. This zip file
-contains all the files needed to share your mod in the recommended format for uploading to Nexus
-Mods or other sites.
-
-You can change the zipped folder name (and zip name) by adding this above the first
-`</PropertyGroup>` in your `.csproj`:
-```xml
-<ModFolderName>YourModName</ModFolderName>
-```
-
-You can change the folder path where the zip is created like this:
-```xml
-<ModZipPath>$(SolutionDir)\_releases</ModZipPath>
-```
-
-Finally, you can disable the zip creation with this:
-```xml
-<EnableModZip>False</EnableModZip>
-```
-
-Or only create it in release builds with this:
-```xml
-<EnableModZip Condition="$(Configuration) != 'Release'">False</EnableModZip>
-```
-
-### Game path
-The package usually detects where your game is installed automatically. If it can't find your game
-or you have multiple installs, you can specify the path yourself. There's two ways to do that:
-
-* **Option 1: global game path (recommended).**
- _This will apply to every project that uses the package._
-
- 1. Get the full folder path containing the Stardew Valley executable.
- 2. Create this file:
-
- platform | path
- --------- | ----
- Linux/Mac | `~/stardewvalley.targets`
- Windows | `%USERPROFILE%\stardewvalley.targets`
-
- 3. Save the file with this content:
-
- ```xml
- <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <GamePath>PATH_HERE</GamePath>
- </PropertyGroup>
- </Project>
- ```
-
- 4. Replace `PATH_HERE` with your game path.
-
-* **Option 2: path in the project file.**
- _You'll need to do this for each project that uses the package._
-
- 1. Get the folder path containing the Stardew Valley `.exe` file.
- 2. Add this to your `.csproj` file under the `<Project` line:
-
- ```xml
- <PropertyGroup>
- <GamePath>PATH_HERE</GamePath>
- </PropertyGroup>
- ```
-
- 3. Replace `PATH_HERE` with your custom game install path.
-
-The configuration will check your custom path first, then fall back to the default paths (so it'll
-still compile on a different computer).
-
-### Ignore files
-If you don't want to include a file in the mod folder or release zip:
-* Make sure it's not copied to the build output. For a DLL, make sure the reference is [not marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).
-* Or add this to your `.csproj` file under the `<Project` line:
- ```xml
- <IgnoreModFilePatterns>\.txt$, \.pdf$</IgnoreModFilePatterns>
- ```
- This is a comma-delimited list of regular expression patterns. If any pattern matches a file's
- relative path in your mod folder, that file won't be included.
-
-### Non-mod projects
-You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). You'll need to
-disable deploying the mod and creating a release zip:
-
-```xml
-<EnableModDeploy>False</EnableModDeploy>
-<EnableModZip>False</EnableModZip>
-```
-
-If this is for unit tests, you may need to copy the referenced DLLs into your build output too:
-```xml
-<CopyModReferencesToBuildOutput>True</CopyModReferencesToBuildOutput>
-```
-
-## Code warnings
-### Overview
-The NuGet package adds code warnings in Visual Studio specific to Stardew Valley. For example:
-![](screenshots/code-analyzer-example.png)
-
-You can hide the warnings using the warning ID (shown under 'code' in the Error List). See...
-* [for specific code](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma-warning);
-* for a method using this attribute:
- ```cs
- [System.Diagnostics.CodeAnalysis.SuppressMessage("SMAPI.CommonErrors", "AvoidNetField")]
- ```
-* for an entire project:
- 1. Expand the _References_ node for the project in Visual Studio.
- 2. Right-click on _Analyzers_ and choose _Open Active Rule Set_.
- 4. Expand _StardewModdingAPI.ModBuildConfig.Analyzer_ and uncheck the warnings you want to hide.
-
-See below for help with each specific warning.
-
-### Avoid implicit net field cast
-Warning text:
-> This implicitly converts '{{expression}}' from {{net type}} to {{other type}}, but
-> {{net type}} has unintuitive implicit conversion rules. Consider comparing against the actual
-> value instead to avoid bugs.
-
-Stardew Valley uses net types (like `NetBool` and `NetInt`) to handle multiplayer sync. These types
-can implicitly convert to their equivalent normal values (like `bool x = new NetBool()`), but their
-conversion rules are unintuitive and error-prone. For example,
-`item?.category == null && item?.category != null` can both be true at once, and
-`building.indoors != null` can be true for a null value.
-
-Suggested fix:
-* Some net fields have an equivalent non-net property like `monster.Health` (`int`) instead of
- `monster.health` (`NetInt`). The package will add a separate [AvoidNetField](#avoid-net-field) warning for
- these. Use the suggested property instead.
-* For a reference type (i.e. one that can contain `null`), you can use the `.Value` property:
- ```c#
- if (building.indoors.Value == null)
- ```
- Or convert the value before comparison:
- ```c#
- GameLocation indoors = building.indoors;
- if(indoors == null)
- // ...
- ```
-* For a value type (i.e. one that can't contain `null`), check if the object is null (if applicable)
- and compare with `.Value`:
- ```cs
- if (item != null && item.category.Value == 0)
- ```
-
-### Avoid net field
-Warning text:
-> '{{expression}}' is a {{net type}} field; consider using the {{property name}} property instead.
-
-Your code accesses a net field, which has some unusual behavior (see [AvoidImplicitNetFieldCast](#avoid-implicit-net-field-cast)).
-This field has an equivalent non-net property that avoids those issues.
-
-Suggested fix: access the suggested property name instead.
-
-### Avoid obsolete field
-Warning text:
-> The '{{old field}}' field is obsolete and should be replaced with '{{new field}}'.
-
-Your code accesses a field which is obsolete or no longer works. Use the suggested field instead.
-
-## Troubleshoot
-### "Failed to find the game install path"
-That error means the package couldn't find your game. You can specify the game path yourself; see
-_[Game path](#game-path)_ above.
-
-## Release notes
-### 2.2
-* Added support for SMAPI 2.8+ (still compatible with earlier versions).
-* Added default game paths for 32-bit Windows.
-* Fixed valid manifests marked invalid in some cases.
-
-### 2.1
-* Added support for Stardew Valley 1.3.
-* Added support for non-mod projects.
-* Added C# analyzers to warn about implicit conversions of Netcode fields in Stardew Valley 1.3.
-* Added option to ignore files by regex pattern.
-* Added reference to new SMAPI DLL.
-* Fixed some game paths not detected by NuGet package.
-
-### 2.0.2
-* Fixed compatibility issue on Linux.
-
-### 2.0.1
-* Fixed mod deploy failing to create subfolders if they don't already exist.
-
-### 2.0
-* Added: mods are now copied into the `Mods` folder automatically (configurable).
-* Added: release zips are now created automatically in your build output folder (configurable).
-* Added: mod deploy and release zips now exclude Json.NET automatically, since it's provided by SMAPI.
-* Added mod's version to release zip filename.
-* Improved errors to simplify troubleshooting.
-* Fixed release zip not having a mod folder.
-* Fixed release zip failing if mod name contains characters that aren't valid in a filename.
-
-### 1.7.1
-* Fixed issue where i18n folders were flattened.
-* The manifest/i18n files in the project now take precedence over those in the build output if both
- are present.
-
-### 1.7
-* Added option to create release zips on build.
-* Added reference to XNA's XACT library for audio-related mods.
-
-### 1.6
-* Added support for deploying mod files into `Mods` automatically.
-* Added a build error if a game folder is found, but doesn't contain Stardew Valley or SMAPI.
-
-### 1.5
-* Added support for setting a custom game path globally.
-* Added default GOG path on Mac.
-
-### 1.4
-* Fixed detection of non-default game paths on 32-bit Windows.
-* Removed support for SilVerPLuM (discontinued).
-* Removed support for overriding the target platform (no longer needed since SMAPI crossplatforms
- mods automatically).
-
-### 1.3
-* Added support for non-default game paths on Windows.
-
-### 1.2
-* Exclude game binaries from mod build output.
-
-### 1.1
-* Added support for overriding the target platform.
-
-### 1.0
-* Initial release.
-* Added support for detecting the game path automatically.
-* Added support for injecting XNA/MonoGame references automatically based on the OS.
-* Added support for mod builders like SilVerPLuM.
+[Documentation moved](technical/mod-package.md).
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 5a7d5ef2..a891c495 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -1,4 +1,155 @@
+&larr; [README](README.md)
+
# Release notes
+## 3.0
+Released 26 November 2019 for Stardew Valley 1.4.
+
+### Release highlights
+For players:
+* **Updated for Stardew Valley 1.4.**
+ SMAPI 3.0 adds compatibility with the latest game version, and improves mod APIs for changes in
+ the game code.
+
+* **Improved performance.**
+ SMAPI should have less impact on game performance and startup time for some players.
+
+* **Automatic save fixing and more error recovery.**
+ SMAPI now detects and prevents more crashes due to game/mod bugs, and automatically fixes your
+ save if you remove some custom-content mods.
+
+* **Improved mod scanning.**
+ SMAPI now supports some non-standard mod structures automatically, improves compatibility with
+ the Vortex mod manager, and improves various error/skip messages related to mod loading.
+
+* **Overhauled update checks.**
+ SMAPI update checks are now handled entirely on the web server and support community-defined
+ version mappings. In particular, false update alerts due to author mistakes can now be solved by
+ the community for all players.
+
+* **Fixed many bugs and edge cases.**
+
+For modders:
+* **New event system.**
+ SMAPI 3.0 removes the deprecated static events in favor of the new `helper.Events` API. The event
+ engine is rewritten to make events more efficient, add events that weren't possible before, make
+ existing events more useful, and make event usage and behavior more consistent. When a mod makes
+ changes in an event handler, those changes are now also reflected in the next event raise.
+
+* **Improved mod build package.**
+ The [mod build package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig) now
+ includes the `assets` folder by default if present, supports the new `.csproj` project format,
+ enables mod `.pdb` files automatically (to provide line numbers in error messages), adds optional
+ Harmony support, and fixes some bugs and edge cases. This also adds compatibility with SMAPI 3.0
+ and Stardew Valley 1.4, and drops support for older versions.
+
+* **Mods loaded earlier.**
+ SMAPI now loads mods much earlier, before the game is initialised. That lets mods do things that
+ were difficult before, like intercepting some core assets.
+
+* **Improved Android support.**
+ SMAPI now automatically detects when it's running on Android, and updates `Constants.TargetPlatform`
+ so mods can adjust their logic if needed. The Save Backup mod is also now Android-compatible.
+
+* **Improved asset propagation.**
+ SMAPI now automatically propagates asset changes for farm animal data, NPC default location data,
+ critter textures, and `DayTimeMoneyBox` buttons. Every loaded texture now also has a `Name` field
+ so mods can check which asset a texture was loaded for.
+
+* **Breaking changes:**
+ See _[migrate to SMAPI 3.0](https://stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0)_ and
+ _[migrate to Stardew Valley 1.4](https://stardewvalleywiki.com/Modding:Migrate_to_Stardew_Valley_1.4)_
+ for more info.
+
+### For players
+* Changes:
+ * Updated for Stardew Valley 1.4.
+ * Improved performance.
+ * Reworked update checks and added community-defined version mapping, to reduce false update alerts due to author mistakes.
+ * SMAPI now removes invalid locations/NPCs when loading a save to prevent crashes. A warning is shown in-game when this happens.
+ * Added update checks for CurseForge mods.
+ * Added support for editing console colors via `smapi-internal/config.json` (for players with unusual consoles).
+ * Added support for setting SMAPI CLI arguments as environment variables for Linux/macOS compatibility.
+ * Improved mod scanning:
+ * Now ignores metadata files/folders (like `__MACOSX` and `__folder_managed_by_vortex`) and content files (like `.txt` or `.png`), which avoids missing-manifest errors in some cases.
+ * Now detects XNB mods more accurately, and consolidates multi-folder XNB mods in logged messages.
+ * Improved launch script compatibility on Linux (thanks to kurumushi and toastal!).
+ * Made error messages more user-friendly in some cases.
+ * Save Backup now works in the background, to avoid affecting startup time for players with a large number of saves.
+ * The installer now recognises custom game paths stored in [`stardewvalley.targets`](http://smapi.io/package/custom-game-path).
+ * Duplicate-mod errors now show the mod version in each folder.
+ * Update checks are now faster in some cases.
+ * Updated mod compatibility list.
+ * Updated SMAPI/game version map.
+* Fixes:
+ * Fixed some assets not updated when you switch language to English.
+ * Fixed lag in some cases due to incorrect asset caching when playing in non-English.
+ * Fixed lag when a mod invalidates many NPC portraits/sprites at once.
+ * Fixed Console Commands not including upgraded tools in item commands.
+ * Fixed Console Commands' item commands failing if a mod adds invalid item data.
+ * Fixed Save Backup not pruning old backups if they're uncompressed.
+ * Fixed issues when a farmhand reconnects before the game notices they're disconnected.
+ * Fixed 'received message' logs shown in non-developer mode.
+ * Fixed various error messages and inconsistent spelling.
+ * Fixed update-check error if a Nexus mod is marked as adult content.
+ * Fixed update-check error if the Chucklefish page for an update key doesn't exist.
+
+### For the web UI
+* Mod compatibility list:
+ * Added support for CurseForge mods.
+ * Added metadata links and dev notes (if any) to advanced info.
+ * Now loads faster (since data is fetched in a background service).
+ * Now continues working with cached data when the wiki is offline.
+ * Clicking a mod link now automatically adds it to the visible mods if the list is filtered.
+
+* JSON validator:
+ * Added JSON validator at [json.smapi.io](https://json.smapi.io), which lets you validate a JSON file against predefined mod formats.
+ * Added support for the `manifest.json` format.
+ * Added support for the Content Patcher format (thanks to TehPers!).
+ * Added support for referencing a schema in a JSON Schema-compatible text editor.
+
+* For the log parser:
+ * Added instructions for Android.
+ * The page now detects your OS and preselects the right instructions (thanks to danvolchek!).
+
+### For modders
+* Breaking changes:
+ * Mods are now loaded much earlier in the game launch. This lets mods intercept any content asset, but the game is not fully initialized when `Entry` is called; use the `GameLaunched` event if you need to run code when the game is initialized.
+ * Removed all deprecated APIs.
+ * Removed unused APIs: `Monitor.ExitGameImmediately`, `Translation.ModName`, and `Translation.Assert`.
+ * Fixed `ICursorPosition.AbsolutePixels` not adjusted for zoom.
+ * `SemanticVersion` no longer omits `.0` patch numbers when formatting versions, for better [semver](https://semver.org/) conformity (e.g. `3.0` is now formatted as `3.0.0`).
+* Changes:
+ * Added support for content pack translations.
+ * Added `IContentPack.HasFile`, `Context.IsGameLaunched`, and `SemanticVersion.TryParse`.
+ * Added separate `LogNetworkTraffic` option to make verbose logging less overwhelmingly verbose.
+ * Added asset propagation for `Data\FarmAnimals`, critter textures, and `DayTimeMoneyBox` buttons.
+ * Added `Texture2D.Name` values set to the asset key.
+ * Added trace logs for skipped loose files in the `Mods` folder and custom SMAPI settings so it's easier to troubleshoot player logs.
+ * `Constants.TargetPlatform` now returns `Android` when playing on an Android device.
+ * Trace logs for a broken mod now list all detected issues (instead of the first one).
+ * Trace logs when loading mods are now more clear.
+ * Clarified update-check errors for mods with multiple update keys.
+ * Updated dependencies (including Json.NET 11.0.2 → 12.0.3 and Mono.Cecil 0.10.1 → 0.11.1).
+* Fixes:
+ * Fixed map reloads resetting tilesheet seasons.
+ * Fixed map reloads not updating door warps.
+ * Fixed outdoor tilesheets being seasonalised when added to an indoor location.
+ * Fixed mods needing to load custom `Map` assets before the game accesses them. SMAPI now does so automatically.
+ * Fixed custom maps loaded from `.xnb` files not having their tilesheet paths automatically adjusted.
+ * Fixed custom maps loaded from the mod folder with tilesheets in a subfolder not working crossplatform. All tilesheet paths are now normalized for the OS automatically.
+ * Fixed issue where mod changes weren't tracked correctly for raising events in some cases. Events now reflect a frozen snapshot of the game state, and any mod changes are reflected in the next event tick.
+ * Fixed issue where, when a mod's `IAssetEditor` uses `asset.ReplaceWith` on a texture asset while playing in non-English, any changes from that point forth wouldn't affect subsequent cached asset loads.
+ * Fixed asset propagation for NPC portraits resetting any unique portraits (e.g. Maru's hospital portrait) to the default.
+ * Fixed changes to `Data\NPCDispositions` not always propagated correctly to existing NPCs.
+ * Fixed `Rendering`/`Rendered` events not raised during minigames.
+ * Fixed `LoadStageChanged` event not raising correct flags in some cases when creating a new save.
+ * Fixed `GetApi` without an interface not checking if all mods are loaded.
+
+### For SMAPI maintainers
+* Added support for core translation files.
+* Migrated to new `.csproj` format.
+* Internal refactoring.
+
## 2.11.3
Released 13 September 2019 for Stardew Valley 1.3.36.
@@ -12,11 +163,14 @@ Released 13 September 2019 for Stardew Valley 1.3.36.
* For the web UI:
* When filtering the mod list, clicking a mod link now automatically adds it to the visible mods.
* Added log parser instructions for Android.
- * Fixed log parser failing in some cases due to time format localisation.
+ * Fixed log parser failing in some cases due to time format localization.
* For modders:
* `this.Monitor.Log` now defaults to the `Trace` log level instead of `Debug`. The change will only take effect when you recompile the mod.
* Fixed 'location list changed' verbose log not correctly listing changes.
+ * Fixed mods able to directly load (and in some cases edit) a different mod's local assets using internal asset key forwarding.
+ * Fixed changes to a map loaded by a mod being persisted across content managers.
+ * Fixed `SDate.AddDays` incorrectly changing year when the result is exactly winter 28.
## 2.11.2
Released 23 April 2019 for Stardew Valley 1.3.36.
@@ -77,12 +231,12 @@ Released 09 January 2019 for Stardew Valley 1.3.32–33.
* Added locale to context trace logs.
* Fixed error loading custom map tilesheets in some cases.
* Fixed error when swapping maps mid-session for a location with interior doors.
- * Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialised.LoadStageChanged` event.
+ * Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialized.LoadStageChanged` event.
* Fixed `LoadStage.SaveParsed` raised before the parsed save data is available.
* Fixed 'unknown mod' deprecation warnings showing the wrong stack trace.
* Fixed `e.Cursor` in input events showing wrong grab tile when player using a controller moves without moving the viewpoint.
- * Fixed incorrect 'bypassed safety checks' warning for mods using the new `Specialised.LoadStageChanged` event in 2.10.
- * Deprecated `EntryDll` values whose capitalisation don't match the actual file. (This works on Windows, but causes errors for Linux/Mac players.)
+ * Fixed incorrect 'bypassed safety checks' warning for mods using the new `Specialized.LoadStageChanged` event in 2.10.
+ * Deprecated `EntryDll` values whose capitalization don't match the actual file. (This works on Windows, but causes errors for Linux/Mac players.)
## 2.10.1
Released 30 December 2018 for Stardew Valley 1.3.32–33.
@@ -99,9 +253,9 @@ Released 29 December 2018 for Stardew Valley 1.3.32–33.
* Tweaked installer to reduce antivirus false positives.
* For modders:
- * Added [events](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events): `GameLoop.OneSecondUpdateTicking`, `GameLoop.OneSecondUpdateTicked`, and `Specialised.LoadStageChanged`.
+ * Added [events](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events): `GameLoop.OneSecondUpdateTicking`, `GameLoop.OneSecondUpdateTicked`, and `Specialized.LoadStageChanged`.
* Added `e.IsCurrentLocation` event arg to `World` events.
- * You can now use `helper.Data.Read/WriteSaveData` as soon as the save is loaded (instead of once the world is initialised).
+ * You can now use `helper.Data.Read/WriteSaveData` as soon as the save is loaded (instead of once the world is initialized).
* Increased deprecation levels to _info_ for the upcoming SMAPI 3.0.
* For the web UI:
@@ -274,7 +428,7 @@ Released 14 August 2018 for Stardew Valley 1.3.28.
* dialogue;
* map tilesheets.
* Added `--mods-path` CLI command-line argument to switch between mod folders.
- * All enums are now JSON-serialised by name instead of numeric value. (Previously only a few enums were serialised that way. JSON files which already have numeric enum values will still be parsed fine.)
+ * All enums are now JSON-serialized by name instead of numeric value. (Previously only a few enums were serialized that way. JSON files which already have numeric enum values will still be parsed fine.)
* Fixed false compatibility error when constructing multidimensional arrays.
* Fixed `.ToSButton()` methods not being public.
@@ -301,7 +455,7 @@ Released 01 August 2018 for Stardew Valley 1.3.27.
* Improved the Console Commands mod:
* Added `player_add name`, which adds items to your inventory by name instead of ID.
* Fixed `world_setseason` not running season-change logic.
- * Fixed `world_setseason` not normalising the season value.
+ * Fixed `world_setseason` not normalizing the season value.
* Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed).
* Removed the `player_setlevel` and `player_setspeed` commands, which weren't implemented in a useful way. Use a mod like CJB Cheats Menu if you need those.
* Fixed `SEHException` errors for some players.
@@ -392,7 +546,7 @@ Released 11 April 2018 for Stardew Valley 1.2.30–1.2.33.
* Fixed mod update alerts not shown if one mod has an invalid remote version.
* Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io).
* Fixed SMAPI update alerts for draft releases.
- * Fixed error when two content packs use different capitalisation for the same required mod ID.
+ * Fixed error when two content packs use different capitalization for the same required mod ID.
* Fixed rare crash if the game duplicates an item.
* For the [log parser](https://log.smapi.io):
@@ -467,8 +621,8 @@ Released 24 February 2018 for Stardew Valley 1.2.30–1.2.33.
* For modders:
* Added support for content packs and new APIs to read them.
* Added support for `ISemanticVersion` in JSON models.
- * Added `SpecialisedEvents.UnvalidatedUpdateTick` event for specialised use cases.
- * Added path normalising to `ReadJsonFile` and `WriteJsonFile` helpers (so no longer need `Path.Combine` with those).
+ * Added `SpecializedEvents.UnvalidatedUpdateTick` event for specialized use cases.
+ * Added path normalizing to `ReadJsonFile` and `WriteJsonFile` helpers (so no longer need `Path.Combine` with those).
* Fixed deadlock in rare cases with asset loaders.
* Fixed unhelpful error when a mod exposes a non-public API.
* Fixed unhelpful error when a translation file has duplicate keys due to case-insensitivity.
@@ -521,11 +675,11 @@ Released 26 December 2017 for Stardew Valley 1.2.30–1.2.33.
* For modders:
* **Added mod-provided APIs** to allow simple integrations between mods, even without direct assembly references.
- * Added `GameEvents.FirstUpdateTick` event (called once after all mods are initialised).
+ * Added `GameEvents.FirstUpdateTick` event (called once after all mods are initialized).
* Added `IsSuppressed` to input events so mods can optionally avoid handling keys another mod has already handled.
* Added trace message for mods with no update keys.
* Adjusted reflection API to match actual usage (e.g. renamed `GetPrivate*` to `Get*`), and deprecated previous methods.
- * Fixed `GraphicsEvents.OnPostRenderEvent` not being raised in some specialised cases.
+ * Fixed `GraphicsEvents.OnPostRenderEvent` not being raised in some specialized cases.
* Fixed reflection API error for properties missing a `get` and `set`.
* Fixed issue where a mod could change the cursor position reported to other mods.
* Updated compatibility list.
@@ -550,7 +704,7 @@ Released 02 December 2017 for Stardew Valley 1.2.30–1.2.33.
* Slightly improved the UI.
* For modders:
- * Added `helper.Content.NormaliseAssetName` method.
+ * Added `helper.Content.NormalizeAssetName` method.
* Added `SDate.DaysSinceStart` property.
* Fixed input events' `e.SuppressButton(button)` method ignoring specified button.
* Fixed input events' `e.SuppressButton()` method not working with mouse buttons.
@@ -634,7 +788,7 @@ Released 14 October 2017 for Stardew Valley 1.2.30–1.2.33.
* **Command-line install**
For power users and mod managers, the SMAPI installer can now be scripted using command-line arguments
- (see [technical docs](technical-docs.md#command-line-arguments)).
+ (see [technical docs](technical/smapi.md#command-line-arguments)).
### Change log
For players:
@@ -705,7 +859,7 @@ For mod developers:
* Added content helper properties for the game's current language.
* Fixed `Context.IsPlayerFree` being false if the player is performing an action.
* Fixed `GraphicsEvents.Resize` being raised before the game updates its window data.
-* Fixed `SemanticVersion` not being deserialisable through Json.NET.
+* Fixed `SemanticVersion` not being deserializable through Json.NET.
* Fixed terminal not launching on Xfce Linux.
For SMAPI developers:
@@ -776,7 +930,7 @@ For modders:
* SMAPI now automatically fixes tilesheet references for maps loaded from the mod folder.
<small>_When loading a map from the mod folder, SMAPI will automatically use tilesheets relative to the map file if they exists. Otherwise it will default to tilesheets in the game content._</small>
* Added `Context.IsPlayerFree` for mods that need to check if the player can act (i.e. save is loaded, no menu is displayed, no cutscene is in progress, etc).
-* Added `Context.IsInDrawLoop` for specialised mods.
+* Added `Context.IsInDrawLoop` for specialized mods.
* Fixed `smapi-crash.txt` being copied from the default log even if a different path is specified with `--log-path`.
* Fixed the content API not matching XNB filenames with two dots (like `a.b.xnb`) if you don't specify the `.xnb` extension.
* Fixed `debug` command output not printed to console.
@@ -803,7 +957,7 @@ For players:
For mod developers:
* Added a `Context.IsWorldReady` flag for mods to use.
- <small>_This indicates whether a save is loaded and the world is finished initialising, which starts at the same point that `SaveEvents.AfterLoad` and `TimeEvents.AfterDayStarted` are raised. This is mainly useful for events which can be raised before the world is loaded (like update tick)._</small>
+ <small>_This indicates whether a save is loaded and the world is finished initializing, which starts at the same point that `SaveEvents.AfterLoad` and `TimeEvents.AfterDayStarted` are raised. This is mainly useful for events which can be raised before the world is loaded (like update tick)._</small>
* Added a `debug` console command which lets you run the game's debug commands (e.g. `debug warp FarmHouse 1 1` warps you to the farmhouse).
* Added basic context info to logs to simplify troubleshooting.
* Added a `Mod.Dispose` method which can be overriden to clean up before exit. This method isn't guaranteed to be called on every exit.
@@ -841,8 +995,8 @@ For players:
For mod developers:
* Added a content API which loads custom textures/maps/data from the mod's folder (`.xnb` or `.png` format) or game content.
* `Console.Out` messages are now written to the log file.
-* `Monitor.ExitGameImmediately` now aborts SMAPI initialisation and events more quickly.
-* Fixed value-changed events being raised when the player loads a save due to values being initialised.
+* `Monitor.ExitGameImmediately` now aborts SMAPI initialization and events more quickly.
+* Fixed value-changed events being raised when the player loads a save due to values being initialized.
## 1.10
Released 24 April 2017 for Stardew Valley 1.2.26.
@@ -858,7 +1012,7 @@ For players:
* Replaced `player_addmelee` with `player_addweapon` with support for non-melee weapons.
For mod developers:
-* Mods are now initialised after the `Initialize`/`LoadContent` phase, which means the `GameEvents.Initialize` and `GameEvents.LoadContent` events are deprecated. You can move any logic in those methods to your mod's `Entry` method.
+* Mods are now initialized after the `Initialize`/`LoadContent` phase, which means the `GameEvents.Initialize` and `GameEvents.LoadContent` events are deprecated. You can move any logic in those methods to your mod's `Entry` method.
* Added `IsBetween` and string overloads to the `ISemanticVersion` methods.
* Fixed mouse-changed event never updating prior mouse position.
* Fixed `monitor.ExitGameImmediately` not working correctly.
@@ -897,7 +1051,7 @@ For mod developers:
* The SMAPI log now has a simpler filename.
* The SMAPI log now shows the OS caption (like "Windows 10") instead of its internal version when available.
* The SMAPI log now always uses `\r\n` line endings to simplify crossplatform viewing.
-* Fixed `SaveEvents.AfterLoad` being raised during the new-game intro before the player is initialised.
+* Fixed `SaveEvents.AfterLoad` being raised during the new-game intro before the player is initialized.
* Fixed SMAPI not recognising `Mod` instances that don't subclass `Mod` directly.
* Several obsolete APIs have been removed (see [migration guides](https://stardewvalleywiki.com/Modding:Index#Migration_guides)),
and all _notice_-level deprecations have been increased to _info_.
@@ -942,7 +1096,7 @@ For mod developers:
* Added a mod registry which provides metadata about loaded mods.
* The `Entry(…)` method is now deferred until all mods are loaded.
* Fixed `SaveEvents.BeforeSave` and `.AfterSave` not triggering on days when the player shipped something.
-* Fixed `PlayerEvents.LoadedGame` and `SaveEvents.AfterLoad` being fired before the world finishes initialising.
+* Fixed `PlayerEvents.LoadedGame` and `SaveEvents.AfterLoad` being fired before the world finishes initializing.
* Fixed some `LocationEvents`, `PlayerEvents`, and `TimeEvents` being fired during game startup.
* Increased deprecation levels for `SObject`, `LogWriter` (not `Log`), and `Mod.Entry(ModHelper)` (not `Mod.Entry(IModHelper)`) to _pending removal_. Increased deprecation levels for `Mod.PerSaveConfigFolder`, `Mod.PerSaveConfigPath`, and `Version.VersionString` to _info_.
diff --git a/docs/technical-docs.md b/docs/technical-docs.md
deleted file mode 100644
index 98dd3540..00000000
--- a/docs/technical-docs.md
+++ /dev/null
@@ -1,232 +0,0 @@
-&larr; [README](README.md)
-
-This file provides more technical documentation about SMAPI. If you only want to use or create
-mods, this section isn't relevant to you; see the main README to use or create mods.
-
-# Contents
-* [SMAPI](#smapi)
- * [Development](#development)
- * [Compiling from source](#compiling-from-source)
- * [Debugging a local build](#debugging-a-local-build)
- * [Preparing a release](#preparing-a-release)
- * [Customisation](#customisation)
- * [Configuration file](#configuration-file)
- * [Command-line arguments](#command-line-arguments)
- * [Compile flags](#compile-flags)
-* [SMAPI web services](#smapi-web-services)
- * [Overview](#overview)
- * [Log parser](#log-parser)
- * [Web API](#web-api)
- * [Development](#development-2)
- * [Local development](#local-development)
- * [Deploying to Amazon Beanstalk](#deploying-to-amazon-beanstalk)
-* [Mod build config package](#mod-build-config-package)
-
-# SMAPI
-## Development
-### Compiling from source
-Using an official SMAPI release is recommended for most users.
-
-SMAPI uses some C# 7 code, so you'll need at least
-[Visual Studio 2017](https://www.visualstudio.com/vs/community/) on Windows,
-[MonoDevelop 7.0](https://www.monodevelop.com/) on Linux,
-[Visual Studio 2017 for Mac](https://www.visualstudio.com/vs/visual-studio-mac/), or an equivalent
-IDE to compile it. It uses build configuration derived from the
-[crossplatform mod config](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme) to detect
-your current OS automatically and load the correct references. Compile output will be placed in a
-`bin` folder at the root of the git repository.
-
-### Debugging a local build
-Rebuilding the solution in debug mode will copy the SMAPI files into your game folder. Starting
-the `StardewModdingAPI` project with debugging from Visual Studio (on Mac or Windows) will launch
-SMAPI with the debugger attached, so you can intercept errors and step through the code being
-executed. This doesn't work in MonoDevelop on Linux, unfortunately.
-
-### Preparing a release
-To prepare a crossplatform SMAPI release, you'll need to compile it on two platforms. See
-[crossplatforming info](https://stardewvalleywiki.com/Modding:Modder_Guide/Test_and_Troubleshoot#Testing_on_all_platforms)
-on the wiki for the first-time setup.
-
-1. Update the version number in `GlobalAssemblyInfo.cs` and `Constants::Version`. Make sure you use a
- [semantic version](https://semver.org). Recommended format:
-
- build type | format | example
- :--------- | :----------------------- | :------
- dev build | `<version>-alpha.<date>` | `3.0-alpha.20171230`
- prerelease | `<version>-beta.<count>` | `3.0-beta.2`
- release | `<version>` | `3.0`
-
-2. In Windows:
- 1. Rebuild the solution in Release mode.
- 2. Copy `windows-install.*` from `bin/SMAPI installer` and `bin/SMAPI installer for developers` to
- Linux/Mac.
-
-3. In Linux/Mac:
- 1. Rebuild the solution in Release mode.
- 2. Add the `windows-install.*` files to the `bin/SMAPI installer` and
- `bin/SMAPI installer for developers` folders.
- 3. Rename the folders to `SMAPI <version> installer` and `SMAPI <version> installer for developers`.
- 4. Zip the two folders.
-
-## Customisation
-### Configuration file
-You can customise the SMAPI behaviour by editing the `smapi-internal/StardewModdingAPI.config.json`
-file in your game folder.
-
-Basic fields:
-
-field | purpose
------------------ | -------
-`DeveloperMode` | Default `false` (except in _SMAPI for developers_ releases). Whether to enable features intended for mod developers (mainly more detailed console logging).
-`CheckForUpdates` | Default `true`. Whether SMAPI should check for a newer version when you load the game. If a new version is available, a small message will appear in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.
-`VerboseLogging` | Default `false`. Whether SMAPI should log more information about the game context.
-`ModData` | Internal metadata about SMAPI mods. Changing this isn't recommended and may destabilise your game. See documentation in the file.
-
-### Command-line arguments
-The SMAPI installer recognises three command-line arguments:
-
-argument | purpose
--------- | -------
-`--install` | Preselects the install action, skipping the prompt asking what the user wants to do.
-`--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do.
-`--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error.
-
-SMAPI itself recognises two arguments, but these are intended for internal use or testing and may
-change without warning.
-
-argument | purpose
--------- | -------
-`--no-terminal` | SMAPI won't write anything to the console window. (Messages will still be written to the log file.)
-`--mods-path` | The path to search for mods, if not the standard `Mods` folder. This can be a path relative to the game folder (like `--mods-path "Mods (test)"`) or an absolute path.
-
-### Compile flags
-SMAPI uses a small number of conditional compilation constants, which you can set by editing the
-`<DefineConstants>` element in `StardewModdingAPI.csproj`. Supported constants:
-
-flag | purpose
----- | -------
-`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`.
-`SMAPI_3_0_STRICT` | Whether to exclude all deprecated APIs from compilation. This is useful for testing mods for SMAPI 3.0 compatibility.
-
-# SMAPI web services
-## Overview
-The `StardewModdingAPI.Web` project provides an API and web UI hosted at `*.smapi.io`.
-
-### Log parser
-The log parser provides a web UI for uploading, parsing, and sharing SMAPI logs. The logs are
-persisted in a compressed form to Pastebin.
-
-The log parser lives at https://log.smapi.io.
-
-### Web API
-SMAPI provides a web API at `api.smapi.io` for use by SMAPI and external tools. The URL includes a
-`{version}` token, which is the SMAPI version for backwards compatibility. This API is publicly
-accessible but not officially released; it may change at any time.
-
-The API has one `/mods` endpoint. This provides mod info, including official versions and URLs
-(from Chucklefish, GitHub, or Nexus), unofficial versions from the wiki, and optional mod metadata
-from the wiki and SMAPI's internal data. This is used by SMAPI to perform update checks, and by
-external tools to fetch mod data.
-
-The API accepts a `POST` request with the mods to match, each of which **must** specify an ID and
-may _optionally_ specify [update keys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks).
-The API will automatically try to fetch known update keys from the wiki and internal data based on
-the given ID.
-
-```
-POST https://api.smapi.io/v2.0/mods
-{
- "mods": [
- {
- "id": "Pathoschild.LookupAnything",
- "updateKeys": [ "nexus:541", "chucklefish:4250" ]
- }
- ],
- "includeExtendedMetadata": true
-}
-```
-
-The API will automatically aggregate versions and errors. Each mod will include...
-* an `id` (matching what you passed in);
-* up to three versions: `main` (e.g. 'latest version' field on Nexus), `optional` if newer (e.g.
- optional files on Nexus), and `unofficial` if newer (from the wiki);
-* `metadata` with mod info crossreferenced from the wiki and internal data (only if you specified
- `includeExtendedMetadata: true`);
-* and `errors` containing any error messages that occurred while fetching data.
-
-For example:
-```
-[
- {
- "id": "Pathoschild.LookupAnything",
- "main": {
- "version": "1.19",
- "url": "https://www.nexusmods.com/stardewvalley/mods/541"
- },
- "metadata": {
- "id": [
- "Pathoschild.LookupAnything",
- "LookupAnything"
- ],
- "name": "Lookup Anything",
- "nexusID": 541,
- "gitHubRepo": "Pathoschild/StardewMods",
- "compatibilityStatus": "Ok",
- "compatibilitySummary": "✓ use latest version."
- },
- "errors": []
- }
-]
-```
-
-## Development
-### Local development
-`StardewModdingAPI.Web` is a regular ASP.NET MVC Core app, so you can just launch it from within
-Visual Studio to run a local version.
-
-There are two differences when it's run locally: all endpoints use HTTP instead of HTTPS, and the
-subdomain portion becomes a route (e.g. `log.smapi.io` &rarr; `localhost:59482/log`).
-
-Before running it locally, you need to enter your credentials in the `appsettings.Development.json`
-file. See the next section for a description of each setting. This file is listed in `.gitignore`
-to prevent accidentally committing credentials.
-
-### Deploying to Amazon Beanstalk
-The app can be deployed to a standard Amazon Beanstalk IIS environment. When creating the
-environment, make sure to specify the following environment properties:
-
-property name | description
-------------------------------- | -----------------
-`LogParser:PastebinDevKey` | The [Pastebin developer key](https://pastebin.com/api#1) used to authenticate with the Pastebin API.
-`LogParser:PastebinUserKey` | The [Pastebin user key](https://pastebin.com/api#8) used to authenticate with the Pastebin API. Can be left blank to post anonymously.
-`LogParser:SectionUrl` | The root URL of the log page, like `https://log.smapi.io/`.
-`ModUpdateCheck:GitHubPassword` | The password with which to authenticate to GitHub when fetching release info.
-`ModUpdateCheck:GitHubUsername` | The username with which to authenticate to GitHub when fetching release info.
-
-## Mod build config package
-### Overview
-The mod build config package is a NuGet package that mods reference to automatically set up
-references, configure the build, and add analyzers specific to Stardew Valley mods.
-
-This involves three projects:
-
-project | purpose
-------------------------------------------------- | ----------------
-`StardewModdingAPI.ModBuildConfig` | Configures the build (references, deploying the mod files, setting up debugging, etc).
-`StardewModdingAPI.ModBuildConfig.Analyzer` | Adds C# analyzers which show code warnings in Visual Studio.
-`StardewModdingAPI.ModBuildConfig.Analyzer.Tests` | Unit tests for the C# analyzers.
-
-When the projects are built, the relevant files are copied into `bin/Pathoschild.Stardew.ModBuildConfig`.
-
-### Preparing a build
-To prepare a build of the NuGet package:
-1. Install the [NuGet CLI](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#nugetexe-cli).
-1. Change the version and release notes in `package.nuspec`.
-2. Rebuild the solution in _Release_ mode.
-3. Open a terminal in the `bin/Pathoschild.Stardew.ModBuildConfig` package and run this command:
- ```bash
- nuget.exe pack
- ```
-
-That will create a `Pathoschild.Stardew.ModBuildConfig-<version>.nupkg` file in the same directory
-which can be uploaded to NuGet or referenced directly.
diff --git a/docs/technical/mod-package.md b/docs/technical/mod-package.md
new file mode 100644
index 00000000..a33480ad
--- /dev/null
+++ b/docs/technical/mod-package.md
@@ -0,0 +1,366 @@
+&larr; [SMAPI](../README.md)
+
+The **mod build package** is an open-source NuGet package which automates the MSBuild configuration
+for SMAPI mods and related tools. The package is fully compatible with Linux, Mac, and Windows.
+
+## Contents
+* [Use](#use)
+* [Features](#features)
+ * [Detect game path](#detect-game-path)
+ * [Add assembly references](#add-assembly-references)
+ * [Copy files into the `Mods` folder and create release zip](#copy-files-into-the-mods-folder-and-create-release-zip)
+ * [Launch or debug game](#launch-or-debug-game)
+ * [Preconfigure common settings](#preconfigure-common-settings)
+ * [Add code warnings](#add-code-warnings)
+* [Code warnings](#code-warnings)
+* [Special cases](#special-cases)
+ * [Custom game path](#custom-game-path)
+ * [Non-mod projects](#non-mod-projects)
+* [For SMAPI developers](#for-smapi-developers)
+* [Release notes](#release-notes)
+
+## Use
+1. Create an empty library project.
+2. Reference the [`Pathoschild.Stardew.ModBuildConfig` NuGet package](https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig).
+3. [Write your code](https://stardewvalleywiki.com/Modding:Creating_a_SMAPI_mod).
+4. Compile on any platform.
+5. Run the game to play with your mod.
+
+## Features
+The package automatically makes the changes listed below. In some cases you can configure how it
+works by editing your mod's `.csproj` file, and adding the given properties between the first
+`<PropertyGroup>` and `</PropertyGroup>` tags.
+
+### Detect game path
+The package finds your game folder by scanning the default install paths and Windows registry. It
+adds two MSBuild properties for use in your `.csproj` file if needed:
+
+property | description
+-------- | -----------
+`$(GamePath)` | The absolute path to the detected game folder.
+`$(GameExecutableName)` | The game's executable name for the current OS (`Stardew Valley` on Windows, or `StardewValley` on Linux/Mac).
+
+If you get a build error saying it can't find your game, see [_set the game path_](#set-the-game-path).
+
+### Add assembly references
+The package adds assembly references to SMAPI, Stardew Valley, xTile, and MonoGame (Linux/Mac) or XNA
+Framework (Windows). It automatically adjusts depending on which OS you're compiling it on.
+
+The assemblies aren't copied to the build output, since mods loaded by SMAPI won't need them. For
+non-mod projects like unit tests, you can set this property:
+```xml
+<CopyModReferencesToBuildOutput>true</CopyModReferencesToBuildOutput>
+```
+
+If your mod uses [Harmony](https://github.com/pardeike/Harmony) (not recommended for most mods),
+the package can add a reference to SMAPI's Harmony DLL for you:
+```xml
+<EnableHarmony>true</EnableHarmony>
+```
+
+### Copy files into the `Mods` folder and create release zip
+<dl>
+<dt>Files considered part of your mod</dt>
+<dd>
+
+These files are selected by default: `manifest.json`,
+[`i18n` files](https://stardewvalleywiki.com/Modding:Translations) (if any), the `assets` folder
+(if any), and all files in the build output. You can select custom files by [adding them to the
+build output](https://stackoverflow.com/a/10828462/262123). (If your project references another mod,
+make sure the reference is [_not_ marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).)
+
+You can deselect a file by removing it from the build output. For a default file, you can set the
+property below to a comma-delimited list of regex patterns to ignore. For crossplatform
+compatibility, you should replace path delimiters with `[/\\]`.
+
+```xml
+<IgnoreModFilePatterns>\.txt$, \.pdf$, assets[/\\]paths.png</IgnoreModFilePatterns>
+```
+
+</dd>
+<dt>Copy files into the `Mods` folder</dt>
+<dd>
+
+The package copies the selected files into your game's `Mods` folder when you rebuild the code,
+with a subfolder matching the mod's project name.
+
+You can change the folder name:
+```xml
+<ModFolderName>YourModName</ModFolderName>
+```
+
+Or disable deploying the files:
+```xml
+<EnableModDeploy>false</EnableModDeploy>
+```
+
+</dd>
+<dt>Create release zip</dt>
+<dd>
+
+The package adds a zip file in your project's `bin` folder when you rebuild the code, in the format
+recommended for sites like Nexus Mods. The zip filename can be changed using `ModFolderName` above.
+
+You can change the folder path where the zip is created:
+```xml
+<ModZipPath>$(SolutionDir)\_releases</ModZipPath>
+```
+
+Or disable zip creation:
+```xml
+<EnableModZip>false</EnableModZip>
+```
+
+</dd>
+</dl>
+
+### Launch or debug game
+On Windows only, the package configures Visual Studio so you can launch the game and attach a
+debugger using _Debug > Start Debugging_ or _Debug > Start Without Debugging_. This lets you [set
+breakpoints](https://docs.microsoft.com/en-us/visualstudio/debugger/using-breakpoints?view=vs-2019)
+in your code while the game is running, or [make simple changes to the mod code without needing to
+restart the game](https://docs.microsoft.com/en-us/visualstudio/debugger/edit-and-continue?view=vs-2019).
+
+This is disabled on Linux/Mac due to limitations with the Mono wrapper.
+
+To disable game debugging (only needed for some non-mod projects):
+
+```xml
+<EnableGameDebugging>false</EnableGameDebugging>
+```
+
+### Preconfigure common settings
+The package also automatically enables PDB files (so error logs show line numbers for simpler
+debugging), and enables support for the simplified `.csproj` format.
+
+### Add code warnings
+The package runs code analysis on your mod and raises warnings for some common errors or pitfalls.
+See [_code warnings_](#code-warnings) for more info.
+
+## Code warnings
+### Overview
+The NuGet package adds code warnings in Visual Studio specific to Stardew Valley. For example:
+![](screenshots/code-analyzer-example.png)
+
+You can hide the warnings using the warning ID (shown under 'code' in the Error List). See...
+* [for specific code](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma-warning);
+* for a method using this attribute:
+ ```cs
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("SMAPI.CommonErrors", "AvoidNetField")]
+ ```
+* for an entire project:
+ 1. Expand the _References_ node for the project in Visual Studio.
+ 2. Right-click on _Analyzers_ and choose _Open Active Rule Set_.
+ 4. Expand _StardewModdingAPI.ModBuildConfig.Analyzer_ and uncheck the warnings you want to hide.
+
+See below for help with each specific warning.
+
+### Avoid implicit net field cast
+Warning text:
+> This implicitly converts '{{expression}}' from {{net type}} to {{other type}}, but
+> {{net type}} has unintuitive implicit conversion rules. Consider comparing against the actual
+> value instead to avoid bugs.
+
+Stardew Valley uses net types (like `NetBool` and `NetInt`) to handle multiplayer sync. These types
+can implicitly convert to their equivalent normal values (like `bool x = new NetBool()`), but their
+conversion rules are unintuitive and error-prone. For example,
+`item?.category == null && item?.category != null` can both be true at once, and
+`building.indoors != null` can be true for a null value.
+
+Suggested fix:
+* Some net fields have an equivalent non-net property like `monster.Health` (`int`) instead of
+ `monster.health` (`NetInt`). The package will add a separate [AvoidNetField](#avoid-net-field) warning for
+ these. Use the suggested property instead.
+* For a reference type (i.e. one that can contain `null`), you can use the `.Value` property:
+ ```c#
+ if (building.indoors.Value == null)
+ ```
+ Or convert the value before comparison:
+ ```c#
+ GameLocation indoors = building.indoors;
+ if(indoors == null)
+ // ...
+ ```
+* For a value type (i.e. one that can't contain `null`), check if the object is null (if applicable)
+ and compare with `.Value`:
+ ```cs
+ if (item != null && item.category.Value == 0)
+ ```
+
+### Avoid net field
+Warning text:
+> '{{expression}}' is a {{net type}} field; consider using the {{property name}} property instead.
+
+Your code accesses a net field, which has some unusual behavior (see [AvoidImplicitNetFieldCast](#avoid-implicit-net-field-cast)).
+This field has an equivalent non-net property that avoids those issues.
+
+Suggested fix: access the suggested property name instead.
+
+### Avoid obsolete field
+Warning text:
+> The '{{old field}}' field is obsolete and should be replaced with '{{new field}}'.
+
+Your code accesses a field which is obsolete or no longer works. Use the suggested field instead.
+
+## Special cases
+### Custom game path
+The package usually detects where your game is installed automatically. If it can't find your game
+or you have multiple installs, you can specify the path yourself. There's two ways to do that:
+
+* **Option 1: global game path (recommended).**
+ _This will apply to every project that uses the package._
+
+ 1. Get the full folder path containing the Stardew Valley executable.
+ 2. Create this file:
+
+ platform | path
+ --------- | ----
+ Linux/Mac | `~/stardewvalley.targets`
+ Windows | `%USERPROFILE%\stardewvalley.targets`
+
+ 3. Save the file with this content:
+
+ ```xml
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <GamePath>PATH_HERE</GamePath>
+ </PropertyGroup>
+ </Project>
+ ```
+
+ 4. Replace `PATH_HERE` with your game path.
+
+* **Option 2: path in the project file.**
+ _You'll need to do this for each project that uses the package._
+
+ 1. Get the folder path containing the Stardew Valley `.exe` file.
+ 2. Add this to your `.csproj` file under the `<Project` line:
+
+ ```xml
+ <PropertyGroup>
+ <GamePath>PATH_HERE</GamePath>
+ </PropertyGroup>
+ ```
+
+ 3. Replace `PATH_HERE` with your custom game install path.
+
+The configuration will check your custom path first, then fall back to the default paths (so it'll
+still compile on a different computer).
+
+You access the game path via `$(GamePath)` in MSBuild properties, if you need to reference another
+file in the game folder.
+
+### Non-mod projects
+You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). Just disable
+the mod-related package features:
+
+```xml
+<EnableGameDebugging>false</EnableGameDebugging>
+<EnableModDeploy>false</EnableModDeploy>
+<EnableModZip>false</EnableModZip>
+```
+
+If you need to copy the referenced DLLs into your build output, add this too:
+```xml
+<CopyModReferencesToBuildOutput>true</CopyModReferencesToBuildOutput>
+```
+
+## For SMAPI developers
+The mod build package consists of three projects:
+
+project | purpose
+------------------------------------------------- | ----------------
+`StardewModdingAPI.ModBuildConfig` | Configures the build (references, deploying the mod files, setting up debugging, etc).
+`StardewModdingAPI.ModBuildConfig.Analyzer` | Adds C# analyzers which show code warnings in Visual Studio.
+`StardewModdingAPI.ModBuildConfig.Analyzer.Tests` | Unit tests for the C# analyzers.
+
+To prepare a build of the NuGet package:
+1. Install the [NuGet CLI](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools#nugetexe-cli).
+1. Change the version and release notes in `package.nuspec`.
+2. Rebuild the solution in _Release_ mode.
+3. Open a terminal in the `bin/Pathoschild.Stardew.ModBuildConfig` package and run this command:
+ ```bash
+ nuget.exe pack
+ ```
+
+That will create a `Pathoschild.Stardew.ModBuildConfig-<version>.nupkg` file in the same directory
+which can be uploaded to NuGet or referenced directly.
+
+## Release notes
+### Upcoming release
+* Updated for SMAPI 3.0 and Stardew Valley 1.4.
+* Added automatic support for `assets` folders.
+* Added `$(GameExecutableName)` MSBuild variable.
+* Added support for projects using the simplified `.csproj` format.
+* Added option to disable game debugging config.
+* Added `.pdb` files to builds by default (to enable line numbers in error stack traces).
+* Added optional Harmony reference.
+* Fixed `Newtonsoft.Json.pdb` included in release zips when Json.NET is referenced directly.
+* Fixed `<IgnoreModFilePatterns>` not working for `i18n` files.
+* Dropped support for older versions of SMAPI and Visual Studio.
+
+### 2.2
+* Added support for SMAPI 2.8+ (still compatible with earlier versions).
+* Added default game paths for 32-bit Windows.
+* Fixed valid manifests marked invalid in some cases.
+
+### 2.1
+* Added support for Stardew Valley 1.3.
+* Added support for non-mod projects.
+* Added C# analyzers to warn about implicit conversions of Netcode fields in Stardew Valley 1.3.
+* Added option to ignore files by regex pattern.
+* Added reference to new SMAPI DLL.
+* Fixed some game paths not detected by NuGet package.
+
+### 2.0.2
+* Fixed compatibility issue on Linux.
+
+### 2.0.1
+* Fixed mod deploy failing to create subfolders if they don't already exist.
+
+### 2.0
+* Added: mods are now copied into the `Mods` folder automatically (configurable).
+* Added: release zips are now created automatically in your build output folder (configurable).
+* Added: mod deploy and release zips now exclude Json.NET automatically, since it's provided by SMAPI.
+* Added mod's version to release zip filename.
+* Improved errors to simplify troubleshooting.
+* Fixed release zip not having a mod folder.
+* Fixed release zip failing if mod name contains characters that aren't valid in a filename.
+
+### 1.7.1
+* Fixed issue where i18n folders were flattened.
+* The manifest/i18n files in the project now take precedence over those in the build output if both
+ are present.
+
+### 1.7
+* Added option to create release zips on build.
+* Added reference to XNA's XACT library for audio-related mods.
+
+### 1.6
+* Added support for deploying mod files into `Mods` automatically.
+* Added a build error if a game folder is found, but doesn't contain Stardew Valley or SMAPI.
+
+### 1.5
+* Added support for setting a custom game path globally.
+* Added default GOG path on Mac.
+
+### 1.4
+* Fixed detection of non-default game paths on 32-bit Windows.
+* Removed support for SilVerPLuM (discontinued).
+* Removed support for overriding the target platform (no longer needed since SMAPI crossplatforms
+ mods automatically).
+
+### 1.3
+* Added support for non-default game paths on Windows.
+
+### 1.2
+* Exclude game binaries from mod build output.
+
+### 1.1
+* Added support for overriding the target platform.
+
+### 1.0
+* Initial release.
+* Added support for detecting the game path automatically.
+* Added support for injecting XNA/MonoGame references automatically based on the OS.
+* Added support for mod builders like SilVerPLuM.
diff --git a/docs/screenshots/code-analyzer-example.png b/docs/technical/screenshots/code-analyzer-example.png
index de38f643..de38f643 100644
--- a/docs/screenshots/code-analyzer-example.png
+++ b/docs/technical/screenshots/code-analyzer-example.png
Binary files differ
diff --git a/docs/technical/smapi.md b/docs/technical/smapi.md
new file mode 100644
index 00000000..96f7dff5
--- /dev/null
+++ b/docs/technical/smapi.md
@@ -0,0 +1,116 @@
+&larr; [README](../README.md)
+
+This file provides more technical documentation about SMAPI. If you only want to use or create
+mods, this section isn't relevant to you; see the main README to use or create mods.
+
+This document is about SMAPI itself; see also [mod build package](mod-package.md) and
+[web services](web.md).
+
+# Contents
+* [Customisation](#customisation)
+ * [Configuration file](#configuration-file)
+ * [Command-line arguments](#command-line-arguments)
+ * [Compile flags](#compile-flags)
+* [For SMAPI developers](#for-smapi-developers)
+ * [Compiling from source](#compiling-from-source)
+ * [Debugging a local build](#debugging-a-local-build)
+ * [Preparing a release](#preparing-a-release)
+* [Release notes](#release-notes)
+
+## Customisation
+### Configuration file
+You can customise the SMAPI behaviour by editing the `smapi-internal/config.json` file in your game
+folder.
+
+Basic fields:
+
+field | purpose
+----------------- | -------
+`DeveloperMode` | Default `false` (except in _SMAPI for developers_ releases). Whether to enable features intended for mod developers (mainly more detailed console logging).
+`CheckForUpdates` | Default `true`. Whether SMAPI should check for a newer version when you load the game. If a new version is available, a small message will appear in the console. This doesn't affect the load time even if your connection is offline or slow, because it happens in the background.
+`VerboseLogging` | Default `false`. Whether SMAPI should log more information about the game context.
+`ModData` | Internal metadata about SMAPI mods. Changing this isn't recommended and may destabilise your game. See documentation in the file.
+
+### Command-line arguments
+The SMAPI installer recognises three command-line arguments:
+
+argument | purpose
+-------- | -------
+`--install` | Preselects the install action, skipping the prompt asking what the user wants to do.
+`--uninstall` | Preselects the uninstall action, skipping the prompt asking what the user wants to do.
+`--game-path "path"` | Specifies the full path to the folder containing the Stardew Valley executable, skipping automatic detection and any prompt to choose a path. If the path is not valid, the installer displays an error.
+
+SMAPI itself recognises two arguments **on Windows only**, but these are intended for internal use
+or testing and may change without warning. On Linux/Mac, see _environment variables_ below.
+
+argument | purpose
+-------- | -------
+`--no-terminal` | SMAPI won't write anything to the console window. (Messages will still be written to the log file.)
+`--mods-path` | The path to search for mods, if not the standard `Mods` folder. This can be a path relative to the game folder (like `--mods-path "Mods (test)"`) or an absolute path.
+
+### Environment variables
+The above SMAPI arguments don't work on Linux/Mac due to the way the game launcher works. You can
+set temporary environment variables instead. For example:
+> SMAPI_MODS_PATH="Mods (multiplayer)" /path/to/StardewValley
+
+environment variable | purpose
+-------------------- | -------
+`SMAPI_NO_TERMINAL` | Equivalent to `--no-terminal` above.
+`SMAPI_MODS_PATH` | Equivalent to `--mods-path` above.
+
+
+### Compile flags
+SMAPI uses a small number of conditional compilation constants, which you can set by editing the
+`<DefineConstants>` element in `SMAPI.csproj`. Supported constants:
+
+flag | purpose
+---- | -------
+`SMAPI_FOR_WINDOWS` | Whether SMAPI is being compiled on Windows for players on Windows. Set automatically in `crossplatform.targets`.
+
+## For SMAPI developers
+### Compiling from source
+Using an official SMAPI release is recommended for most users.
+
+SMAPI uses some C# 7 code, so you'll need at least
+[Visual Studio 2017](https://www.visualstudio.com/vs/community/) on Windows,
+[MonoDevelop 7.0](https://www.monodevelop.com/) on Linux,
+[Visual Studio 2017 for Mac](https://www.visualstudio.com/vs/visual-studio-mac/), or an equivalent
+IDE to compile it. It uses build configuration derived from the
+[crossplatform mod config](https://github.com/Pathoschild/Stardew.ModBuildConfig#readme) to detect
+your current OS automatically and load the correct references. Compile output will be placed in a
+`bin` folder at the root of the git repository.
+
+### Debugging a local build
+Rebuilding the solution in debug mode will copy the SMAPI files into your game folder. Starting
+the `SMAPI` project with debugging from Visual Studio (on Mac or Windows) will launch SMAPI with
+the debugger attached, so you can intercept errors and step through the code being executed. This
+doesn't work in MonoDevelop on Linux, unfortunately.
+
+### Preparing a release
+To prepare a crossplatform SMAPI release, you'll need to compile it on two platforms. See
+[crossplatforming info](https://stardewvalleywiki.com/Modding:Modder_Guide/Test_and_Troubleshoot#Testing_on_all_platforms)
+on the wiki for the first-time setup.
+
+1. Update the version number in `.root/build/common.targets` and `Constants::Version`. Make sure
+ you use a [semantic version](https://semver.org). Recommended format:
+
+ build type | format | example
+ :--------- | :----------------------- | :------
+ dev build | `<version>-alpha.<date>` | `3.0-alpha.20171230`
+ prerelease | `<version>-beta.<count>` | `3.0-beta.2`
+ release | `<version>` | `3.0`
+
+2. In Windows:
+ 1. Rebuild the solution in Release mode.
+ 2. Copy `windows-install.*` from `bin/SMAPI installer` and `bin/SMAPI installer for developers` to
+ Linux/Mac.
+
+3. In Linux/Mac:
+ 1. Rebuild the solution in Release mode.
+ 2. Add the `windows-install.*` files to the `bin/SMAPI installer` and
+ `bin/SMAPI installer for developers` folders.
+ 3. Rename the folders to `SMAPI <version> installer` and `SMAPI <version> installer for developers`.
+ 4. Zip the two folders.
+
+## Release notes
+See [release notes](../release-notes.md).
diff --git a/docs/technical/web.md b/docs/technical/web.md
new file mode 100644
index 00000000..78d93625
--- /dev/null
+++ b/docs/technical/web.md
@@ -0,0 +1,380 @@
+&larr; [README](../README.md)
+
+**SMAPI.Web** contains the code for the `smapi.io` website, including the mod compatibility list
+and update check API.
+
+## Contents
+* [Log parser](#log-parser)
+* [JSON validator](#json-validator)
+* [Web API](#web-api)
+* [Short URLs](#short-urls)
+* [For SMAPI developers](#for-smapi-developers)
+ * [Local development](#local-development)
+ * [Deploying to Amazon Beanstalk](#deploying-to-amazon-beanstalk)
+
+## Log parser
+The log parser provides a web UI for uploading, parsing, and sharing SMAPI logs. The logs are
+persisted in a compressed form to Pastebin. The log parser lives at https://log.smapi.io.
+
+## JSON validator
+### Overview
+The JSON validator provides a web UI for uploading and sharing JSON files, and validating them as
+plain JSON or against a predefined format like `manifest.json` or Content Patcher's `content.json`.
+The JSON validator lives at https://json.smapi.io.
+
+### Schema file format
+Schema files are defined in `wwwroot/schemas` using the [JSON Schema](https://json-schema.org/)
+format. The JSON validator UI recognises a superset of the standard fields to change output:
+
+<dl>
+<dt>Documentation URL</dt>
+<dd>
+
+The root schema may have a `@documentationURL` field, which is a web URL for the user
+documentation:
+```js
+"@documentationUrl": "https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest"
+```
+
+If present, this is shown in the JSON validator UI.
+
+</dd>
+<dt>Error messages</dt>
+<dd>
+
+Any part of the schema can define an `@errorMessages` field, which overrides matching schema
+errors. You can override by error code (recommended), or by error type and a regex pattern matched
+against the error message (more fragile):
+
+```js
+// by error type
+"pattern": "^[a-zA-Z0-9_.-]+\\.dll$",
+"@errorMessages": {
+ "pattern": "Invalid value; must be a filename ending with .dll."
+}
+```
+```js
+// by error type + message pattern
+"@errorMessages": {
+ "oneOf:valid against no schemas": "Missing required field: EntryDll or ContentPackFor.",
+ "oneOf:valid against more than one schema": "Can't specify both EntryDll or ContentPackFor, they're mutually exclusive."
+}
+```
+
+Error messages may contain special tokens:
+
+* The `@value` token is replaced with the error's value field. This is usually (but not always) the
+ original field value.
+* When an error has child errors, by default they're flattened into one message:
+ ```
+ line | field | error
+ ---- | ---------- | -------------------------------------------------------------------------
+ 4 | Changes[0] | JSON does not match schema from 'then'.
+ | | ==> Changes[0].ToArea.Y: Invalid type. Expected Integer but got String.
+ | | ==> Changes[0].ToArea: Missing required fields: Height.
+ ```
+
+ If you set the message for an error to `$transparent`, the parent error is omitted entirely and
+ the child errors are shown instead:
+ ```
+ line | field | error
+ ---- | ------------------- | ----------------------------------------------
+ 8 | Changes[0].ToArea.Y | Invalid type. Expected Integer but got String.
+ 8 | Changes[0].ToArea | Missing required fields: Height.
+ ```
+
+ The child errors themselves may be marked `$transparent`, etc. If an error has no child errors,
+ this override is ignored.
+
+ Validation errors for `then` blocks are transparent by default, unless overridden.
+
+</dd>
+</dl>
+
+### Using a schema file directly
+You can reference the validator schemas in your JSON file directly using the `$schema` field, for
+text editors that support schema validation. For example:
+```js
+{
+ "$schema": "https://smapi.io/schemas/manifest.json",
+ "Name": "Some mod",
+ ...
+}
+```
+
+Available schemas:
+
+format | schema URL
+------ | ----------
+[SMAPI `manifest.json`](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest) | https://smapi.io/schemas/manifest.json
+[Content Patcher `content.json`](https://github.com/Pathoschild/StardewMods/tree/develop/ContentPatcher#readme) | https://smapi.io/schemas/content-patcher.json
+
+## Web API
+### Overview
+SMAPI provides a web API at `api.smapi.io` for use by SMAPI and external tools. The URL includes a
+`{version}` token, which is the SMAPI version for backwards compatibility. This API is publicly
+accessible but not officially released; it may change at any time.
+
+### `/mods` endpoint
+The API has one `/mods` endpoint. This crossreferences the mod against a variety of sources (e.g.
+the wiki, Chucklefish, CurseForge, ModDrop, and Nexus) to provide metadata mainly intended for
+update checks.
+
+The API accepts a `POST` request with these fields:
+
+<table>
+<tr>
+<th>field</th>
+<th>summary</th>
+</tr>
+
+<tr>
+<td><code>mods</code></td>
+<td>
+
+The mods for which to fetch metadata. Included fields:
+
+
+field | summary
+----- | -------
+`id` | The unique ID in the mod's `manifest.json`. This is used to crossreference with the wiki, and to index mods in the response. If it's unknown (e.g. you just have an update key), you can use a unique fake ID like `FAKE.Nexus.2400`.
+`updateKeys` | _(optional)_ [Update keys](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Manifest#Update_checks) which specify the mod pages to check, in addition to any mod pages linked to the `ID`.
+`installedVersion` | _(optional)_ The installed version of the mod. If not specified, the API won't recommend an update.
+`isBroken` | _(optional)_ Whether SMAPI failed to load the installed version of the mod, e.g. due to incompatibility. If true, the web API will be more permissive when recommending updates (e.g. allowing a stable → prerelease update).
+
+</td>
+</tr>
+
+<tr>
+<td><code>apiVersion</code></td>
+<td>
+
+_(optional)_ The installed version of SMAPI. If not specified, the API won't recommend an update.
+
+</td>
+</tr>
+
+<tr>
+<td><code>gameVersion</code></td>
+<td>
+
+_(optional)_ The installed version of Stardew Valley. This may be used to select updates.
+
+</td>
+</tr>
+
+<tr>
+<td><code>platform</code></td>
+<td>
+
+_(optional)_ The player's OS (`Android`, `Linux`, `Mac`, or `Windows`). This may be used to select updates.
+
+</td>
+</tr>
+
+<tr>
+<td><code>includeExtendedMetadata</code></td>
+<td>
+
+_(optional)_ Whether to include extra metadata that's not needed for SMAPI update checks, but which
+may be useful to external tools.
+
+</td>
+</table>
+
+Example request:
+```js
+POST https://api.smapi.io/v3.0/mods
+{
+ "mods": [
+ {
+ "id": "Pathoschild.ContentPatcher",
+ "updateKeys": [ "nexus:1915" ],
+ "installedVersion": "1.9.2",
+ "isBroken": false
+ }
+ ],
+ "apiVersion": "3.0.0",
+ "gameVersion": "1.4.0",
+ "platform": "Windows",
+ "includeExtendedMetadata": true
+}
+```
+
+Response fields:
+
+<table>
+<tr>
+<th>field</th>
+<th>summary</th>
+</tr>
+
+<tr>
+<td><code>id</code></td>
+<td>
+
+The mod ID you specified in the request.
+
+</td>
+</tr>
+
+<tr>
+<td><code>suggestedUpdate</code></td>
+<td>
+
+The update version recommended by the web API, if any. This is based on some internal rules (e.g.
+it won't recommend a prerelease update if the player has a working stable version) and context
+(e.g. whether the player is in the game beta channel). Choosing an update version yourself isn't
+recommended, but you can set `includeExtendedMetadata: true` and check the `metadata` field if you
+really want to do that.
+
+</td>
+</tr>
+
+<tr>
+<td><code>errors</code></td>
+<td>
+
+Human-readable errors that occurred fetching the version info (e.g. if a mod page has an invalid
+version).
+
+</td>
+</tr>
+
+<tr>
+<td><code>metadata</code></td>
+<td>
+
+Extra metadata that's not needed for SMAPI update checks but which may be useful to external tools,
+if you set `includeExtendedMetadata: true` in the request. Included fields:
+
+field | summary
+----- | -------
+`id` | The known `manifest.json` unique IDs for this mod defined on the wiki, if any. That includes historical versions of the mod.
+`name` | The normalised name for this mod based on the crossreferenced sites.
+`nexusID` | The mod ID on [Nexus Mods](https://www.nexusmods.com/stardewvalley/), if any.
+`chucklefishID` | The mod ID in the [Chucklefish mod repo](https://community.playstarbound.com/resources/categories/stardew-valley.22/), if any.
+`curseForgeID` | The mod project ID on [CurseForge](https://www.curseforge.com/stardewvalley), if any.
+`curseForgeKey` | The mod key on [CurseForge](https://www.curseforge.com/stardewvalley), if any. This is used in the mod page URL.
+`modDropID` | The mod ID on [ModDrop](https://www.moddrop.com/stardew-valley), if any.
+`gitHubRepo` | The GitHub repository containing the mod code, if any. Specified in the `Owner/Repo` form.
+`customSourceUrl` | The custom URL to the mod code, if any. This is used for mods which aren't stored in a GitHub repo.
+`customUrl` | The custom URL to the mod page, if any. This is used for mods which aren't stored on one of the standard mod sites covered by the ID fields.
+`main` | The primary mod version, if any. This depends on the mod site, but it's typically either the version of the mod itself or of its latest non-optional download.
+`optional` | The latest optional download version, if any.
+`unofficial` | The version of the unofficial update defined on the wiki for this mod, if any.
+`unofficialForBeta` | Equivalent to `unofficial`, but for beta versions of SMAPI or Stardew Valley.
+`hasBetaInfo` | Whether there's an ongoing Stardew Valley or SMAPI beta which may affect update checks.
+`compatibilityStatus` | The compatibility status for the mod for the stable version of the game, as defined on the wiki, if any. See [possible values](https://github.com/Pathoschild/SMAPI/blob/develop/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiCompatibilityStatus.cs).
+`compatibilitySummary` | The human-readable summary of the mod's compatibility in HTML format, if any.
+`brokeIn` | The SMAPI or Stardew Valley version that broke this mod, if any.
+`betaCompatibilityStatus`<br />`betaCompatibilitySummary`<br />`betaBrokeIn` | Equivalent to the preceding fields, but for beta versions of SMAPI or Stardew Valley.
+
+
+</td>
+</tr>
+</table>
+
+Example response with `includeExtendedMetadata: false`:
+```js
+[
+ {
+ "id": "Pathoschild.ContentPatcher",
+ "suggestedUpdate": {
+ "version": "1.10.0",
+ "url": "https://www.nexusmods.com/stardewvalley/mods/1915"
+ },
+ "errors": []
+ }
+]
+```
+
+Example response with `includeExtendedMetadata: true`:
+```js
+[
+ {
+ "id": "Pathoschild.ContentPatcher",
+ "suggestedUpdate": {
+ "version": "1.10.0",
+ "url": "https://www.nexusmods.com/stardewvalley/mods/1915"
+ },
+ "metadata": {
+ "id": [ "Pathoschild.ContentPatcher" ],
+ "name": "Content Patcher",
+ "nexusID": 1915,
+ "curseForgeID": 309243,
+ "curseForgeKey": "content-patcher",
+ "modDropID": 470174,
+ "gitHubRepo": "Pathoschild/StardewMods",
+ "main": {
+ "version": "1.10",
+ "url": "https://www.nexusmods.com/stardewvalley/mods/1915"
+ },
+ "hasBetaInfo": true,
+ "compatibilityStatus": "Ok",
+ "compatibilitySummary": "✓ use latest version."
+ },
+ "errors": []
+ }
+]
+```
+
+## Short URLs
+The SMAPI web services provides a few short URLs for convenience:
+
+short url | → | target page
+:-------- | - | :----------
+[smapi.io/3.0](https://smapi.io/3.0) | → | [stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0](https://stardewvalleywiki.com/Modding:Migrate_to_SMAPI_3.0)
+[smapi.io/community](https://smapi.io/community) | → | [stardewvalleywiki.com/Modding:Community](https://stardewvalleywiki.com/Modding:Community)
+[smapi.io/docs](https://smapi.io/docs) | → | [stardewvalleywiki.com/Modding:Index](https://stardewvalleywiki.com/Modding:Index)
+[smapi.io/package](https://smapi.io/package) | → | [github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md](https://github.com/Pathoschild/SMAPI/blob/develop/docs/technical/mod-package.md)
+[smapi.io/troubleshoot](https://smapi.io/troubleshoot) | → | [stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting](https://stardewvalleywiki.com/Modding:Player_Guide/Troubleshooting)
+[smapi.io/xnb](https://smapi.io/xnb) | → | [stardewvalleywiki.com/Modding:Using_XNB_mods](https://stardewvalleywiki.com/Modding:Using_XNB_mods)
+
+## For SMAPI developers
+### Local environment
+A local environment lets you run a complete copy of the web project (including cache database) on
+your machine, with no external dependencies aside from the actual mod sites.
+
+Initial setup:
+
+1. [Install MongoDB](https://docs.mongodb.com/manual/administration/install-community/) and add its
+ `bin` folder to the system PATH.
+2. Create a local folder for the MongoDB data (e.g. `C:\dev\smapi-cache`).
+3. Enter your credentials in the `appsettings.Development.json` file. You can leave the MongoDB
+ credentials as-is to use the default local instance; see the next section for the other settings.
+
+To launch the environment:
+1. Launch MongoDB from a terminal (change the data path if applicable):
+ ```sh
+ mongod --dbpath C:\dev\smapi-cache
+ ```
+2. Launch `SMAPI.Web` from Visual Studio to run a local version of the site.
+ <small>(Local URLs will use HTTP instead of HTTPS, and subdomains will become routes, like
+ `log.smapi.io` &rarr; `localhost:59482/log`.)</small>
+
+### Production environment
+A production environment includes the web servers and cache database hosted online for public
+access. This section assumes you're creating a new production environment from scratch (not using
+the official live environment).
+
+Initial setup:
+
+1. Launch an empty MongoDB server (e.g. using [MongoDB Atlas](https://www.mongodb.com/cloud/atlas)).
+2. Create an AWS Beanstalk .NET environment with these environment properties:
+
+ property name | description
+ ------------------------------- | -----------------
+ `LogParser:PastebinDevKey` | The [Pastebin developer key](https://pastebin.com/api#1) used to authenticate with the Pastebin API.
+ `LogParser:PastebinUserKey` | The [Pastebin user key](https://pastebin.com/api#8) used to authenticate with the Pastebin API. Can be left blank to post anonymously.
+ `LogParser:SectionUrl` | The root URL of the log page, like `https://log.smapi.io/`.
+ `ModUpdateCheck:GitHubPassword` | The password with which to authenticate to GitHub when fetching release info.
+ `ModUpdateCheck:GitHubUsername` | The username with which to authenticate to GitHub when fetching release info.
+ `MongoDB:Host` | The hostname for the MongoDB instance.
+ `MongoDB:Username` | The login username for the MongoDB instance.
+ `MongoDB:Password` | The login password for the MongoDB instance.
+ `MongoDB:Database` | The database name (e.g. `smapi` in production or `smapi-edge` in testing environments).
+
+To deploy updates:
+1. Deploy the web project using [AWS Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/).
+2. If the MongoDB schema changed, delete the MongoDB database. (It'll be recreated automatically.)