Howdy, Stranger!

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

[Twine 2.x] [Sugarcube 2.x] Is it possible to create a map of rooms dynamically using Javascript?

edited October 2015 in Help! with 2.0
Hi all,
My first post in here.

I've been poking around to see if I can create a few dozen rooms in Twine that don't have links, but just act as a pool for some Javascript to pull from.

For example if I want to create the Minotaur Labyrinth, and have 200 possible room descriptions but only want 100 in a given playthrough and want the labyrinth to be generated dynamically in javascript.

Can I jump into the first passage, have the link hook out to the javascript and get passed to where the javascript says the next room is, rather than creating hardlinks?

Twine 2.0.8, SugarCube 2.0.0-beta.8, Javascript
Platform: Windows


  • If you look at the SugarCube documentation for markup links you will see that you can use $variables to represent both the link text (Text) and/or the target passage title (Link).

    So if you use code to randomly determine the target passage titles to go to then you could use code like the following to display the links:
    <<set $linkA to "Some randomly chosen Passage Title">>
    <<set $linkB to "Some other randomly chosen Passage Title">>
    [[Go north|$linkA]]
    [[Go west|$linkB]]
    ... you could also include code to determine the associated Link Text to show for each of the above links.

    It is a good idea to procedurally generated the maze (the list of passages involved and exits/entrances of each of those passage) at the start of the story that way you can use path checking to make sure that the player is not going to be stuck travelling between a small number of passages. Another hard part when creating a procedurally generated maze is making sure that if the direction of traversal is reversed that the traveller ends up in the same room that they just left.

    eg. If the player goes from room A to B by going in a direction, then the direction to choose to travel back to room A should make sense, unless you like the text "You are in a maze of twisty little passages, all alike".
  • Cool :) I wasn't sure if it would treat it like that. Full steam ahead!
  • Also, rather than just have it create each room with random exits on the fly, the idea is to create room types with defined entrances and exits. So there will be blocks with entrances to the north and east only, of the wood and stone data set, etc.
    Just to keep things consistent.
    The idea of reversing traversal and having it remember a number of steps backward (not just layout) is a cool idea :) So you could mark a room with an inventory item and then create a stack that tracks your movements and pops rooms off to another stack to go backward.
    I could just store that marked room in a variable, but if there are any wandering creatures or timed events I might want turns consumed in the traversal back.
  • [quote="greyelf;12902"
    <<set $linkA to "Some randomly chosen Passage Title">>
    <<set $linkB to "Some other randomly chosen Passage Title">>

    So, in my test system I have Javascript populating an array with the target rooms, then using a random number generator to pick which room a teleporter pedestal will send me to :)
    But I've tried cheating the above sample by doing the following:
    <<set $link to $pedestalTarget>>
    Hoped that would work, but it did not. On the plus side my debug alerts that I added to my java show that the room selector is working.
    I guess my option now would be to just add paragraphs for all potential target rooms and put conditionals on which one gets displayed depending on the value of $pedestalTarget.

    Unless there's a sneakier way to do it with less code.

    For those curious I will record a video in a moment showing what I'm doing :)
  • edited October 2015
    A local variable within an essentially private scope cannot be accessed outside of that scope, and certainly not with the story variable syntax (i.e. $foo). To assign to the story variable $pedestalTarget from raw JavaScript, you have to go through the Sate.variables object.

    You also don't need/want to be generating your random integers that way. Use the built-in random() function.

    In your Story JavaScript, do the following instead:
    // Get a random integer in the range [0, 3] (i.e. 0, 1, 2, 3).
    var randomNumber = random(0, 3);
    // Assign a randomly chosen pedestal to $pedestalTarget.
    State.variables.pedestalTarget = pedestalList[randomNumber];

    Furthermore, unless you need the random number for something other than selecting a member from randomNumber, then you could simply use the built-in either() function or the
    <Array>.random() method. For example:
    // Assign a randomly chosen pedestal to $pedestalTarget.
    State.variables.pedestalTarget = either(pedestalList);
    // - OR -
    // Assign a randomly chosen pedestal to $pedestalTarget.
    State.variables.pedestalTarget = pedestalList.random();

    Also, you probably don't need to make a copy of $pedestalTarget within your passage, simply use it directly within the link. For example:
    Step on to the [[pedestal|$pedestalTarget]]

    EDIT: Alternatively, you could just assign the list of pedestals to a story variable and randomly choose right at the link. For example: (in Story JavaScript)
    State.variables.pedestalList = [ … ]; // list of pedestal rooms
    Then in your passages:
    Step on to the [[pedestal|either($pedestalList)]]
    /* - OR - */
    Step on to the [[pedestal|$pedestalList.random()]]
Sign In or Register to comment.