Is there a more elegant solution than mine? Surely. But what?

I’m using Twine 2.3.5, with Sugarcube 2.30.0.

I’m running several macros together to create a conversation between two characters in a passage. One character speech box appears, says something, and then disappears to be replaced by the next character’s speech box and so on.

I’m using Chapel’s speech box macro to create the speech box, Matt Boldt’s typed.js macro so characters’ speech text types itself out, and Chapel’s fading macro to fade between characters’ speech boxes at timed intervals. I.e. fade out character A’s speech box at this time, fade in character B’s speech box 100ms later.

The problem is it’s really clunky and unreliable. Sometimes speech boxes overlap, sometimes there are large gaps between them, and sometimes they just about work - all without me changing the timings.

I’m also aware that playing with the timings to get them almost right has taken me ages and this is only one passage of many.

Here is some of my passage code:

<</fadeout>><</fadein>><<fadein 100ms 10s>><<fadeout 100ms 29s>><<father>>@@.typed;"Father character saying stuff, blah blah blah".<</father>><</fadeout>><</fadein>><<fadein 100ms 29100ms>><<fadeout 100ms 32s>><<you>>@@.typed;"You character saying some other stuff, blah blah blah"<</you>><</fadeout>><</fadein>>

I feel there must be a more elegant solution where one event finishing triggers the start of the next, but I can’t work it out. Can you help please? :slight_smile: :space_invader: :smiley:

Are those timing taking into account the different people read at different speeds?

Is there a reason you’re not using the <<type>> macro that comes with v2.32.0 of SugarCube?
(that was later update in v2.32.1 & v2.32.2 of SugarCube)

The SugarCube <<type>> macro includes a number of events that might help you with the timing of when exactly to do the fade-out effect. Especially if you decide to allow the Reader to influence the speed of the ‘typing’ and possibly the period of time the completed text stays visible.

Thanks for replying @Greyelf

No reason other than typed.js was the first macro for typing that I found. I’ll remember to check Twine documentation first next time. The type macro looks prefect for what I want, thank you.

It’s not, no. I’d love to allow the Reader to influence the speed of typing and how long text stays visible, but wouldn’t have a clue how. Could you point me in the right direction please?

When placing this code in my passage:

<<type 40ms start 10s>>
	"Something, something, something".
<</type>>

I get this error:

Error: macro << /type >> does not exist

You first post says you are using Sugarcube 2.30.0. The Type macro needs 2.32.0 or newer. Your code works perfectly fine for me on 2.33.2.

For the configurable speed, the easiest way is to set up a setting for it. You can play with the Settings API to create several options that you could swap out for variables.

For example, they could configure scrolling speed in milliseconds or whatever speed you want. Then you should be able to reference Type to use that variable.

Setting example (this goes into Story Javascript):

Setting.addHeader("Set text scroll speed in ms");
Setting.addRange("speed", {
	label    : "Scroll speed",
	min      : 10,
	max      : 50,
	step     : 5,
	default  : 20
	});

This sets up a slider bar that:

  1. starts at 20
  2. minimum value of 10
  3. max of 50; and
  4. increments by 5 each step

Then reference it in your type command in your passage:

<<type settings.speed start 10s>>
	"Something, something, something".
<</type>>

Settings are not referenced with a ‘$’. The above is missing the ‘ms’ after the speed, that’ll have to be concatenated on, but not sure how that would work.

EDIT: Adding a setting will create a Settings button in the uibar. If you have modified or are using another uibar (or hidden it) you won’t see it.

Thanks @cooldevo. I installed Sugarcube 2.33.2. but now when I run it, all my passages have this storyInit graphic covering them. Do you know why that might be?


I have a storyInit passage.

If you are running it via ‘Test’ button then you’ll see that. It’s “showing” the StoryInit initializing parameters without actually showing them. In the bug in the bottom corner of the screen you can see them all and watch them there as they change throughout the story. If you skip below that box, everything underneath of that is the actual passage.

If you use ‘Play’ button then you won’t see that.

I normally troubleshoot with ‘Test’ as I can watch variables. If I want to test what a user sees, then I use ‘Play’. If you have external links, to images or music, you need to publish then run to see everything.

I just wanted to pop in and mention that slow text is very much disliked by a large group of readers.

Like Christopher Huang’s review of Lux:

“the dialogue sequences are set on a timed delivery, and if you’ve been following my reviews, you’ll know how much I hate that sort of thing. It’s not too objectionable here, but I could really do without it.”

or Notagoth’s review of the Mysterious Stories of Caroline:

“As is often the case with timed text in Twine (I’ve done this myself) the transitions are overly slow in places, sometimes to the point of annoyance.”

or Robin Johnson’s review of Mrs Lojka:

“Unfortunately I accidentally closed my browser somewhere near the end of the game, and the unskippable slow text made it too much trouble to catch up again”

or Jack Welch’s review of Pensee Profondes:

“Here, the slow text display really grated on my nerves — I just wanted to get to the first choice, but I didn’t have the patience to plod through back to that point, and with seven more games in the comp …”

A lot of times it’s better to just use the visual flow to break up the dialogue instead of forcing it through timing.

1 Like

If the effect is needed by the author for their story (hopefully judiciously), allowing the speed to be configurable is a possible compromise.

If it’s supposed to emulate Hangouts/iMessage/etc., then perhaps that usage could be replicated. I’m not sure if it has been done yet by someone else, but when a user is replying, instead of showing the text message typing across; use some some link replaces and CSS you could probably replicate that functionality. So you see “…replying” or “user is typing” or something like that, which after a couple of seconds is replaced with the actual message.

Thanks @cooldevo, that’s a relief! I’ve actually hidden the UI bar but could consider bringing it back if there’s no other way to give the reader similar control.

And thanks for the heads up @mathbrush, there is a conceptual justification for using the effect but even so I don’t want to frustrate the reader.

What if I provided them with a way to skip to the end of each piece of dialogue, would that work as a compromise, do you think? That way they could always just click through if they’re bored or have read it before.

1 Like

I think everyone I’ve seen who dislikes slow text is happy when it’s click-throughable. That’s a really good idea!

Since you are on the newest SugarCube, there is a skipkey that you can see the syntax for in the TYPE Macro.

You can keep the uibar hidden if you want. You can manually cause it to run (say on the first passage) by putting this in the passage:

<<run UI.settings()>>

You could also manually call it from a link in a header/footer (or anywhere) like this, which will leave a clickable link that will open the Settings.

<<link Settings>>
    <<run UI.settings()>>
<</link>>

Thanks so much both of you. I find this IF community so helpful and welcoming to FNGs/rookies/noobs, like me.

I have one final question: I’ve spent all afternoon trying to figure out how to use type events, particularly :typingstop, to make the end of one piece of dialogue trigger the start of the next but can’t.

I’m confused because the syntax asks for javascript code:

$(document).on(':typingstop', function (ev) {
	/* JavaScript code */
});

I don’t think my dialogue code is js and it didn’t work when I tried putting it in there anyway. I want the end of this:

<<father>><<type 40ms start 10s skipkey "Control">>"Some dialogue".<</type>><</father>>

To trigger the beginning of this:

<<you>><<type 40ms start 10s skipkey "Control">>"The next bit of dialogue".<</type>><</you>>

Added a small fix to the setting bar to include a header in my above post, otherwise no one will know what it’s referring to.

I believe the ‘events’ are handled in the Story Javscript. You can call also JavaScript within passages with macros like <<script>> or a couple others.

I’m barely a JS beginner, so I’ll have to defer to someone else on that.

By default you would need to use JavaScript to handle to the type related events, placing that code either: within your project’s Story JavaScript area; or within the Passage using a <<script>> macro like suggested by @cooldevo.

However if you prefer to use TwineScript within your Passage to handle the type related events then you could use one of the Event Macros that are included in Chapel’s Custom Macro Collection, possibly the <<one>> macro.

Chapel’s Event Macro seems a good fit for me. After studying the documentation, here is what i’ve written:

<<one 'keydown'>>
<<which Enter>>
    <<trigger 'click' '<<you>><<type 40ms start 500ms skipkey "Control">>"My messenger?"<</type>><</you>>'>>
<</one>>

The idea was to make it so that when the user presses enter, this piece of character dialogue types itself out - with the option of skipping to the end. Suffice to say, nothing happens. Have I misunderstood the syntax?

There are some issues with your last example:

  1. the Event macros are what is known as ‘silent’, which means they don’t directly display any output generated within their associated body content. You can however use DOM Manipulation macros like <<append>> within them to ‘append’ content to a known area of the page.
  2. the <<which>> macro’s keycode argument needs to be an integer. eg. Enter is 13
  3. The 2nd argument of the <<trigger>> macro is mean to be a CSS Selector, not a String contain content to output.

Based on the above information your code example be altered to something like…

@@#output;@@

<<one 'keydown'>>
<<which 13>>
    <<append '#output'>><<you>><<type 40ms start 500ms skipkey "Control">>"My messenger?"<</type>><</you>><</append>>
<</one>>

…which uses Custom Style markup to define an area with an identifier of #output into which the <<append>> macro is placing its content when the Enter key is pressed.