public static void Save()
 {
     try {
         var jsonFileNode = new JSONNode();
         jsonFileNode.SetAs("NextNpcID", NextNpcID);
         jsonFileNode.SetAs("NotifyKingdomPermission", NotifyKingdomPermission);
         jsonFileNode.SetAs("NotifyLootboxPermission", NotifyLootboxPermission);
         jsonFileNode.SetAs("spawner", KingdomSpawner.GetJson());
         jsonFileNode.SetAs("loot", Lootbox.GetJson());
         JSONNode jsonKingdoms = new JSONNode(NodeType.Array);
         try {
             KingdomsLock.EnterReadLock();
             foreach (NpcKingdom kingdom in Kingdoms)
             {
                 jsonKingdoms.AddToArray(kingdom.GetJson());
             }
         } finally {
             if (KingdomsLock.IsReadLockHeld)
             {
                 KingdomsLock.ExitReadLock();
             }
         }
         jsonFileNode.SetAs("kingdoms", jsonKingdoms);
         JSON.Serialize(JsonFilePath, jsonFileNode, 3);
         Log.Write($"Saved {Count} kingdoms to json");
     } catch (Exception exception) {
         Log.WriteError($"Exception while saving kingdoms; {exception.Message}");
     }
 }
 public static void Load()
 {
     try {
         JSONNode jsonFileNode;
         if (JSON.Deserialize(JsonFilePath, out jsonFileNode, false))
         {
             try {
                 KingdomsLock.EnterWriteLock();
                 Kingdoms.Clear();
             } finally {
                 if (KingdomsLock.IsWriteLockHeld)
                 {
                     KingdomsLock.ExitWriteLock();
                 }
             }
             jsonFileNode.TryGetAsOrDefault("NextNpcID", out NextNpcID, DefaultNextNpcID);
             jsonFileNode.TryGetAsOrDefault("NotifyKingdomPermission", out NotifyKingdomPermission, DefaultNotifyPermission);
             jsonFileNode.TryGetAsOrDefault("NotifyLootboxPermission", out NotifyLootboxPermission, DefaultNotifyPermission);
             JSONNode jsonSpawner;
             if (jsonFileNode.TryGetAs("spawner", out jsonSpawner) && jsonSpawner.NodeType == NodeType.Object)
             {
                 KingdomSpawner.SetFromJson(jsonSpawner);
             }
             else
             {
                 Log.Write($"kingdom spawner not configured in {JsonFilePath}, loading defaults");
             }
             JSONNode jsonLoot;
             if (jsonFileNode.TryGetAs("loot", out jsonLoot))
             {
                 Lootbox.SetFromJson(jsonLoot);
             }
             JSONNode jsonKingdoms;
             if (!jsonFileNode.TryGetAs("kingdoms", out jsonKingdoms) || jsonKingdoms.NodeType != NodeType.Array)
             {
                 Log.WriteError($"No 'kingdoms' array found in '{JsonFilePath}'");
                 return;
             }
             foreach (JSONNode jsonNode in jsonKingdoms.LoopArray())
             {
                 string type;
                 if (jsonNode.TryGetAs("KingdomType", out type))
                 {
                     NpcKingdom kingdom;
                     if ("farm".Equals(type))
                     {
                         kingdom = new NpcFarm();
                     }
                     else
                     {
                         Log.WriteError($"Unknown npc kingdom type {type}");
                         continue;
                     }
                     kingdom.InitFromJson(jsonNode);
                     NextNpcID = System.Math.Max(NextNpcID, kingdom.NpcID);
                 }
             }
             Log.Write($"Loaded {Count} kingdoms from json");
         }
     } catch (Exception exception) {
         Log.WriteError($"Exception while loading kingdoms; {exception.Message}");
     }
 }