The main way I've seen floating around to add a history/backlog jump button is with this code, which rolls back to the identifier of the targeted HistoryEntry object in the _history_list variable:
Code: Select all
define gui.button_text_idle_color = '#00FF00'
screen history():
tag menu
## Avoid predicting this screen, as it can be very large.
predict False
use game_menu(_("History"), scroll=("vpgrid" if gui.history_height else "viewport"), yinitial=1.0):
style_prefix "history"
for h in _history_list:
window:
## This lays things out properly if history_height is None.
has fixed:
yfit True
################## History/backlog jump button code.
# Shows the number of checkpoints that Ren'Py thinks need to be rolled back to get to this line. If this is "None," it can't get here.
$ getIdentifier = renpy.get_identifier_checkpoints(h.rollback_identifier)
text "h.rollback_identifier: [getIdentifier]" xalign 0.0 yalign 0.3
# The necessary history/backlog jump button.
textbutton _("Jump") action RollbackToIdentifier(h.rollback_identifier)
################## End of extra code.
if h.who:
label h.who:
style "history_name"
substitute False
## Take the color of the who text from the Character, if
## set.
if "color" in h.who_args:
text_color h.who_args["color"]
$ what = renpy.filter_text_tags(h.what, allow=gui.history_allow_tags)
text what:
substitute False
if not _history_list:
label _("The dialogue history is empty.")
Because config.hard_rollback_limit = 100 by default, the max rollback stops here:
config.hard_rollback_limit and config.rollback_length must be changed together. Because config.rollback_length = 128 by default, 128 it will always be the maximum number of rollbacks regardless of config.hard_rollback_limit. This is not a problem, as these both can be set to 250, to match config.history_length = 250 by default.
Here's where the problem begins. If I rollback 98 lines, it jumps there just fine, but then I can only rollback 2 more lines. Annoyingly, it does not load another 100 lines for rollback, the remainders stay as "None." You could try to hide this issue by setting the config.hard_rollback_limit and config.rollback_length variables to something like crazy like 1,000, but it would just make it really laggy, unoptimized, and this still doesn't fix the problem if the user, for example, does 10 rollbacks of 100 lines in a row:
==============================================================================================================================================
So I came up with a new idea of forcing rolling back the same number of lines in the history as the number of checkpoints it would take to get there, the "Actual" number:
Code: Select all
[code]define gui.button_text_idle_color = '#00FF00'
screen history():
tag menu
## Avoid predicting this screen, as it can be very large.
predict False
use game_menu(_("History"), scroll=("vpgrid" if gui.history_height else "viewport"), yinitial=1.0):
style_prefix "history"
########## The number of objects resets to 0 each time the list is loaded.
$ number = 0
for h in _history_list:
window:
## This lays things out properly if history_height is None.
has fixed:
yfit True
################## History/backlog jump button code.
# Shows the number of checkpoints that Ren'Py thinks need to be rolled back to get to this line.
# If this is "None" it can't get here.
$ getIdentifier = renpy.get_identifier_checkpoints(h.rollback_identifier)
text "h.rollback_identifier: [getIdentifier]" xalign 0.0 yalign 0.3
# Shows the actual number of checkpoints that Ren'Py needs to roll back to get to this line.
# This list has to be reversed, or the numbers would be start large and get small.
# Gets the total number of history objects until it maxes out at 250, which is the default.
# This is necessary for any number of history objects under 250 at the beginning of the game.
$ historynum = len(_history_list)
# Adds 1 for each new history object.
$ number += 1
# Uses the total number of history objects and the current number to reverse the list.
$ getActual = historynum + 1 - number
text "Actual: [getActual]" xalign 0.0 yalign 0.6
# The necessary history/backlog jump button, which now rolls back the exact number it should.
textbutton _("Jump") action Rollback(force=True, checkpoints=getActual, abnormal=False)
################## End of extra code.
if h.who:
label h.who:
style "history_name"
substitute False
## Take the color of the who text from the Character, if
## set.
if "color" in h.who_args:
text_color h.who_args["color"]
$ what = renpy.filter_text_tags(h.what, allow=gui.history_allow_tags)
text what:
substitute False
if not _history_list:
label _("The dialogue history is empty.")
This works, but for some reason I can't rollback to where the h.rollback_identifier and "Actual" number are not the same or is "None," even though I'm not using h.rollback_identifier to jump. And it still doesn't load another 100 lines for rollback, the remainders always stay as "None." The final images below show what I mean by checkpoints being of order. The identifier number should just count up normally like the "Actual" number I added, but sometimes, randomly through stress testing, loading and unloading, and refreshing, it will eventually be out of order and say "None" randomly:
The perfect solution would be getting the game to always rollback to the "Actual" number, without question, and without any errors, every time, because the "Actual" number is always correct. But I'm out of ideas. If anyone has a way to improve my code or something completely different to get this cool feature to work, please let me know. Thanks.
Here are the files of my test game if you're interested: And the traceback below when I try to jump and it doesn't work because the checkpoints are out of order or "None":
Code: Select all
I'm sorry, but an uncaught exception occurred.
While running game code:
File "renpy/common/00gamemenu.rpy", line 170, in script
$ ui.interact()
File "renpy/common/00gamemenu.rpy", line 170, in <module>
$ ui.interact()
File "renpy/common/00action_other.rpy", line 233, in __call__
renpy.rollback(*self.args, **self.kwargs)
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "renpy/common/00gamemenu.rpy", line 170, in script
$ ui.interact()
File "D:\Programs\renpy-8.0.3-sdk\renpy\ast.py", line 1131, in execute
renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
File "D:\Programs\renpy-8.0.3-sdk\renpy\python.py", line 1061, in py_exec_bytecode
exec(bytecode, globals, locals)
File "renpy/common/00gamemenu.rpy", line 170, in <module>
$ ui.interact()
File "D:\Programs\renpy-8.0.3-sdk\renpy\ui.py", line 299, in interact
rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\core.py", line 3377, in interact
repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, pause=pause, pause_start=pause_start, pause_modal=pause_modal, **kwargs) # type: ignore
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\core.py", line 4258, in interact_core
rv = root_widget.event(ev, x, y, 0)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\transition.py", line 53, in event
return self.new_widget.event(ev, x, y, st) # E1101
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\screen.py", line 743, in event
rv = self.child.event(ev, x, y, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1399, in event
rv = super(Window, self).event(ev, x, y, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 279, in event
rv = d.event(ev, x - xo, y - yo, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1399, in event
rv = super(Window, self).event(ev, x, y, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 279, in event
rv = d.event(ev, x - xo, y - yo, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 279, in event
rv = d.event(ev, x - xo, y - yo, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\viewport.py", line 298, in event
rv = super(Viewport, self).event(ev, x, y, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 279, in event
rv = d.event(ev, x - xo, y - yo, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1399, in event
rv = super(Window, self).event(ev, x, y, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 279, in event
rv = d.event(ev, x - xo, y - yo, st)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\layout.py", line 1175, in event
rv = i.event(ev, x - xo, y - yo, cst)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\behavior.py", line 1073, in event
return handle_click(self.clicked)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\behavior.py", line 1008, in handle_click
rv = run(action)
File "D:\Programs\renpy-8.0.3-sdk\renpy\display\behavior.py", line 329, in run
return action(*args, **kwargs)
File "renpy/common/00action_other.rpy", line 233, in __call__
renpy.rollback(*self.args, **self.kwargs)
File "D:\Programs\renpy-8.0.3-sdk\renpy\exports.py", line 1716, in rollback
renpy.game.log.rollback(checkpoints, greedy=greedy, label=label, force=(force is True), abnormal=abnormal, current_label=current_label)
File "D:\Programs\renpy-8.0.3-sdk\renpy\rollback.py", line 889, in rollback
self.load_failed()
File "D:\Programs\renpy-8.0.3-sdk\renpy\rollback.py", line 807, in load_failed
raise Exception("Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?")
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?
Windows-10-10.0.19043 AMD64
Ren'Py 8.0.3.22090809
History Backlog Jump Button Test 803 1.0
Thu Sep 8 23:13:10 2022