Постоянные данные
Ren'Py поддерживает постоянные данные — сохраняемые данные, которые не
связаны с определённой точкой в игре. Доступ к постоянным данным
осуществляется через поля объекта persistent, который привязан к
переменной persistent.
Все данные, доступные через поля persistent, сохраняются, когда
Ren'Py завершает работу или когда вызывается функция renpy.save_persistent().
Постоянные данные загружаются при запуске Ren'Py и когда Ren'Py
обнаруживает, что постоянные данные на диске были обновлены.
Объект persistent является особенным в том, что доступ к неопределенному полю будет иметь значение None, а не вызывать исключение. Если по умолчанию для постоянного значения должно быть что-то отличное от None, следует использовать оператор default:
default persistent.main_background = "princess_not_saved"
Пример использования persistent — создание разблокируемой галереи изображений. Это делается путем хранения флага в persistent, который определяет, была ли галерея разблокирована, как в примере:
label gallery:
if not persistent.gallery_unlocked:
show background
centered "You haven't unlocked this gallery yet."
$ renpy.full_restart()
# Здесь фактическое отображение галереи.
Когда игрок получает концовку, которая разблокирует галерею, флаг должен быть установлен в True.
$ persistent.gallery_unlocked = True
Поскольку постоянные данные загружаются до выполнения блоков init python, постоянные данные
должны содержать только типы, которые являются родными для Python или Ren'Py. В качестве альтернативы
можно использовать классы, определенные в блоках python early, при условии,
что эти классы могут быть сериализованы (pickled) и реализуют равенство.
Поля, начинающиеся с двух подчёркиваний (__), поддерживаются, но к ним будет применён
эффект искажения имён, описанный в этом разделе,
что означает, что они будут специфичны для файла, в котором они определены. Это подразумевает, что
если файл будет переименован между двумя релизами, доступ к значению, которое это поле имело в
предыдущем релизе, будет нарушен.
Кроме того, эти поля не затрагиваются методом persistent._clear().
Напоминаем, что поля, начинающиеся с одного подчёркивания _, зарезервированы и
не должны использоваться.
Слияние постоянных данных
Бывают случаи, когда Ren'Py должен объединить постоянные данные из двух источников. Например, Ren'Py может потребоваться объединить постоянные данные, хранящиеся на USB-накопителе, с постоянными данными с локальной машины.
Ren'Py выполняет это слияние по полям, принимая значение
поля, которое было обновлено последним. В некоторых случаях это
нежелательное поведение. В таком случае можно использовать функцию renpy.register_persistent().
Например, если у нас есть набор просмотренных концовок, мы бы хотели получить объединение этого набора при слиянии данных.
init python:
if persistent.endings is None:
persistent.endings = set()
def merge_endings(old, new, current):
current.update(old)
current.update(new)
return current
renpy.register_persistent('endings', merge_endings)
Функции для постоянных данных
- persistent._hasattr(field_name)
Проверяет, было ли установлено постоянное поле field_name или нет. Это позволяет различать поля, которые были явно установлены в None, и поля, которые никогда не устанавливались.
- persistent._clear(progress=False)
Сбрасывает постоянные данные, за исключением полей, начинающихся с
__.- progress
Если true, также сбрасывает данные о прогрессе, которые хранит Ren'Py.
Обратите внимание, что это приведет к повторному применению значений по умолчанию.
- renpy.register_persistent(field, func)
Регистрирует функцию, которая используется для слияния значений поля persistent-объекта, загруженного с диска, со значениями текущего persistent-объекта.
- field
Имя поля в persistent-объекте.
- function
Функция, которая вызывается с тремя параметрами: old, new и current:
- old
Значение поля в более старом объекте.
- new
Значение поля в более новом объекте.
- current
Значение поля в текущем persistent-объекте. Этот параметр предоставляется для случаев, когда идентификатор объекта, на который ссылается поле, не может измениться.
Ожидается, что функция вернёт новое значение поля в persistent-объекте.
- renpy.save_persistent()
Сохраняет persistent-данные на диск.
Межигровые постоянные данные
Межигровые постоянные данные (Multi-Game persistence) — это функция, которая позволяет вам обмениваться информацией между играми Ren'Py. Это может быть полезно, если вы планируете сделать серию игр и хотите, чтобы они обменивались информацией.
Для использования межигровых постоянных данных объект MultiPersistent должен быть создан во время инициализации
(желательно с помощью define).
Затем пользователь может обновлять этот объект и сохранять его на диск,
вызывая его метод save. Неопределенные поля по умолчанию равны None. Чтобы обеспечить
возможность повторной загрузки объекта в другой игре, мы настоятельно не рекомендуем
хранить в объекте экземпляры пользовательских типов.
- class MultiPersistent(name, save_on_quit=False)
Создает новый объект
MultiPersistent. Это следует вызывать только во время инициализации, и он возвращает новыйMultiPersistentс заданным именем.- name
Имя, используемое для доступа к межигровым постоянным данным. Игры, использующие одно и то же имя, будут получать доступ к одним и тем же данным.
- save_on_quit
Если это True, этот объект будет автоматически сохраняться при завершении работы Ren'Py.
- save()
Сохраняет межигровые постоянные данные на диск. Этот метод необходимо вызывать после изменения данных.
В качестве примера, возьмем первую часть игры, состоящей из двух частей:
define mp = MultiPersistent("demo.renpy.org")
label start:
# ...
# Записываем факт, что пользователь прошел первую часть.
$ mp.beat_part_1 = True
$ mp.save()
e "You beat part 1. See you in part 2!"
А это вторая часть:
define mp = MultiPersistent("demo.renpy.org")
label start:
if mp.beat_part_1:
e "I see you've beaten part 1, so welcome back!"
else:
e "Hmm, you haven't played part 1, why not try it first?"