Page 1 of 1

6.12.x: Style Preferences

Posted: Tue Jun 21, 2011 9:18 pm
by PyTom
Another day, another design.

I was thinking about if it would be possible to allow styles to change as the game progresses. After thinking it over a bit, the answer is yes, with the caveat that this only would apply to displayables created after the style change occurs. The screen system makes this caveat acceptable, since the text and windows on the screen are recreated when an interaction is restarted.

Anyway, I'm thinking of an API like this.

Code: Select all

A style preference is a preference that controls one or more style properties. A style preference has a name and one or more alternatives. At any given time, one of the alternatives is the selected for the style preference. The selected alternative is stored in the persistent data, and defaults to the first alternative registered for a style property.

An alternative has one or more associations of style, property, and value associated with it, and represents a promise that when the alternative becomes the selected alternative for the style preference, the property on the style will be assigned the given value. This occurs when Ren'Py first initializes, and then whenever a new alternative is selected.

renpy.register_style_preference(preference, alternative, style, property, value):

     Registers information about an alternative for a style preference.

    `preference`
        A string, the name of the style property.

    `alternative`
        A string, the name of the alternative.

    `style`
        The style that will be updated. This may be a style object or a string giving the style name.

    `property`
        A string giving the name of the style property that will be update.

    `value`
        The value that will be assigned to the style property.

renpy.set_style_preference(preference, alternative):

    Sets the selected alternative for the style preference.

    `preference`
        A string giving the name of the style preference.

    `alternative`
        A string giving the name of the alternative.

renpy.get_style_preference(preference):

    Returns a string giving the name of the selected alternative for the named style preference. 

    `preference`
        A string giving the name of the style preference.

StylePreference(preference, alternative):

    An action that causes `alternative` to become the selected alternative for the given style preference.

    `preference`
        A string giving the name of the style preference.

    `alternative`
        A string giving the name of the alternative.

One should ensure that every alternative for a given style preference updates the same set of styles and properties. Otherwise, some styles may not be assigned values, and the result will not be deterministic. 

Here's an example of registering a style property that allows the user to choose between large, simple text and smaller outlined text.

::

    init python:
        renpy.register_style_property("text", "decorated", style.say_dialogue, "outlines", [ (1, "#000", 0, 0) ])
        renpy.register_style_property("text", "decorated", style.say_dialogue, "size", 22)

        renpy.register_style_property("text", "large", style.say_dialogue, "outlines", [ ])
        renpy.register_style_property("text", "large", style.say_dialogue, "size", 24)

Re: 6.12.x: Style Preferences

Posted: Wed Jun 22, 2011 4:55 am
by Aleema
Interesting. So we could, if I'm interpreting this right, let the player customize the GUI? Or perhaps the GUI gets progressively worse as the story gets darker? Something like that? Or, as you have, have a "handicapped" option for readers who need large text?

And what COULDN'T this work with? Right now, I'm assuming anything in a Screen, the text, and dialogue window? Any UI function, or just screen language UI? Are game menus refreshed on interaction (is that included if they're using screens.rpy)? Sorry, just a bit confused on the extent of this.

Re: 6.12.x: Style Preferences

Posted: Sun Aug 07, 2011 11:45 pm
by PyTom
Aleema wrote:Interesting. So we could, if I'm interpreting this right, let the player customize the GUI? Or perhaps the GUI gets progressively worse as the story gets darker? Something like that? Or, as you have, have a "handicapped" option for readers who need large text?

And what COULDN'T this work with? Right now, I'm assuming anything in a Screen, the text, and dialogue window? Any UI function, or just screen language UI? Are game menus refreshed on interaction (is that included if they're using screens.rpy)? Sorry, just a bit confused on the extent of this.
Didn't notice this, so let me belatedly reply. The goal is to let people customize the gui, rather than have it change as the story proceeds. For example, one could offer a choice between text with outlines, text with a drop shadow, or text with none of that. I've demonstrated an interface that can change the font and size of all text in the game.

This works the best with screens, both screen language, and those defined with renpy.define_screen. For non-screen things, a style change will take effect the next time the thing is shown.

Anyway, here's the code for font and size picking, right out of my test script. (This would probably go on the preferences screen of a normal game.)

Code: Select all

init python:
    renpy.register_style_preference("font", "dejavu", style.default, "font", "DejaVuSans.ttf")
    renpy.register_style_preference("font", "mikachan", style.default, "font", "mikachan.ttf")
    
    renpy.register_style_preference("size", "20", style.default, "size", 20)
    renpy.register_style_preference("size", "22", style.default, "size", 22)
    renpy.register_style_preference("size", "24", style.default, "size", 24)

screen test:

    hbox:
        textbutton "dejavu" action StylePreference("font", "dejavu")    
        textbutton "mikachan" action StylePreference("font", "mikachan")    

        textbutton "20" action StylePreference("size", "20")    
        textbutton "22" action StylePreference("size", "22")    
        textbutton "24" action StylePreference("size", "24")    

Re: 6.12.x: Style Preferences

Posted: Mon Aug 08, 2011 12:35 am
by SleepKirby
The example definitely helps. Looks like a great idea - I would add the text style option to my game, and it would be neat to have a preference for something like the dialogue box design, as well.

One question - when the preference applies to style.default, like this:

Code: Select all

renpy.register_style_preference("size", "20", style.default, "size", 20)
Does setting this preference also change every style that inherited from style.default, like my_style here?:

Code: Select all

init:
    style.my_style = Style(style.default)    # Does my_style's font size change to 20 when the above preference is set?

Re: 6.12.x: Style Preferences

Posted: Mon Aug 08, 2011 6:18 am
by PyTom
It'll change style.default. So it would change all styles that inherit from style.default, except those that set the size to a more specific value.

Re: 6.12.x: Style Preferences

Posted: Wed Aug 10, 2011 10:38 pm
by Gumaster
Couldn't this possibly cause problems with the game text, though? For example, pages with text that barely managed to fit in would overflow if the size increased (not game-breaking, but a bit unpleasant to look at), and spacing text out with spaces (like having, say, "\ \ \ \ \ \ \ \ \ Boo!", to have the text appear indented for that one line) would result in the spaces increasing (due to increase font size) and the spacing would be thrown off as a result, possibly moving onto the new line.
It probably wouldn't be as much of a problem with ADV games as NVL though.

Re: 6.12.x: Style Preferences

Posted: Wed Aug 10, 2011 10:52 pm
by PyTom
The answer is yes, this could cause problems with game text.

That's why the design was limited to multiple-choice style preferences. I think it's reasonable to expect a creator to test at least the boundary conditions, like the smallest and largest font size.

While it would have been fairly easy to allow things like sliders, I deliberately held back, as it would probably make testing overly difficult.

Oh, and in 6.13, you can use the new {space=30} tag to always get 30 pixels of space. :-)

Re: 6.12.x: Style Preferences

Posted: Thu Aug 11, 2011 9:35 pm
by SleepKirby
It looks like you can use config.debug_text_overflow to at least detect those text overflow problems. If I'm understanding right, you would make sure you set your text window's xmaximum and ymaximum properly, then skip through your story and Ren'Py would log the overflows.

As for what to do about overflows, I guess there's a lot of options and it's best left to the game developer. You would either shorten or split up the overflowing lines of text, make more space in your dialogue window, or allow the dialogue window to expand when there's more text. (Or just not offer the larger font size options.)