Привет! Раз уж ты открыл эту статью, то я уверен ты создаешь визуальные новеллы на движке 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
Комментарии к записи: 6
В кратце: например в игре человек сделал сейв, игру обновили вот там где был сейв, человеку вылетает traceback и он идет к разрабам в непонимании, что за дичь происходит.
Но все-таки правда хотелось бы узнать, а что именно происходит при активации кода
Я в силу своих познаний понимаю принцип лишь примерно, исходя из того, что написано
Не совсем уверена, что под цифрой 4 творится
Я и сама вношу в дефолтный код довольно много своих правок, и не хотелось бы, чтобы в один прекрасный момент что-то сломалось просто потому, что у меня что-то уже работает не совсем так, как оно было