Сайт Anivisual.net закрыт

Он продолжит функционировать в виде архива. Новые материалы добавлять нельзя.

ЧИНИМ СОХРАНЕНИЯ В REN'PY

ЧИНИМ СОХРАНЕНИЯ В REN'PY

Привет! Раз уж ты открыл эту статью, то я уверен ты создаешь визуальные новеллы на движке Ren'Py и хочу сказать, что это не является полностью решением проблемы с поломкой сохранений — это скорее костыль. А также если тебе помогла эта статья или была полезной, поддержи меня чем угодно - лайком, репостом, подпиской или добавлением дебютной игры в список желаемого в Steam)

Приступим к делу! Ссылку на исходник проекта я оставлю в конце статьи.

1. Прописываем вот такой код:
Код

label start:
  python:
   if persistent.jump_to:
   j = persistent.jump_to
   persistent.jump_to = False
   renpy.jump(j)



2. В options.rpy или где удобно прописываем вот такой код:
Код

init -998 python:
  def _on_save(json):
  json['game_version'] = config.version
  json['jump_chapter'] = current_chapter
  config.save_json_callbacks = [_on_save]


3. Создаем экран аналогичный экрану "confirm":
Код

screen dialog(message, yes_action, no_action):

  ## Гарантирует, что другие экраны будут недоступны, пока показан этот экран.
  modal True

  zorder 200

  style_prefix "confirm"

  add "gui/overlay/confirm.png"

  frame:

  vbox:
  xalign .5
  yalign .5
  spacing 45

  label _(message):
  style "confirm_prompt"
  xalign 0.5

  hbox:
  xalign 0.5
  spacing 150

  textbutton _("Да") action yes_action
  textbutton _("Нет") action no_action

  ## Правый клик и esc, как ответ "Нет".
  key "game_menu" action no_action


4. В начале script.rpy или где удобно прописываем вот такой код:
Код

init:
  $ current_chapter = "start"
#===================================================================================================
init python:
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals

  def save_is_compatible(name, page=None):
   
  save_json = FileJson(name=name, page=page)
   
  if save_json is None:
  return None
  else:
  save_version = save_json.get('game_version', '')
  return save_version

  def what_chapter(name, page=None):
  save_json = FileJson(name=name, page=page)
   
  if save_json is None:
  return "start"
  else:
  labels = renpy.get_all_labels()
  to_chapter = save_json.get('jump_chapter', '')
  if to_chapter in labels:
  return to_chapter
  else:
  return "start"


5. В screens.rpy прописываем выше экрана "file_slots", "saves" и "load"
вот такой код:
Код

init python:
  def FileActionMod(name):
   
  if renpy.get_screen("load") and FileLoadable(name) and not main_menu:
  if save_is_compatible(name) == config.version:
  return Show(screen="dialog", message=layout.LOADING,
  yes_action=(FileAction(name, confirm=False), Hide("dialog")), no_action=Hide("dialog"))
  else:
  return Show(screen="dialog", message="Это сохранение несовместимо с вашей версией игры и будет откатываться к началу главы.\n А также несохранённый прогресс будет потерян. Продолжить?",
  yes_action=(SetField(persistent, 'jump_to', what_chapter(name)), Hide("dialog"), Start()), no_action=Hide("dialog"))
   
  elif renpy.get_screen("load") and FileLoadable(name) and main_menu:
  if save_is_compatible(name) == config.version:
  return FileAction(name)
  else:
  return Show(screen="dialog", message="Это сохранение несовместимо с вашей версией игры и будет откатываться к началу главы. Продолжить?",
  yes_action=(SetField(persistent, 'jump_to', what_chapter(name)), Hide("dialog"), Start()), no_action=Hide("dialog"))
   
  elif renpy.get_screen("save") and FileLoadable(name) and not main_menu:
  return Show(screen="dialog", message=layout.OVERWRITE_SAVE,
  yes_action=(FileAction(name, confirm=False), Hide("dialog")), no_action=Hide("dialog"))
   
  elif renpy.get_screen("save") and not FileLoadable(name) and not main_menu:
  return FileAction(name)


6. В кнопке экрана "file_slots" мы прописываем вот такое действие FileActionMod(slot), вместо стандартного FileAction(slot).

Вуаля! Теперь создавая новую сборку и обновляя её, меняем версию игры и при попытке игрока загрузить сохранение — ему выйдет вот такое уведомление, конечно же его можно модифицировать, можно поставить другое действие или вообще просто удалять файл сохранения, но я считаю, что это немного неправильно. Удачи, вот исходник проекта. Буду рад поддержке и конечно же модификациям этого кода!

А вот так прописывается переменная "current_chapter", в начале главы, чтобы Ren'Py знал какое значение помещать в сохранение:

Код

label start:
  python:
   if persistent.jump_to:
   j = persistent.jump_to
   persistent.jump_to = False
   renpy.jump(j)

  $ current_chapter = "start"
  scene bg room

  show eileen happy

  e "Вы создали новую игру Ren'Py."

  e "Добавьте сюжет, изображения и музыку и отправьте её в мир!"

  return
18
Декабрь
6
3.7
5819
Добавлять комментарии могут только зарегистрированные пользователи.

Комментарии к записи: 6

avatar
#1 Хемуль
87473
в 13:58 (07/Авг/2020)
0
Вроде полезная информация. Спасибо.
avatar
#2 miosion
259436
в 10:02 (08/Авг/2020)
1
Всегда пожалуйста! nbaka
avatar
#3 СОНЦЕ
93
в 20:23 (10/Авг/2020)
1
А можно пожалуйста вкратце очертить что это именно, когда, и как происходит, чтобы быть начеку? Или просто у тех, кому вроде все ок, можно мимо крокодить?  nomnom
avatar
#4 miosion
259436
в 10:17 (12/Авг/2020)
1
Рано или поздно с этой ошибкой да сталкиваются, но это скорее для понимающих зачем это нужно.

В кратце: например в игре человек сделал сейв, игру обновили вот там где был сейв, человеку вылетает traceback и он идет к разрабам в непонимании, что за дичь происходит.
avatar
#5 dante00035
546558
в 07:10 (23/Окт/2021)
1
Спасибо огроменное!!! Давно искал способ изолирования сохранений предыдущих версий nlol
avatar
#6 RiokoRain
5267
в 19:24 (02/Авг/2022)
1
Спасибо большое, как раз искала решение данной проблемы  nlove 
Но все-таки правда хотелось бы узнать, а что именно происходит при активации кода
Я в силу своих познаний понимаю принцип лишь примерно, исходя из того, что написано
Не совсем уверена, что под цифрой 4 творится
Я и сама вношу в дефолтный код довольно много своих правок, и не хотелось бы, чтобы в один прекрасный момент что-то сломалось просто потому, что у меня что-то уже работает не совсем так, как оно было