Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

(live: $time + 1 + "s") problem (add number and string)

I want to make a timed conversation, in which every phrase comes a second after the last. I tried putting (live:)[] inside (live:)[], but it breaks my entire code (with some ifs and elses).

I thought: there's a way to do it. Let's do a
(set: $time to 0)
Then, at the start of every phrase, let's put the code to use.
(live: $time + 1)[Phrase one]
(live: $time + 1)[Phrase two]
(live: $time + 1)[Phrase three]
(live: $time + 1)[Phrase four]
ISSUE: (live:) needs the letter s for seconds (as well as ms to milliseconds). I tried:
(live: $time + 1 + "s")[Didn't work, clearly]
(live: (print: "$time + 1") + (print: "s"))[Didn't as well]
I ask for two things:
FIRST: Is there a way to do the math (turning the 1 to string isn't good, as I need it to sum to the latest $time) AND "sum it" with the "s" character?
SECOND: Is it too hard to implement (live:) number default as seconds (so we don't need to put the letter, just when specified)

Thank you VERY much. This forum has been awesome.

Comments

  • You can chain the macros, but that would get ugly fast.  You'd probably be better off appending/replacing/whatever to a named hook and simply staggering your delays.

    You could use something like this for a timed append:

    {
    [Phrase one]<timed-append|
    (live: 1s)[(stop:)(append: ?timed-append)[, Phrase two]]
    (live: 2s)[(stop:)(append: ?timed-append)[, Phrase three]]
    (live: 3s)[(stop:)(append: ?timed-append)[, Phrase four]]
    (live: 4s)[(stop:)(append: ?timed-append)[, Phrase five]]
    }
    You could use something like this for a timed replace:

    {
    [Phrase one]<timed-replace|
    (live: 1s)[(stop:)(replace: ?timed-replace)[Phrase two]]
    (live: 2s)[(stop:)(replace: ?timed-replace)[Phrase three]]
    (live: 3s)[(stop:)(replace: ?timed-replace)[Phrase four]]
    (live: 4s)[(stop:)(replace: ?timed-replace)[Phrase five]]
    }
  • Additionally, you seem to be operating under a misconception.  The time values that the (live:) macro takes are not strings and you cannot treat them that way.  They are numbers, specifically numeric literals which include a temporal unit (e.g. 1s represents 1 second or 1000 milliseconds).

    AFAIK, they decompose into the appropriate number of milliseconds and that's also what (live:) actually takes, time in milliseconds (though that's an implementation detail, which you shouldn't worry about).

    For example, the append example I gave above could also be done as:

    {
    [Phrase one]<timed-append|
    (set: $delay to 1s)
    (live: $delay * 1)[(stop:)(append: ?timed-append)[, Phrase two]]
    (live: $delay * 2)[(stop:)(append: ?timed-append)[, Phrase three]]
    (live: $delay * 3)[(stop:)(append: ?timed-append)[, Phrase four]]
    (live: $delay * 4)[(stop:)(append: ?timed-append)[, Phrase five]]
    }
    Though, you don't need a $variable for something simple like that (which is why my original example didn't use one).
  • TheMadExile wrote:

    You can chain the macros, but that would get ugly fast.  You'd probably be better off appending/replacing/whatever to a named hook and simply staggering your delays.


    I'm not a native english speaker, so help me with this: append is like adding? Eg: Phase One will become Phase One, Phase Two?

    TheMadExile wrote:

    You could use something like this for a timed append:

    {
    [Phrase one]<timed-append|
    (live: 1s)[(stop:)(append: ?timed-append)[, Phrase two]]
    (live: 2s)[(stop:)(append: ?timed-append)[, Phrase three]]
    (live: 3s)[(stop:)(append: ?timed-append)[, Phrase four]]
    (live: 4s)[(stop:)(append: ?timed-append)[, Phrase five]]
    }
    You could use something like this for a timed replace:

    {
    [Phrase one]<timed-replace|
    (live: 1s)[(stop:)(replace: ?timed-replace)[Phrase two]]
    (live: 2s)[(stop:)(replace: ?timed-replace)[Phrase three]]
    (live: 3s)[(stop:)(replace: ?timed-replace)[Phrase four]]
    (live: 4s)[(stop:)(replace: ?timed-replace)[Phrase five]]
    }


    That's not what I want. It's a dialogue that appears as seconds passes, so replacing isn't my thing. There's another problem I'll tell you just below:


    TheMadExile wrote:

    Additionally, you seem to be operating under a misconception.  The time values that the (live:) macro takes are not strings and you cannot treat them that way.  They are numbers, specifically numeric literals which include a temporal unit (e.g. 1s represents 1 second or 1000 milliseconds).

    I didn't say they were strings. That's exactly my problem, as twine doesn't add 1 (as 1 second) and s (the letter you need to put next to the number in (live:) macro).


    TheMadExile wrote:

    AFAIK, they decompose into the appropriate number of milliseconds and that's also what (live:) actually takes, time in milliseconds (though that's an implementation detail, which you shouldn't worry about).

    For example, the append example I gave above could also be done as:

    {
    [Phrase one]<timed-append|
    (set: $delay to 1s)
    (live: $delay * 1)[(stop:)(append: ?timed-append)[, Phrase two]]
    (live: $delay * 2)[(stop:)(append: ?timed-append)[, Phrase three]]
    (live: $delay * 3)[(stop:)(append: ?timed-append)[, Phrase four]]
    (live: $delay * 4)[(stop:)(append: ?timed-append)[, Phrase five]]
    }
    Though, you don't need a $variable for something simple like that (which is why my original example didn't use one).


    But I have a bunch of lines of dialogue. I want something like: this dialogue will come, then this one will, then this one, then this one, one after another for, like, thirty lines.
    Is that possible?
    If not, I'll do the (live: 1s) through (live:30s), but it would be awesome if I could do (live: $second + 1) thirty times.
  • Append will add on to the end of text stored in the "timed-append" hook.

    So the "timed-append" hook has the text "Phrase one"

    When you do
    (append: ?timed-append)[, Phrase two]]
    "timed-append" will now say "Phrase one, Phrase two"

    I have a simple way of doing a timed conversation that uses an array and (move:) that worked when I wrote it, but doesn't work today. Here's a variant of my example that still works. This doesn't do exactly what you want, but it might be useful.
    (hook:"story")[]

    (set:$slowtext to "Hello.
    How are you doing?

    This is some dialogue.
    It will appear slowly.")
    {
    (set:$x to 1)
    (live:100ms)[
    (set:$c to (substring:$slowtext,$x,$x))
    (if:$c)[
    (append:?story)[$c]
    (set:$x to $x+1)
    ]
    ]
    }
    The array example (when it worked) basically worked the same way, but used "(move: $slowtext&#039;s 1st into $x)" instead of "(set: $c to (substring:$slowtext, $x, $x))"

    NOTE: I'm not sure it's a good idea to split a string variable over multiple lines the way I do in that example, but I don't know of a different way to get line breaks in there.


    You can also get an interesting effect if you change "(append:?story)[$c]" to "(append:?story)[(t8n:&quot;dissolve&quot;)[$c]]"
  • oakandsage wrote:

    Append will add on to the end of text stored in the "timed-append" hook.

    So the "timed-append" hook has the text "Phrase one"

    When you do
    (append: ?timed-append)[, Phrase two]]
    "timed-append" will now say "Phrase one, Phrase two"

    I have a simple way of doing a timed conversation that uses an array and (move:) that worked when I wrote it, but doesn't work today. Here's a variant of my example that still works. This doesn't do exactly what you want, but it might be useful.

    (hook:"story")[]

    (set:$slowtext to "Hello.
    How are you doing?

    This is some dialogue.
    It will appear slowly.")
    {
    (set:$x to 1)
    (live:100ms)[
    (set:$c to (substring:$slowtext,$x,$x))
    (if:$c)[
    (append:?story)[$c]
    (set:$x to $x+1)
    ]
    ]
    }
    The array example (when it worked) basically worked the same way, but used "(move: $slowtext&#039;s 1st into $x)" instead of "(set: $c to (substring:$slowtext, $x, $x))"

    NOTE: I'm not sure it's a good idea to split a string variable over multiple lines the way I do in that example, but I don't know of a different way to get line breaks in there.


    You can also get an interesting effect if you change "(append:?story)[$c]" to "(append:?story)[(t8n:&quot;dissolve&quot;)[$c]]"


    I like this but I can't really understand it. Would I be asking too much for a more detailed explanation? For instance, what the substring macro does or what these letters $x or $c do?
  • Not at all, I was very lazy about my variable naming and some of my style. Some coding conventions from my day job crept into my code, and they're not at all good practice in other contexts.

    $c is a character. Actually, it's really a string that we're going to make sure is only 1 character long. My day job again, sorry. $x is a terribly named iterator. It contains the index of the next character of $slowtext that we want to print.

    Every 100ms, we want to print the next character of $slowtext. Here's how we accomplish that:
    (set:$x to 1)
    Strings (and everything else) in Harlowe's syntax is 1-based, so the first character of the $slowtext string is character 1. This just initializes $x so that when we start printing characters from the string, we'll start at the beginning of the string.
    (live:100ms)[ ... ]
    (live:) - This, as I believe you already know, will do everything between the [ ] every 100ms.
    (set:$c to (substring:$slowtext,$x,$x))
    (substring:$slowtext,$1,$5) will get you the 1st to the 5th character of $slowtext. In this case, we only want one character (the next one to print), so we get characters $x to $x and assign them to the variable $c.
    (if:$c)[ ... ]
    should probably be written as (if: $c is not &quot;&quot;), or (unless: $c is &quot;&quot;).
    $c
    will be empty if the substring function couldn't get any text because we started after the end of $slowtext. This makes sure that we don't just keep printing empty strings or blow up the browser after $x becomes a huge number.
    (append:?story)[$c]
    (append:) is what actually adds $c onto the end of the text in the story hook.
    (set:$x to $x+1)
    increments $x so that we will print the next character the next time the code in (live:) is called. (Otherwise we would just print the same character again)

    Hope that clarifies things a bit!
  • oakandsage wrote:

    NOTE: I'm not sure it's a good idea to split a string variable over multiple lines the way I do in that example, but I don't know of a different way to get line breaks in there.


    You can use \n to insert a newline into a string.

    (set: $slowtext to "Hello.\nHow are you doing?\n\nThis is some dialogue.\nIt will appear slowly.")

    (print: $slowtext)
  • oakandsage wrote:

    Not at all, I was very lazy about my variable naming and some of my style. Some coding conventions from my day job crept into my code, and they're not at all good practice in other contexts.

    $c is a character. Actually, it's really a string that we're going to make sure is only 1 character long. My day job again, sorry. $x is a terribly named iterator. It contains the index of the next character of $slowtext that we want to print.

    Every 100ms, we want to print the next character of $slowtext. Here's how we accomplish that:

    (set:$x to 1)
    Strings (and everything else) in Harlowe's syntax is 1-based, so the first character of the $slowtext string is character 1. This just initializes $x so that when we start printing characters from the string, we'll start at the beginning of the string.
    (live:100ms)[ ... ]
    (live:) - This, as I believe you already know, will do everything between the [ ] every 100ms.
    (set:$c to (substring:$slowtext,$x,$x))
    (substring:$slowtext,$1,$5) will get you the 1st to the 5th character of $slowtext. In this case, we only want one character (the next one to print), so we get characters $x to $x and assign them to the variable $c.
    (if:$c)[ ... ]
    should probably be written as (if: $c is not &quot;&quot;), or (unless: $c is &quot;&quot;).
    $c
    will be empty if the substring function couldn't get any text because we started after the end of $slowtext. This makes sure that we don't just keep printing empty strings or blow up the browser after $x becomes a huge number.
    (append:?story)[$c]
    (append:) is what actually adds $c onto the end of the text in the story hook.
    (set:$x to $x+1)
    increments $x so that we will print the next character the next time the code in (live:) is called. (Otherwise we would just print the same character again)

    Hope that clarifies things a bit!


    I like this. I'll try this on, but be sure it's just a workaround, as what I keep not being able to do what I wanted, that is, print phrase by phrase.
  • greyelf wrote:

    You can use \n to insert a newline into a string.

    Huh. Yeah, that works. Since HTML seems to be escaped when printing strings, I was afraid backslashes would also be. (In retrospect, I wasn't thinking this through. It looks to me like when I put \n into a string in the editor, the string ends up containing a newline character. As it should. '<' and '>' are most likely stored as '<' and '>' and escaped during printing)
  • angelodias wrote:
    (live: $time + 1)[Phrase one]
    (live: $time + 1)[Phrase two]
    (live: $time + 1)[Phrase three]
    (live: $time + 1)[Phrase four]

    If you just want each phrase to appear as-is, you should try something like this:

    (live: 1s)[
    (if: time > 1s)[Phrase one]
    (if: time > 2s)[Phrase two]
    (if: time > 3s)[Phrase three]
    ]
    Note that time is not the same as $time - it has no $ sigil because the program controls it, not the author. The meaning of $ is simple: the variable is under the author's control, not the program's.

    The 1s given to (live:) refers not to the time in which the phrases appear, but the frequency in which the live hook's contents is re-run. (live: 1s) means "rerun this hook's code every 1 second".
  • L wrote:

    If you just want each phrase to appear as-is, you should try something like this:

    (live: 1s)[
    (if: time > 1s)[Phrase one]
    (if: time > 2s)[Phrase two]
    (if: time > 3s)[Phrase three]
    ]


    @angelodias: Remember to use a (stop:) macro after you have shown your last Phase because the above will keep rendering every second until you do something that stops it

    (live: 1s)[
    (if: time > 1s)[Phrase one]
    (if: time > 2s)[Phrase two]
    (if: time > 3s)[Phrase three]
    (if: time > 4s)[(stop:)]
    ]

  • L wrote:

    angelodias wrote:
    (live: $time + 1)[Phrase one]
    (live: $time + 1)[Phrase two]
    (live: $time + 1)[Phrase three]
    (live: $time + 1)[Phrase four]

    If you just want each phrase to appear as-is, you should try something like this:

    (live: 1s)[
    (if: time > 1s)[Phrase one]
    (if: time > 2s)[Phrase two]
    (if: time > 3s)[Phrase three]
    ]
    Note that time is not the same as $time - it has no $ sigil because the program controls it, not the author. The meaning of $ is simple: the variable is under the author's control, not the program's.

    The 1s given to (live:) refers not to the time in which the phrases appear, but the frequency in which the live hook's contents is re-run. (live: 1s) means "rerun this hook's code every 1 second".


    I'm very happy with the answer but it still doesn't solve my issue.
    I don't want to insert 1s, 2s, 3s, ... 30s, 31s, 32s etc. I want to insert a code that increases the value each second and play with each new value. Then, I'll have to write only one line and repeat it.
    like this:
    Set my time value to 0.
    Time value + 1 = line 1, time value 1.
    Time value + 1 = line 2, time value 2.
    Time value + 1 = line 3, time value 3.
    Time value + 1 = line 4, time value 4.
    (stop:)
  • I think what bothers me a little about your response is that it doesn't show you've tried to find a solution on your own.

    Here you go:
    (set: $t to 1)

    [Phrase $t]<start|

    (live: 1s)[
    (if: time > $ts and time < 5s)[(set: $t to it + 1)(append: ?start)[
    Phrase $t]]
    ]
  • st33d wrote:

    I think what bothers me a little about your response is that it doesn't show you've tried to find a solution on your own.

    Here you go:
    (set: $t to 1)

    [Phrase $t]<start|

    (live: 1s)[
    (if: time > $ts and time < 5s)[(set: $t to it + 1)(append: ?start)[
    Phrase $t]]
    ]


    Thank you VERY much! I'll try this right away!

    And, differently from what you think, I always try a lot before asking something. I'm not a programmer and my true problem (which I'm trying to overcome) is thinking like a programmer. Twine is being a nice experience of try-and-error. Sorry if I "sounded wrong"
Sign In or Register to comment.