НАСТРОЙКИ МОДОВ (id: modsettings) — как подключить свой мод
===========================================================

Что это
-------
Мод добавляет в веер меню (под молотком) кнопку «Настройки модов». В окне слева —
моды, которые подключили настройки, справа — сами настройки выбранного мода:
  bool    — кнопка ПЕРЕКЛ. (ВКЛ / ВЫКЛ)
  number  — кнопки − и + с шагом step между min и max
  choice  — кнопки − и + по списку options
  action  — кнопка ВЫПОЛНИТЬ: хаб шлёт моду сигнал, мод делает что хочет
Кнопка ПО УМОЛЧАНИЮ сбрасывает настройки выбранного мода.

Значения лежат в СОХРАНЕНИИ хаба (alem.set), у каждой колонии свои. Это отличается от
родных настроек mod.json → settings: те одинаковы для всех партий. Если вам нужны
настройки «на устройство» — используйте родные.

Подключение: мягкое, без requires
---------------------------------
Хаб не нужен вашему моду для запуска. Нет хаба — мод берёт значения по умолчанию.

1) Объявить настройки (на загрузке скрипта — один раз, самый простой способ):

  alem.shared.set("modsettings_def_" .. "id_вашего_мода", {
    title = "Мой мод",                       -- заголовок в окне (по умолчанию name из mod.json)
    desc  = "Короткое описание, до ~70 букв",
    items = {
      { id = "wolves", name = "Волки у юрт", type = "bool",   def = true,  desc = "…" },
      { id = "loot",   name = "Добыча, ×",   type = "number", def = 1, min = 0, max = 3, step = 0.5 },
      { id = "mode",   name = "Письмо",      type = "choice", def = 1, options = { "нет", "короткое", "подробное" } },
      { id = "reset_all", name = "Сбросить мир", type = "action" },
    },
  })

  Поля те же, что у родных настроек в mod.json: id, name, desc, type, def, min, max, step,
  options. def у choice — номер варианта с нуля. Максимум 60 настроек на мод.
  Ключ на доске должен начинаться с modsettings_def_ и заканчиваться id вашего мода.

  Второй способ — вызовом (в on_mods_ready, когда все скрипты загружены):
  if alem.can_call("modsettings", "register") then
    alem.call("modsettings", "register", { mod = "id_вашего_мода", title = "…", items = { … } })
  end

2) Прочитать значение:

  local v = alem.call("modsettings", "get", "id_вашего_мода", "wolves", true)   -- true — запасное
  -- bool → true/false, number → число, choice → строка варианта
  Перед вызовом: alem.can_call("modsettings", "get") — нет хаба, значит, берите своё запасное.

  Можно и без вызова: хаб зеркалит значения на доску.
  alem.shared.get("modsettings_v_id_вашего_мода_wolves", true)

3) Узнавать об изменениях и действиях (без опроса):

  alem.on("on_mod_event", function(name, data, from)
    if data.mod ~= "id_вашего_мода" then return end
    if name == "modsettings_changed" then  -- data = { mod, id, value }
    elseif name == "modsettings_action" then  -- data = { mod, id }
    end
  end)
  Или следить за одним ключом: alem.shared.watch("modsettings_v_<мод>_<id>", function(value) end)

Открытые функции хаба (договор)
-------------------------------
  alem.call("modsettings", "register", def)            -> true / false   def.mod обязателен
  alem.call("modsettings", "get", мод, id, запасное)   -> значение или запасное
  alem.call("modsettings", "set", мод, id, значение)   -> true / false   (choice: строка варианта или номер с нуля)
  alem.call("modsettings", "reset", мод)               -> true / false   вернуть def всем настройкам мода
  alem.call("modsettings", "open", мод)                -> true / false   открыть окно на вашем моде
  alem.call("modsettings", "list")                     -> список id подключённых модов
  alem.call("modsettings", "version")                  -> 1
  Ещё на доске: modsettings_api = 1 (версия соглашения).
Сигналы хаба: modsettings_changed {mod, id, value}, modsettings_action {mod, id}.

Правила, чтобы не ссориться
---------------------------
  * Всегда проверяйте alem.can_call("modsettings", …) — «нет хаба» это норма, а не ошибка.
  * Не нужно requires: он выключит ваш мод, если хаба нет.
  * Старые данные не пропадают: значение хранится по id настройки. Не меняйте id между версиями.
  * Если хаб не принял описание — причина в журнале мода (кнопка ЖУРНАЛ на экране «Моды»).
