Спецификация API внутриигрового компаньона RKK Project 410

ДРУГИЕ ЯЗЫКИ

Этот документ также доступен на английском и немецком языках.

Модуль RKK Hook — внутриигровой компаньон для менеджера модификаций RKK Project 410. Модуль поставляется непосредственно в составе менеджера и не требует отдельной установки игроком. В игровом меню модификаций модуль отображается под названием «RKK Компаньон» (или «RKK Companion»).

Модуль не является сюжетной модификацией и не распространяется как самостоятельный файл через Steam Workshop. Включать собственную копию .rpy-файла хука в дистрибутив вашей модификации не требуется.

Настоящее руководство описывает публичный API пакета версии 1.3.4 (HOOK_VERSION 13) для операционных систем Windows и Linux. Все функции API спроектированы таким образом, что при отсутствии активной интеграции с менеджером их вызовы выполняются как безопасные холостые операции (no-op) и не вызывают исключений.

Важно: Обработка отсутствия менеджера
Если пользователь запускает модификацию без установленного менеджера RKK Project 410, функции rkk_* отсутствуют в пространстве имён store. Прямой вызов этих функций приведёт к ошибке NameError. Для предотвращения сбоев используйте безопасное обращение через getattr или объявите функции-заглушки (shim) в блоке init вашей модификации.


Архитектура и перехват системных функций Ren'Py

Для корректной фиксации сессий, сбора аварийных дампов и обеспечения переходов между игрой и менеджером хук перехватывает ряд системных механизмов Ren'Py:

  • config.exception_handler: Модуль регистрирует собственный обработчик ошибок с обязательным вызовом предыдущего обработчика в цепочке. При переопределении exception_handler в своём моде всегда сохраняйте и вызывайте ранее установленный обработчик.
  • os.startfile и webbrowser.open: Перехватываются попытки открытия системных файлов отчётов (traceback.txt, errors.txt, error.txt). Это предотвращает нежелательное появление окон Проводника Windows при сбоях. Все остальные пути и URL-адреса обрабатываются без изменений.
  • renpy.quit: Функция оборачивается однократно. Сохранение и фиксация состояния сессии подключаются к спискам обратных вызовов config.quit_callbacks и config.python_exit_callbacks.
  • config.label_callbacks и config.interact_callbacks: Обработчики хука добавляются в конец существующих списков без их очистки.

Предупреждение по цепочкам вызовов
При назначении собственных функций в exception_handler или обёрток над renpy.quit обязательно сохраняйте ссылку на предыдущую функцию и вызывайте её в конце работы. Не присваивайте пустые списки переменным label_callbacks, interact_callbacks или quit_callbacks — это приведёт к потере отчётов о крашах или нарушению работы сторонних обработчиков.


Обеспечение совместимости (Shim)

Способ 1. Однократный вызов без настройки

Для разовых вызовов функций API можно использовать безопасное обращение через getattr:

$ getattr(store, "rkk_note", lambda *a, **k: None)("Игрок достиг развилки")

Способ 2. Совместимая заглушка (Рекомендуется)

Если ваш мод неоднократно обращается к API, добавьте следующий блок заглушек в один из .rpy-файлов проекта. Заглушки создаются только тогда, когда настоящие функции компаньона отсутствуют. Порядок загрузки файлов не имеет значения: если менеджер установлен, его настоящие функции всегда переопределят заглушки.

init -1500 python:
    if "rkk_note" not in dir(store):
        def rkk_note(text, tag=None):
            pass
    if "rkk_report_mod_version" not in dir(store):
        def rkk_report_mod_version(mod_label, version):
            pass
    if "rkk_report_mod_title" not in dir(store):
        def rkk_report_mod_title(mod_label, title):
            pass
    if "rkk_is_companion_available" not in dir(store):
        def rkk_is_companion_available():
            return False
    if "rkk_companion_info" not in dir(store):
        def rkk_companion_info():
            return {"available": False}
    if "rkk_get_active_mods" not in dir(store):
        def rkk_get_active_mods():
            return {}
    if "rkk_set_context" not in dir(store):
        def rkk_set_context(key, value):
            pass
    if "rkk_get_context" not in dir(store):
        def rkk_get_context():
            return {}
    if "rkk_open_manager" not in dir(store):
        def rkk_open_manager():
            pass
    if "rkk_visual_poll_reload" not in dir(store):
        def rkk_visual_poll_reload():
            return False

Справочник функций API

rkk_note(text, tag=None)

Записывает текстовую контрольную точку (breadcrumb) в историю текущей сессии и аварийный отчёт при краше. Содержит текст сообщения, временную метку и текущую метку сценария (label). Записи не сохраняются в постоянный текстовый лог на диске.

$ rkk_note("Открыта галерея персонажей")
$ rkk_note("Игрок погиб у столовой", tag="death")
  • Параметры:
    • text (str) — текст заметки (до 160 символов).
    • tag (str, опционально) — категория или тег события (до 40 символов).
  • Ограничения: В аварийном дампе сохраняются последние 20 заметок.
  • Рекомендации: Вызывайте функцию на ключевых сюжетообразующих развилках и значимых событиях. Избегайте вызовов на каждом шаге interact.

rkk_set_context(key, value) / rkk_get_context()

Устанавливает или возвращает постоянные теги контекста сессии. В отличие от однократных заметок rkk_note, контекст сохраняет своё значение до тех пор, пока не будет явно изменён или сброшен. Для удаления ключа передайте None или пустую строку в качестве value.

$ rkk_set_context("route", "Ulyana")
$ rkk_set_context("day", "7")
$ rkk_set_context("route", None) # Сброс ключа

$ current_context = rkk_get_context()
  • Ограничения:
    • Максимум 16 активных ключей в контексте.
    • Длина ключа (key) — до 40 символов.
    • Длина значения (value) — до 80 символов.

rkk_report_mod_version(mod_label, version)

Передаёт номер версии вашей модификации компаньону для сопоставления данных в отчётах об ошибках. Вызывается один раз при инициализации. Идентификатор mod_label должен совпадать с ключом, под которым мод зарегистрирован в глобальном словаре mods[...].

init:
    $ mods["my_cool_mod"] = "Мой мод"
    $ rkk_report_mod_version("my_cool_mod", "1.4.2")
  • Ограничения: Длина mod_label — до 80 символов, version — до 40 символов. При отсутствии вызова версия мода не попадёт в аварийный отчёт.

rkk_report_mod_title(mod_label, title)

Передаёт отображаемое название модификации для интерфейса библиотеки лаунчера. Используется в случаях, когда имя в mods[...] формируется динамически (через переменные или функции локализации _()), из-за чего статический парсер лаунчера не может извлечь имя из файла.

init python:
    my_mod_name = _("Мой мод")

init:
    $ mods["my_cool_mod"] = my_mod_name
    $ rkk_report_mod_title("my_cool_mod", my_mod_name)
  • Ограничения: Длина названия — до 120 символов. Сведения записываются в файл rkk/mod-titles.json и экспортируются в отчёт сессии.

rkk_get_active_mods()

Возвращает словарь вида {mod_label: version} для всех модификаций, вызвавших rkk_report_mod_version в текущей игровой сессии. Предназначен для лёгких проверок совместимости и мягких зависимостей между модами без участия интерфейса лаунчера.

$ active_versions = rkk_get_active_mods()
if "another_mod" in active_versions:
    $ rkk_note("Совместимость: обнаружен another_mod v" + active_versions["another_mod"], tag="compat")

rkk_is_companion_available() / rkk_companion_info()

Служат для проверки активности и параметров модуля-компаньона перед отрисовкой пользовательского интерфейса. Функция rkk_is_companion_available() возвращает True, если найден конфигурационный файл hook.ini и указанный путь к менеджеру валиден.

if rkk_is_companion_available():
    $ info = rkk_companion_info()

Структура словаря, возвращаемого rkk_companion_info():

| Ключ | Тип | Описание | | :--- | :--- | :--- | | available | bool | Флаг готовности и активности интеграции | | hook_version | int | Числовой номер версии хука (текущий: 13) | | hook_version_label | str | Строковое обозначение версии пакета ("1.3.4") | | detect_crashes | bool | Состояние перехватчика аварийных сбоев | | session_id | str | Уникальный идентификатор текущей игровой сессии |

При отсутствии компаньона функции возвращают False и {"available": False} соответственно.


rkk_open_manager()

Сохраняет и экспортирует данные текущей сессии, запускает менеджер модификаций RKK Project 410 и завершает процесс игры. Вызов функции следует выполнять только после предварительной проверки через rkk_is_companion_available().

if rkk_is_companion_available():
    textbutton _("Менеджер RKK Project 410"):
        action Function(rkk_open_manager)

Если бинарный файл менеджера недоступен, выводится всплывающее уведомление renpy.notify, а игра продолжается.


rkk_visual_poll_reload()

Вспомогательный метод для инструментария Visual Author (не используется в сюжете). Проверяет наличие файла-метки .rkk_visual_reload в каталоге game/ или в корневой папке проекта. Если метка найдена, функция удаляет её и вызывает renpy.reload_script(). Возвращает True, если произошла перезагрузка, иначе — False.


Полный пример применения в модификации

# 1. Безопасные заглушки для автономного запуска
init -1500 python:
    if "rkk_note" not in dir(store):
        def rkk_note(text, tag=None):
            pass
    if "rkk_report_mod_version" not in dir(store):
        def rkk_report_mod_version(mod_label, version):
            pass
    if "rkk_set_context" not in dir(store):
        def rkk_set_context(key, value):
            pass
    if "rkk_get_active_mods" not in dir(store):
        def rkk_get_active_mods():
            return {}

# 2. Регистрация модификации
init:
    $ mods["my_mod_label"] = "Моя сюжетная модификация"
    $ rkk_report_mod_version("my_mod_label", "1.4.2")

# 3. Игровой сценарий
label my_mod_label:
    $ rkk_set_context("route", "Ulyana")
    $ rkk_set_context("day", "7")

    $ mods_active = rkk_get_active_mods()
    if "busy_patch" in mods_active:
        $ rkk_note("Активирован патч совместимости: busy_patch " + mods_active["busy_patch"], tag="compat")

    "Главный герой подошёл к зданию столовой."
    $ rkk_note("Игрок погиб возле столовой", tag="death")
    return

При запуске мода у игрока без установленного менеджера RKK Project 410 файл функционирует как стандартная модификация без вызова ошибок. При наличии менеджера все данные контекста, версии и контрольные точки корректно заносятся в отчёт.