Howdy, Stranger!

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

[Twine 2.1.1] [SugarCube 2.14] Passages and interactable objects.

Hi there,

I'm looking for best practices and solutions to the following problem:

Let's say I have a passage, in which I want a treasure chest and a person. When the player enters the room, I want to have options poping up that enable me to interact with these two objects. These objects are defined in JavaScript, where I declare the type, count, name and possible actions that can be carried out by the player on a given object.

Now, of course you could put in IFs into each passage, but thats too tedious of a work.
What I want is some way to identify objects in the room and print the actions that can be taken on them by default.

The printing part has already been figured out, now I'm trying to come up with an idea that allows me to track these objects when traversing.

Here's the idea that I have and going to try out:

Add the object names as Tags to the passage in question and when always when entering the passage (by defining a task in JavaScript, once a room has been created) compare the Tags that are assigned to the current room and match them with an array of interactable objects. If the object is on the list then the passage will show the actions that can be taken.

Now, this solution requires me to specify the objects that I want to interact with on a list (or separate lists) and do the comparison against the tags each time I enter a passage.

My question is: is there a better way of doing this? Can the Tags that are assigned to the passage can be used to implement something like this? Would the names of the objects and the tags collide with other names that SugarCube uses and if so which ones?

I know that 'widget' is already taken, but i guess 'treasure chest' and 'pirate' aren't :)


  • As ever, the Emperor documentation provides, see the special tags documentation. In summary, when compiled by Twine 2, SugarCube recognizes the following tags as special: bookmark, nobr, and widget.

    As to your sample tags. Tags are delimited by space, so treasure chest is two tags, not a single one. You'll have to come up with some kind of non-space-separated compound format if you want tags that contain multiple words—e.g. treasurechest, treasure-chest, treasure_chest, treasure.chest, etc.

    Beyond that, there's no insurmountable reason I can think of off the top of my head why you couldn't use tags for this. The other obvious solution would be to simply list the items somewhere within the passage, probably at the top, by defining an array of them, probably in a temporary variable. Either way, it's difficult to say more than that without knowing how you're planning on showing the actions.

    One possible issue could be how you're planning on tracking the status of these items once the player has interacted with them. For example, if one is an actual item that the player can pick up, you'll probably need to ensure that the item is no longer available within the passage. You'd have a similar issue with NPCs who can be removed from the passage in some way—e.g. killed, recruited, leaves for some reason, etc.
  • edited March 2017
    Right, i did not think of ways to dispose of these objects. You are right.

    About your idea on listing the objects on the top of the passage? How would this work? How do you access these or make checks for them to see if they are inside the passage?

  • One way I thought about tracking these objects is maybe storing the passage name in their data structure and once the current passage becomes the same as the one defined inside the object, I would print the actions that are corresponding to that given object.
    For this I would need to setup a task that does the check before or after the passage has been displayed.

    Is this how you would solve this problem or is there a way to read out the defined story variables from the room that is being visited?
  • To track their state you're eventually going to need to store them in story variables. When exactly you start doing that is up to you.

    You could initialize an object at startup which contains entries—likely some kind of object defining actions—for each passage which you want to have actions. For example:
    <<set $rooms to {
    	"John's House - Basement" : { /* action object */ },
    	"John's House - Garage"   : { /* action object */ }
    During play, you'd check to see if the current passage had an entry and, if so, do something with it:
    → JavaScript example
    if (State.variables.rooms.hasOwnProperty(passage())) {
    	/* This passage has an entry in $rooms, so process the entry. */
    → TwineScript example
    <<if $rooms.hasOwnProperty(passage())>>
    	/* This passage has an entry in $rooms, so process the entry. */
    Pros: Master list of all room actions defined from the start.
    Cons: All room actions contained within $rooms, thus the story history, right from the start, even ones the player may never see.

    Alternatively, you could do the setup somewhere within each such passage—probably at the top—though that would necessitate doing your processing at some point after basic rendering. For example:
    → JavaScript example
    if (!State.variables.rooms.hasOwnProperty(passage())) {
    	State.variables.rooms[passage()] = { /* action object */ };
    → TwineScript example
    <<if not $rooms.hasOwnProperty(passage())>>
    	<<set $rooms[passage()] to { /* action object */ }>>
    Pros: Room actions only added to $rooms, thus the story history, as needed.
    Cons: Room action definitions spread throughout the passages—i.e. no master list.

  • I like the one with the master list. Definitely something that I was looking for.
    Thanks a lot!
Sign In or Register to comment.