0 votes
by (210 points)

Hello there ! I think you may be happy to find a real question from a real humain being in what looks like a sea of bots.

So, without losing anymore time, let's get into it.

I'm creating an interactive story for a school project, and everything has gone good so far, yet I'm having a little issue with the code to create a discussion, because of my very limited knowledge.

Here's an example of the few tests I did :

CSS Style Sheet

.dempsey {
  position: fixed;
  top: 0em;
  left: 10em;
}
.nikolai {
  position: fixed;
  top: 0em;
  right: 10em;

}

Twine's passage

(set: $timer1 to 0)
(live: 1s)[(set: $timer1 to it + 1)]



{<div class="dempsey">
(live: 1s)[
(if: $timer1 is 1)[Hi Nikolai, how are you ?]
(if: $timer1 is 2)[Hi Nikolai, how are you ?]
(if: $timer1 is 3)[Hi Nikolai, how are you ?]
(if: $timer1 is 4)[Hi Nikolai, how are you ?]]</div>
<div class="nikolai">(live: 1s)[(if: $timer1 is 5)[Good since last time, and you ?]
(if: $timer1 is 6)[Good since last time, and you ?]
(if: $timer1 is 7)[Good since last time, and you ?]
(if: $timer1 is 8)[Good since last time, and you ?]]</div>}

The goal is to create a discussion between two characters (or more whatever), with each line having it's own position (that's not a problem), but each line need to disappears when a new one appears (that's the problem) so it looks more like a real conversation.
I tried to do it with a countdown system but I can only do it for two sentences per character, since it only works with (if:) and (else-if:).

The method I did above works pretty well, but it's a very barbarian way to do it, since it's very rustic and archaic, though it's still doing is job.

So I would like if you guys and girls could help me improving my coding and make this works better !!

Thank you for reading !!
And have a good day (english is not my first language btw) !

1 Answer

+1 vote
by (159k points)
selected by
 
Best answer

First a little background:

1. The timer events created by the (live:) macro interfer with the end-user's ability to interact with the page so it is generally recommend to have as few of these timers active at any one time, preferably only one. In your example you have two such (live:) macro timers with the same delay period active at the same time, which means you could easily combine the contents of the associated hooks of those two (live:) macros together.

2. Using a named hook combined with the (replace:) macro is an ideal way to update a known area of the page.

3. Once you have finished with your (live:) timer you should use a (stop:) macro to end it as soon as possible, unless the final iteration of that timer results in a Passage Transition (movement to another passage)

The following solution uses two named hooks (named dempsey and nikolai) to act as targets of the (replace:) macros being used to update the two people's dialogue, it uses a single (live:) plus a counter variable combined with an (if:) / (else-if) structure to control both the timing and what is shown, and it uses a (stop:) macro to stop the timer when the last line of the discussion is to be spoken.

{
	|dempsey>[]
	|nikolai>[]
}
{
(set: $timer1 to 0)
(live: 1s)[
	(set: $timer1 to it + 1)

	(if: $timer1 is 1)[
		(replace: ?dempsey)[Hi Nikolai, how are you ?]
	]
	(else-if: $timer1 is 5)[
		(replace: ?dempsey)[]
		(replace: ?nikolai)[Good since last time, and you ?]

	]
	(else-if: $timer1 is 9)[
		<!-- This is the last line of the discussion, stop the timer. -->
		(stop:)
		(replace: ?nikolai)[]
		(replace: ?dempsey)[last line of the discussion]
	]
]
}

Because the above example is using named hooks instead of ID'ed div elements to contain the individuals dialogue the CSS selectors within your project's Story Stylesheet are will need to be changed to target the named hooks instead.

tw-hook[name="dempsey"] {
	position: fixed;
	top: 0em;
	left: 10em;
}
tw-hook[name="nikolai"] {
	position: fixed;
	top: 0em;
	right: 10em;
}


note: Both your and my implementations currently have each line of the discussion spoken every 4 seconds after the first line has been spoken, this means that currently 3 iterations of the timer out of every 4 is wasted doing nothing but updating a counter variable.

If you are planning on continuing this pattern of the characters only speaking every 4 seconds then I suggest changing the main (live:) macro so that it's delay is 4s instead of 1s, you will also need to adjust the conditions of the (if:)/(else-if:) macros to compensate. 

The replacement timer related code would look like the following, you will notice it uses two (live;) timers to control the timing difference between displaying the first line and the others, and that only one timer is active at any time.

{
(set: $timer1 to 0)
(live: 1s)[
	(set: $timer1 to it + 1)
	(replace: ?dempsey)[Hi Nikolai, how are you ?]
	(stop:)

	(live: 4s)[
		(set: $timer1 to it + 1)

		(if: $timer1 is 2)[
			(replace: ?dempsey)[]
			(replace: ?nikolai)[Good since last time, and you ?]
		]
		(else-if: $timer1 is 3)[
			<!-- This is the last line of the discussion, stop the timer. -->
			(stop:)
			(replace: ?nikolai)[]
			(replace: ?dempsey)[last line of the discussion]
		]
	]
]
}

 

by (210 points)
Thank you so much for that very constructive response !!
Very clear, nothing more to say, thanks sir !
...