ControlBindingsStore.cs
using Sandbox;
using System;

namespace PaintballBaddies;

// Preferences must survive an immediate quit and must not expire like cookies.
// Organization storage also keeps editor/local and published play consistent.
internal static class ControlBindingsStore
{
    private const string Directory = "paintball-baddies";
    private const string Path = Directory + "/controls-v1.json";

    public static Dictionary<string, string> Load()
    {
        try
        {
            if (FileSystem.OrganizationData.FileExists(Path))
                return FileSystem.OrganizationData.ReadJson<Dictionary<string, string>>(Path);
        }
        catch (Exception exception)
        {
            Log.Warning($"Could not read saved controls; using previous bindings. {exception.Message}");
        }
        return null;
    }

    public static bool Save(Dictionary<string, string> bindings)
    {
        try
        {
            FileSystem.OrganizationData.CreateDirectory(Directory);
            FileSystem.OrganizationData.WriteJson(Path, new Dictionary<string, string>(bindings));
            return true;
        }
        catch (Exception exception)
        {
            Log.Warning($"Could not save controls. {exception.Message}");
            return false;
        }
    }
}