Page 1 of 1

FancyText: Effects for Slow Text Display

Posted: Fri Jul 17, 2020 4:02 am
by yukinogatari
What is this?

FancyText is a simple drop-in module for Ren'Py 7.3.5 that lets you display text on screens with a little more pizazz than vanilla. In simpler terms, it lets you add fade-in or slide or rotation effects to slow text display.

Click the image below to see a quick sample of what FancyText is capable of doing.

example.gif

Where can I get it?

You can download the code from the FancyText GitHub repository.

How do I use it?

Simply drop 01_fancytext.rpy into your game's directory and you'll have access to the new fancytext screen language statement. fancytext is identical to the built-in text, but with three new parameters added.
  • slow_effect: An effect that applies to each character of text as it's being displayed.
  • slow_effect_delay: The time, in seconds, slow_effect will take to complete.
  • always_effect: An effect that applies to each character of text for the duration that it's on-screen, after slow_effect has completed.
For specific examples and to see the effects in action, check out script.rpy, or drop the whole file into a new project.

Included Effects

Effects that begin with slow_ are for use with the slow_effect parameter. Effects that have parameters must have those parameters provided. Slow effects only work when the text cps is set to something other than 0, and animate across the text at the rate of text display.
  • slow_typewriter: A non-effect that replicates the built-in typewriter effect.
  • slow_fade: Slowly fades characters in over slow_effect_delay seconds.
  • slow_slide_up(y = 20): Slides the text up y pixels into place over slow_effect_delay seconds.
  • slow_slide_down(y = 20): Slides the text down y pixels into place over slow_effect_delay seconds.
  • slow_slide_right(x = 20): Slides the text right x pixels into place over slow_effect_delay seconds.
  • slow_slide_left(x = 20): Slides the text left x pixels into place over slow_effect_delay seconds.
  • slow_shake(x = 0, y = 0): Causes each character to shake for slow_effect_delay seconds with an intensity of x horizontal pixels and y vertical pixels.
  • slow_rotate: Causes each character to rotate 360 degrees over slow_effect_delay seconds.
  • slow_shaking_slide(shake_x = 0, shake_y = 0, slide_x = 0, slide_y = 0): A combination of slow_shake and the slow_slide functions.
  • slow_nonsense: Changes the position, alpha, and angle of every character wildly over slow_effect_delay seconds.
Effects that begin with always_ are for use with the always_effect parameter, and will affect the text for as long as it's on screen.
  • always_shake(x = 0, y = 0): Causes each character to shake with an intensity of x horizontal pixels and y vertical pixels.
  • always_pulse: Causes the text to slowly cycle between visible and invisible.
How does it work?

FancyText is a basic modification of the built-in Text that expands rendering to apply a small range of transformations to each individual glyph as it's displayed to the screen in slow mode. In effect, this allows you to expand on the default typewriter style, adding fades or slides or rotations to text as it appears.

It does so by hijacking the unused alpha property on Blit objects to store a Transform, applying the values of alpha, xoffset, yoffset, and rotate (no support for changing the center of rotation) to each individual glyph every time it's drawn. This means FancyText is, unsurprisingly, more resource-intensive than default text rendering.

The Transform objects are created by a function that takes three parameters: st, gt, and delay—the current time, the time the current glyph is expected to begin displaying, and the amount of time the glyph has allotted to complete displaying. This is similar to how ATL functions work, only applied to every character over the duration of the line displaying.

There also exists functions for transforming the text constantly, which I've dubbed "always effects." They work the same way as slow effects, take effect after any slow effect is complete, and have no "end" time. They continue to update until the user clicks past the line. I honestly can't think of any really practical use for this, but practicality's never stopped me from doing anything before.

You can look inside 01_fancytext.rpy to see a bunch of example functions and how they work.

FancyText effectively patches a few functions into the Text class, so it relies on a bunch of assumptions about how the Text class works in this specific version (7.3.5). This is generally known as "a bad idea," and as such, I cannot guarantee it will work with any past or future versions of Ren'Py.

Why not make a pull request?

Because, in short, this code is terrible. I programmed it this way for simplicity of implementation and speed of experimentation, sacrificing things like efficiency and modularity in the process. It's a bunch of dirty hacks to do something the text system is only kind of designed for, but it was cool enough to want to share.

That said, if someone wants to expand this into a proper animation feature for text, they are more than welcome to.

Can I use it for ____?

Yes. FancyText is released under the MIT license, the same license as Ren'Py itself. A good portion of the code is copied and modified from Ren'Py's source code, so it seemed only reasonable to release it under the same license.

Why did you make this???

I needed a gentle fade-in effect on my text for something, and searching the forum only led me to other users requesting the same thing going back years. That need combined with tax-related depression and a complete lack of concern for real-world practicality led to this crime against good coding practices.

Disclaimers and stuff

Honestly, I haven't tested this very much, so I can't guarantee it won't horribly break things in games more complicated than the tutorial. If you do run into any problems though, please feel free to let me know.

A lot of the included effects aren't practical, and should probably not be used in actual games, except sparingly. I'm not going to stop you from making a character that talks in slow_nonsense, though.

Re: FancyText: Effects for Slow Text Display

Posted: Fri Jul 17, 2020 5:19 am
by abysswatcher
This is really cool! Thanks for the amazing code and effects!

Re: FancyText: Effects for Slow Text Display

Posted: Wed Jul 29, 2020 11:37 pm
by Tayruu
Hell yeah, a soft fade to the typewriter effect is just the sort of thing I've been after myself. Shaking text is a neat and possibly useful effect too.

There's a few minor hiccups though.

- Fancytext doesn't like text outlines. If the dialogue has an outline style, it throws an error.

Code: Select all

While running game code:
  File "game/sc_00_debug.rpy", line 60, in script
    hawke "My name is Hawke."
  File "game/_init_s_fancytext.rpy", line 271, in render
    oblits = outline_blits(blits, o)
NameError: global name 'outline_blits' is not defined
- Any introductory effect replays after mid-message pauses. Tested with slow_fade and slow_nonsense and {w}/{w=x} tags.)
- This also appears to affect extend. I use extend to show menus at the end of dialogue, like so:

Code: Select all

    inu "I woke up in this forest,{w=0.4} and with this body,{w=0.6} and I haven't found anyone else around."
    show hawke neutral
    pause(0.4)
    label debug_dialogue_a1:
    menu:
        extend ""
        [menu starts here]
With the default text function, this effect is seamless. With fancytext, there's a noticeable jump and the text disappears for a moment as it regenerates the whole line again.

- Not easily implemented with the nvl screen, though this seems to be a fault of nvl not liking to have arguments. I can still put fancytext what id what_id slow_effect slow_fade slow_effect_delay 0.1 in the nvl screen itself without worry.

... I really love slow_nonsense though. If that madness could be centered on the line more than come from above, it might be a good effect.

Re: FancyText: Effects for Slow Text Display

Posted: Thu Jul 30, 2020 4:49 am
by yukinogatari
Thanks for the reports, and I'm glad you're enjoying the effects! I've pushed an update to the repository that should fix the outline issue and text reanimating. The sample script you posted appears to run as expected now~ Let me know if you run into any other issues!

At some point when I have more time, I may try and make it possible to adjust the center of rotation for the rotation effects (matrices are hard and it's been years since I last thought about linear algebra lmao).

Re: FancyText: Effects for Slow Text Display

Posted: Fri Jul 31, 2020 2:43 am
by Tayruu
I can confirm that the repeating of the animation on extend and wait tags is fixed, as well as outlines.

... oops, turns out that pause was literally the pause(0.4) in that code. Wonder why that was there.
Regardless, it seems all smooth sailing. o:

Re: FancyText: Effects for Slow Text Display

Posted: Tue Aug 04, 2020 7:01 pm
by Perihelion
This is really cool! Thanks for this. Unfortunately the alpha manipulation seems to be broken in the nightly build. Any plans to get it working with nightly?

Re: FancyText: Effects for Slow Text Display

Posted: Wed Aug 05, 2020 1:47 am
by yukinogatari
I'll probably update it for the next stable release, but I'm a bit too busy to look into the nightlies.

Re: FancyText: Effects for Slow Text Display

Posted: Wed Aug 05, 2020 9:32 am
by Wudgeous
I just wanted to say this is one of the coolest things I've ever seen for ren'py. I especially love the AAAAAAAAAAA, it reminds me of the blustery Winnie the Pooh episode. (:

Re: FancyText: Effects for Slow Text Display

Posted: Wed Aug 05, 2020 2:41 pm
by Perihelion
yukinogatari wrote:
Wed Aug 05, 2020 1:47 am
I'll probably update it for the next stable release, but I'm a bit too busy to look into the nightlies.
No problem. Looks like the issue was that it needed to use the new shader system. I fixed it by replacing this:

Code: Select all

char.alpha = trans.alpha
with this:

Code: Select all

char.add_shader("renpy.alpha")
char.add_uniform("u_renpy_alpha", trans.alpha)
char.add_uniform("u_renpy_over", 1.0)
You could probably also use this to add any other shader you wanted, which would open up a cool range of new effects. :)

Re: FancyText: Effects for Slow Text Display

Posted: Thu Aug 06, 2020 1:13 am
by yukinogatari
Good to know! I don't know a thing about writing shaders but I'll definitely have to play around with it if Ren'Py's getting some kind of custom shader support.

Re: FancyText: Effects for Slow Text Display

Posted: Thu Nov 05, 2020 1:30 pm
by XT9K
I've implemented my own version of this if you'd like to check it out. viewtopic.php?f=51&t=60527 I even used your idea for help applying rotations to the renders, so really thankful for that!