<commit_before>---
layout: default
title: Advanced SMAPI mod configuration
intro: > 
   This page explains more advanced ways to use JSON files through <code>this.Helper</code>.
   This page is overkill for the vast majority of mods; see
   <em><a href="creating-a-smapi-mod#configuration">creating a SMAPI mod</a></em>
   for a simpler approach that is sufficient for most mods.
---

## Custom JSON files
Sometimes one `config.json` isn't enough, or you need to store data that's not meant to be edited
by the user. This is pretty easy using the `ModHelper`:

1. Create your model (see the main guide for more details):

   ```c#
   class ModData
   {
      public bool ExampleBoolean { get; set; }
      public float ExampleFloat { get; set; }

      public ModConfig()
      {
         this.ExampleBoolean = true;
         this.ExampleFloat = 0.5;
      }
   }
   ```

2. In your mod code, just use `this.Helper` to read and write to a named file:

   ```c#
   var model = this.Helper.ReadJsonFile<ModData>("data.json");
   this.Helper.WriteJsonFile("data.json", model);
   ```

For more advanced scenarios, you can also use a directory path; the directories will be created
automatically as needed. For example, here's how you'd create per-save JSON files:

```c#
var model = this.Helper.ReadJsonFile<ModData>($"{Game1.uniqueIDForThisGame}/data.json");
this.Helper.WriteJsonFile($"{Game1.uniqueIDForThisGame}/data.json", model);
```

## File I/O config wrapper
<p class="warning">
This section describes an experimental interface. Stability and backwards compatibility in future
versions are not guaranteed.
</p>

If your mod often reloads or saves the configuration, you can wrap your config model with file
I/O logic:

1. Create a `ModConfig` class (just like the previous section), but this time extend
   `StardewModdingAPI.Advanced.ConfigFile`:

   ```c#
   class ModConfig : StardewModdingAPI.Advanced.ConfigFile
   {
      public bool ExampleBoolean { get; set; }
      public float ExampleFloat { get; set; }

      public ModConfig()
      {<commit_msg>expand & tweak advanced config guide<commit_after>---
layout: default
title: Advanced SMAPI mod configuration
intro: > 
   This page explains more advanced ways to use JSON files through <code>this.Helper</code>.
   This page is overkill for the vast majority of mods; see
   <em><a href="creating-a-smapi-mod#configuration">creating a SMAPI mod</a></em>
   for a simpler approach that is sufficient for most mods.
---

## Custom JSON files
Sometimes one `config.json` isn't enough, or you need to store data that's not meant to be edited
by the user. This is pretty easy using the `ModHelper`:

1. Create your model (see the main guide for more details):

   ```c#
   class ModData
   {
      public bool ExampleBoolean { get; set; }
      public float ExampleFloat { get; set; }

      public ModData()
      {
         this.ExampleBoolean = true;
         this.ExampleFloat = 0.5;
      }
   }
   ```

2. In your mod code, just use `this.Helper` to read and write to a named file:

   ```c#
   // read file
   var model = this.Helper.ReadJsonFile<ModData>("data.json") ?? new ModData();

   // save file (if needed)
   this.Helper.WriteJsonFile("data.json", model);
   ```
   Note that `ReadJsonFile` will return `null` if the file doesn't exist. The above example will
   create a default instance if that happens; if you don't want to do that, just remove the
   `?? new ModData()` part.

## Per-save JSON files
You can also specify a directory path (relative to your mod directory) instead of just the file
name. The directories will be created automatically if needed. For example, here's how you'd use
per-save config files:

```c#
// read file
var model = this.Helper.ReadJsonFile<ModData>($"{Constants.SaveFolderName}/config.json") ?? new ModData();

// write file (if needed)
this.Helper.WriteJsonFile($"{Constants.SaveFolderName}/config.json", model);
```

## File I/O config wrapper
<p class="warning">
This section describes an experimental interface. Stability and backwards compatibility in future
versions are not guaranteed.
</p>

If your mod often reloads or saves the configuration, you can wrap your config model with file
I/O logic:

1. Create a `ModConfig` class (just like the previous section), but this time extend
   `StardewModdingAPI.Advanced.ConfigFile`:

   ```c#
   class ModConfig : StardewModdingAPI.Advanced.ConfigFile
   {
      public bool ExampleBoolean { get; set; }
      public float ExampleFloat { get; set; }

      public ModConfig()
      {
{'fraction_non_alphanumeric': 0.0999780268072951, 'fraction_numerical': 0.0026367831245880024, 'mean_word_length': 3.5429141716566868, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5822580', 'n_tokens_mistral': 1328, 'n_tokens_neox': 1278, 'n_words': 537}