ЧИНИМ СОХРАНЕНИЯ В 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


Автор материала: miosion
Материал от пользователя сайта.

Ren'Py 31.07.2020 583 miosion сохранения. traceback, RenPy.чинимсохранениянаrenpy, ren'py 4.0/4

Комментарии (4):
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
0
1 Хемуль  
87473
Вроде полезная информация. Спасибо.

1
2 miosion  
259436
Всегда пожалуйста! nbaka

1
3 СОНЦЕ  
93
А можно пожалуйста вкратце очертить что это именно, когда, и как происходит, чтобы быть начеку? Или просто у тех, кому вроде все ок, можно мимо крокодить?  nomnom

1
4 miosion  
259436
Рано или поздно с этой ошибкой да сталкиваются, но это скорее для понимающих зачем это нужно.

В кратце: например в игре человек сделал сейв, игру обновили вот там где был сейв, человеку вылетает traceback и он идет к разрабам в непонимании, что за дичь происходит.