Add config schema generation
Resolves #928.
Changes
- Adds a new dependency to
SMAPI.Toolkit:Newtonsoft.Json.Schemafor schema generation. - Adds
GenerateConfigSchemaoption toSConfigthat's set tofalseby default. - Adds
IDataHelper.WriteJsonSchemaFileandJsonHelper.WriteJsonSchemaFileto generate and write the schema to file. - Updates
ModHelper.ReadConfigto generate the fileconfig.schema.json.
Notes
I think develop references DLLs from Stardew Valley 1.6 that I don't have access with, so I had to create the code on stable and port it to develop.
I'm not sure how to test this PR, there aren't any unit tests that I can run. I thought about installing latest SMAPI normally and just overwriting the DLLs in the game folder with the ones I build using the PR. However, I don't even know if that works with the .NET DLL resolution process...
You'd be correct in saying that develop references Stardew Valley 1.6. Getting access is as simple as joining the Stardew Valley Discord server and asking in the #making-mods channel to get added (not even pinging anyone - anyone already in the alpha can add you).
Thanks! Unfortunately Json.NET Schema isn't free, and the AGPL version is limited to 1000 validations per hour. That could easily be reached in our case (since players can have hundreds or thousands of mods, they may launch the game more than once per hour, and mods often read/write their config files more than once).
Updated PR to use NJsonSchema.
Unfortunately NJsonSchema fails for many mods (see log). A few sample cases:
| mod | config | result |
|---|---|---|
| Automate | config | ❌ crashes with InvalidOperationException. |
| Chests Anywhere | config | ❌ ditto Automate. |
| CJB Cheats Menu | config | ❌ ditto Automate. |
| CJB Item Spawner | config | ❌ ditto Automate. |
| CJB Show Item Sell Price | config | ❌ creates a schema for an empty object: { "$schema": "...", title: "ModConfig", type: "object", "additionalProperties": false }. |
| Content Patcher | config | ❌ ditto Automate. |
| Crops Anytime Anywhere | config | ✅ Seems correct. |
| Data Layers | config | ❌ ditto Automate. |
| Debug Mode | config | ❌ ditto Automate. |
| Fast Animations | config | ✅ Seems correct. |
| Generic Mod Config Menu | config | ❌ only includes ScrollSpeed property. |
| Horse Flute Anywhere | config | ❌ ditto Automate. |
| NPC Location Compass | config | ✅ Seems correct. |
| Skip Intro | config | ✅ Seems correct. |
It seems to only work with properties (not fields), and fails with some common types like KeybindList (maybe due to the get-only properties?).
I rebased the PR branch onto the latest develop, so you can try it like this:
- Reset to the latest PR branch.
- Open SMAPI in Visual Studio.
- In
SMAPI/Constants.cs, change theMinimumGameVersionback to 1.6.8. - Click Build > Rebuild Solution to deploy the SMAPI files.
- Click Debug > Start Without Debugging to launch SMAPI.