readback module

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Message
Author
User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

readback module

#1 Post by delta » Mon Oct 13, 2008 4:40 am

People have been asking for this, so I made a readback implementation that actually works with current stock versions of Ren'Py as far as I know (the exact same code is already used in The Answer, which is pretty much vanilla 6.7.1). It needs Ren'Py 6.7.0 and up, I think, since config.nvl_show_display_say was introduced there, can't find it in the changelog right now. It properly integrates with the style and config system, see the init block on top of the file. There are a couple of things you may want to configure. It assumes you're using the classic navigation layout, though it shouldn't be hard to adapt it to other layouts. Just drop the attached file into your game folder, unless you've been non-trivially customising Ren'Py is should work as-is.

btw I won't promise to support this, though you can always ask questions.
Attachments
readback.rpy
(5.43 KiB) Downloaded 1095 times
The rest is left as an exercise for the reader.

User avatar
EvilDragon
Veteran
Posts: 284
Joined: Fri Dec 28, 2007 5:47 am
Location: Where the Dragons rule!
Contact:

Re: readback module

#2 Post by EvilDragon » Mon Oct 13, 2008 7:29 am

Cool man, I will have to try it.

BTW; I saw the parameter for defining readback buffer. 100 lines is the default. Is it possible to make it define pages (for NVL mode) rather than lines?
Angels of paradise, angels of sacrifice
Please let me be under your wings...

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#3 Post by delta » Mon Oct 13, 2008 8:22 am

Not without touching the engine itself (defeating the purpose of a flexible module). A NVL page is not really a logical "unit" in Ren'Py, and a line does not know which page it belongs to. This method only stores a list of lines which can not hold more items than the readback length. If you really need that, you have to hook into nvl_clear() to do... something. Probably to store a marker line in the readback buffer, and then adjust the prune function to work with these markers as boundaries. nvl_clear() is a very simple function that just clears the nvl buffer list and is defined in /common/00nvl_mode.rpy. It has no predefined hook, you'll need to hack it directly or overwrite it with your own function of the same name that does more than the standard one. That, however, can lead to problems in future version if that function ever changes (since this module is not part of the stock Ren'Py distro and overwriting nvl_clear() is not documented, I would not just assume it will never change).

I guess you want this because you don't want a partial nvl page in the readback buffer, not because you want an exact number of pages. In that case, just add the marker line as I said above and change the prune function to kill lines until it hits the last marker. If you want mixed NVL/ADV mode you also need to add such a marker line after each ADV line or it will go kill happy. And then you need to do some math to adjust the size of the readback buffer accordingly. In short, it's a hassle, like most things associated with NVL mode.

P.S. I should mention that the readback buffer lives in the store, and as such is saved with savegames. This is, on the one hand, a a very good thing, on the other hand it can bloat the memory footprint and savegame size if used too recklessly. Then again, game scripts aren't nearly long enough for this ever to make much of a difference, and it's just text, which should be insignificant in comparison to the sizes of an user's hard drive. So you can basically just set the length to a value higher than the number of lines in your script so it never gets pruned. Ever17, for example, does exactly that, and its script is humongous.
The rest is left as an exercise for the reader.

GJsoft

Re: readback module

#4 Post by GJsoft » Mon Oct 13, 2008 8:50 am

*deleted*
Last edited by GJsoft on Wed Aug 31, 2011 6:13 pm, edited 1 time in total.

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#5 Post by delta » Mon Oct 13, 2008 10:23 am

GJsoft wrote: I would only like to know if it would be possible to make a custom frame for readback.
Yes. What you're looking for is style.readback_window (and possibly others, see the script for details). I guess you know how to change a style, if not... sorry, I'm not even going to start.
The rest is left as an exercise for the reader.

User avatar
PyTom
Ren'Py Creator
Posts: 15893
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: readback module

#6 Post by PyTom » Mon Oct 13, 2008 10:42 am

Well, my disdain for a limited readback mode is well-known. So :-/. That being said, let me suggest a couple of things:

readback_catcher would probably be better written as:

Code: Select all

    def readback_catcher():
        ui.keymap(rollback=ui.callsinnewcontext("_game_menu", "text_history_screen"),
                        rollforward=ui.returns(None))
One thing that might be interesting would be to have a rollback function that first tries renpy.rollback, and then switches into readback mode if renpy.rollback returns. Coupled with an appropriate setting of the config variable, this could give the user a couple of screens of rollback, and then switch to readback for the rest.
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
"Silly and fun things are important." - Elon Musk
Software > Drama • https://www.patreon.com/renpytom

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#7 Post by delta » Mon Oct 13, 2008 11:02 am

PyTom wrote:Coupled with an appropriate setting of the config variable, this could give the user a couple of screens of rollback, and then switch to readback for the rest.
In KS (at the moment), I actually use rollback by default, but block it at each choice. Readback is available from the game menu if the user wants to read back beyond choices (i.e., it's available like in the "dev" readback level setting of this module). I don't switch between them automatically, because it seems confusing to me to switch from rollback to readback suddenly, but I plan to write it into the manual/help file. The blocking happens in my scene sequencer, so it's an easy solution, but far beyond the scope of a simple plugin.

As for the tired old readback vs. rollback argument, I see that rollback has far more technical merit and I wouldn't want to miss it for development, but in the end it's a stylistic choice that is up to the game designer. Flat-out denying it at an engine level seems like saying "you mustn't shoot a film in black and white when the far more technicaly refined color option is available" to me.
The rest is left as an exercise for the reader.

User avatar
EvilDragon
Veteran
Posts: 284
Joined: Fri Dec 28, 2007 5:47 am
Location: Where the Dragons rule!
Contact:

Re: readback module

#8 Post by EvilDragon » Wed Oct 15, 2008 8:47 am

delta wrote:Not without touching the engine itself (defeating the purpose of a flexible module). A NVL page is not really a logical "unit" in Ren'Py, and a line does not know which page it belongs to. This method only stores a list of lines which can not hold more items than the readback length. If you really need that, you have to hook into nvl_clear() to do... something. Probably to store a marker line in the readback buffer, and then adjust the prune function to work with these markers as boundaries. nvl_clear() is a very simple function that just clears the nvl buffer list and is defined in /common/00nvl_mode.rpy. It has no predefined hook, you'll need to hack it directly or overwrite it with your own function of the same name that does more than the standard one. That, however, can lead to problems in future version if that function ever changes (since this module is not part of the stock Ren'Py distro and overwriting nvl_clear() is not documented, I would not just assume it will never change).

I guess you want this because you don't want a partial nvl page in the readback buffer, not because you want an exact number of pages. In that case, just add the marker line as I said above and change the prune function to kill lines until it hits the last marker. If you want mixed NVL/ADV mode you also need to add such a marker line after each ADV line or it will go kill happy. And then you need to do some math to adjust the size of the readback buffer accordingly. In short, it's a hassle, like most things associated with NVL mode.
I'm using NVL mode only. Though I'm not that good a programmer to actually make what you said come true -_-'

Also, I'm always using nvl clear when needed. I seriously doubt that that function will ever change, its purpose is very... "clear" :D :D

EDIT: I actually tested your readback module in my project. It doesn't work right in NVL mode (v6.8.0b), it shows only the last NVL text line... At least to me. In the Eileen demo it worked fine, save for showing the text in actual pages they belong to (it showed all the lines continuously).
Angels of paradise, angels of sacrifice
Please let me be under your wings...

GJsoft

Re: readback module

#9 Post by GJsoft » Thu Oct 16, 2008 2:57 pm

*deleted*
Last edited by GJsoft on Wed Aug 31, 2011 6:13 pm, edited 1 time in total.

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#10 Post by delta » Thu Oct 16, 2008 4:57 pm

As I said, NVL pages are a totally arbitrary concept in Ren'Py and if you want readback to pick it up you'll have to hack the engine deeper than a module can do.

Also, it only showing the last line is something I never encountered. I'm looking into it.
The rest is left as an exercise for the reader.

User avatar
EvilDragon
Veteran
Posts: 284
Joined: Fri Dec 28, 2007 5:47 am
Location: Where the Dragons rule!
Contact:

Re: readback module

#11 Post by EvilDragon » Thu Mar 26, 2009 12:43 pm

Any news about this, delta?
Angels of paradise, angels of sacrifice
Please let me be under your wings...

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#12 Post by delta » Thu Mar 26, 2009 1:36 pm

No. I haven't been able to trigger that bug myself.
The rest is left as an exercise for the reader.

User avatar
EvilDragon
Veteran
Posts: 284
Joined: Fri Dec 28, 2007 5:47 am
Location: Where the Dragons rule!
Contact:

Re: readback module

#13 Post by EvilDragon » Thu Mar 26, 2009 1:48 pm

Use it with my game if it helps. :)
Angels of paradise, angels of sacrifice
Please let me be under your wings...

User avatar
delta
Epitome of Generic
Posts: 525
Joined: Sat Dec 22, 2007 12:59 pm
Projects: yes
Contact:

Re: readback module

#14 Post by delta » Fri Mar 27, 2009 2:01 pm

I found the error. You are constructing your characters with the NVLCharacter() object. This script assumes you use Character(kind=nvl), which is enough (I see that this contradicts the examples in the NVL documentation, but it makes no difference, either with this module or without it). Since I don't want to overwrite the NVLCharacter(), you will need to adjust your script like this:

Code: Select all

    $ blink = anim.Blink("img/misc/arrow1.png", 0.1, 0.1, 0.35, 0.35)
    $ ctc = Character(kind=nvl, ctc=blink, ctc_pause=blink)
    $ noctc = Character(None, kind=nvl, ctc=blink) #no {w} ctcs
    $ narrator = Character(None, kind=ctc)
    $ d = Character(None, kind=ctc, what_prefix='"', what_suffix='"', ) #dialogue
    $ dn = Character(None, kind=ctc, what_prefix='\n"', what_suffix='"') #dialogue with newline beforehand
The rest is left as an exercise for the reader.

User avatar
EvilDragon
Veteran
Posts: 284
Joined: Fri Dec 28, 2007 5:47 am
Location: Where the Dragons rule!
Contact:

Re: readback module

#15 Post by EvilDragon » Fri Mar 27, 2009 2:23 pm

Thanks, will try it!

Now only to somehow update readback with page markers (too rich for my blood ^^'). Also, is it possible to somehow detach the readback screen from the game menu, making it essentially the same as rollback, but with changed style? This is more of a journal use, the way you did it.
Angels of paradise, angels of sacrifice
Please let me be under your wings...

Post Reply

Who is online

Users browsing this forum: Google [Bot]