0 votes
by (390 points)
Hello all!
Yes, it's me again! And i have another question. This time: Random events! :D

I already found out how to generate a random number:

Math.floor((Math.random() * 6) + 1);

My problem now is, that i can't set the random number as a variable and after that triggering the event via if/elseif. I know the code should look like this:

Math.floor((Math.random() * 6) + 1) = $randombumber;

<<if $randomnumber eq 1>>
You entered a building
<<elseif $randomnumber eq 2>>
You just do whatever you want

and so on. The important thing is: Calculating and triggering the event shouldn't be visible for the player of course. Depending on the output, the player should just see the event itself and not the mechanic behind that event. Does someone know how i can set the outcome of that random number generator as a variable?

Thanks in advance! :)

1 Answer

+2 votes
by (63.1k points)
edited by
 
Best answer

I already found out how to generate a random number:

Math.floor((Math.random() * 6) + 1);

SugarCube already includes a variety of random generation functions, including:

So you shouldn't need to fall back on JavaScript just for this.  And that's exactly what you're doing.

My problem now is, that i can't set the random number as a variable and after that triggering the event via if/elseif. I know the code should look like this:

Math.floor((Math.random() * 6) + 1) = $randombumber;

You've written this in a Frankenstein way here, attempting to use both TwineScript and JavaScript, attempting to place code directly into passage text (I assume), etc.  I'm going to split this answer into two parts, the first will cover what you're trying to do; the second will talk about how to utilize JavaScript.

1. Using randomness.

Here's what your code should look like as you've attempted to write it:

<<set $randomnumber to random(1, 6)>>\
<<if $randomnumber is 1>>\
You entered a building
<<elseif $randomnumber is 2>>\
You just do whatever you want
<<else>>\
It was higher than two.
<</if>>
$randomnumber

You'll notice that I used the random() function (it does the same thing, essentially, as the JavaScript code you found, so there's no need to reinvent the wheel).  You'll also notice that I changed your 'eq's to 'is's.  This is because 'eq' and 'is' are not the same, but as a general rule, you should use 'is' unless you're absolutely sure you need to use 'eq'.  This is because 'is' is far easier to predict; 'eq' will occasionally react strangely and produce very hard to find errors.

This code works, but we can do better.  For one, we don't actually need the variable; we can omit it entirely by using a <<switch>> macro instead:

<<nobr>>
    <<switch random(1, 6)>>
    <<case 1>>
        You enter a building.
    <<case 2>>
        Do whatever you want.
    <<case 3 4 5 6>>
        The number was higher than 2.
    <<default>>
        Blah.  Something went wrong if this is shown.
    <</switch>>
<</nobr>>

The switch is superior in this case because it saves us a variable.

There are many other ways to generate a random number, too.  Here are a few, for completeness:

<<set _roll to 0>>\
Roll a die!

@@#result;...@@

<<link 'Use the {{{random()}}} function!'>>
    <<set _roll to random(1, 6)>>
    <<replace '#result'>>_roll<</replace>>
<</link>>
<<link 'Use the {{{either()}}} function!'>>
    <<set _roll to either(1, 2, 3, 4, 5, 6)>>
    <<replace '#result'>>_roll<</replace>>
<</link>>
<<link 'Use the {{{<array>.random()}}} method!'>>
    <<set _roll to [1, 2, 3, 4, 5, 6].random()>>
    <<replace '#result'>>_roll<</replace>>
<</link>>
<<link 'Use the {{{<array>.shuffle()}}} method!'>>
    <<set _roll to [1, 2, 3, 4, 5, 6].shuffle(), _roll.length to 1>>
    <<replace '#result'>>_roll<</replace>>
<</link>>

You can load up the above code in a passage and try them out yourself.

2. Using JavaScript.

You can use JavaScript as a part of TwineScript, but not as a replacement for TwineScript.  The code you write in passages needs to be in TwineScript.  That means using macros.  You can insert JavaScript expressions into most macros that don't require discreet arguments (though that can be done, too, using back-ticks).  If you just need to run some pure JavaScript, then you use the <<run>> or <<script>> macros.  All other JavaScript you want to use goes in your story's JavaScript area (accessible from the bottom-left up-arrow menu in the editor).  Here's some examples of some uses of JavaScript:

/% 
    use jQuery and standard JavaScript array methods
    to find and print a list of all links on the page 
    we use <<timed>> here to let the DOM finish
    rendering before we manipulate it.
%/
<<timed 100ms>>
    <<set $var to jQuery('a').toArray()>>
    <<print $var.join('\n')>>
<</timed>>

/%
    We just want to run some pure JS code, so we 
    can use the <<run>> or <<script>> macros.
%/
<<run alert('hello world')>>
<<script>>
    (function (sv) {
        sv = JSON.stringify(sv);
        console.log(sv);
    }(State.variables));
<</script>>

You can use JavaScript fairly liberally throughout SugarCube, but all of the code your write in passages needs to either be HTML, markup, or macros.  In the macros themselves, you can use JavaScript to your heart's content.

So your code: 

Math.floor((Math.random() * 6) + 1) = $randombumber;

Should instead be written:

<<set $randomnumber to Math.floor((Math.random() * 6) + 1)>>

 Assuming that you wanted to write that code instead of using the random() function.

As a final note, the $ is the variable sigil in TwineScript, but is actually an alias for jQuery in JavaScript.  To access story variables via JavaScript, you'd use the State.variables object.  So your above code could also be written like this:

<<script>>
    State.variables.randomnumber = Math.floor((Math.random() * 6) + 1);
<</script>>

 

by (390 points)
Holy moly. Thanks for the answer and a proper explanation! I used the second one with the case and switch. I think it's much more easier and better to handle since i don't have to set variables for every random event.

Thank you really really much. This function will improve the game a lot! <3
by (190 points)
<<nobr>>
    <<switch random(1, 6)>>
    <<case 1>>
        You enter a building.
    <<case 2>>
        Do whatever you want.
    <<case 3 4 5 6>>
        The number was higher than 2.
    <<default>>
        Blah.  Something went wrong if this is shown.
    <</switch>>
<</nobr>>

I using this one but I using 1,9  and does it matter what says on default. strangely it went orange...not sure it means anything. does it need <<case 3 4 5 6>>  <- does it need that entry to make it not orange...orange I get means error.  I kind want random occurences be more than what it is normally given... What else am I missing I kind want go beyond 9 literally because idea of random you want go 9+ I still haven't figured out get combat part yet...

...