Chapbook Modal Text Window strategy?

Twine Version: 2.3.12
Story Format: Chapbook

I’m trying to learn Chapbook but the one thing so far I really miss is the popup windows that could be summoned in AXMA by preceding a link with an asterisk like [[*Inventory|invpassage]].

I know that the normal thing is to link to a new passage and use a back link, but this feels clunkier and I tried to make an inventory link that resides in the header, but I get stuck if the player clicks a header link twice because the {back} link in the inventory passage forgets where it needs to go.

I know Sugarcube does it, yeah, yeah. I should learn JavaScript, yeah I know…

Is there any way to replicate this feature in Chapbook - especially for use in layered menu passages - or do I just need to suppress this need to use them and figure out how to do menu-type passages another way?

I was just searching for a solution to my problem and this is my question exactly. Has anyone come up with a way to put a running inventory/status link in a header/footer? The best option I can think of is defining the header in every single passage in the story, but I’m hoping there’s a tidier way.

A possible short term work around is to use the [if] modifier combined with the passage.name lookup variable to conditionally suppress a menu item that relates to the currently shown Passage.

The following TWEE Notation based example shows how to use the {embed passage:} insert to source header content from a child Passage. and the [append] modifier to suppress the line-break between each menu item.

:: Start
config.header.center: "{embed passage: 'Menu'}"
--
This is the {passage.name} passage.

:: Menu
[if passage.name !== 'Inventory']
[[Inventory]]
[append]
[if passage.name !== 'Help']
[[Help]]

:: Inventory
This is the {passage.name} passage.

:: Help
This is the {passage.name} passage.

note: whether or not the above is a “good” solution is an entirely different question. :slight_smile:

2 Likes

Hey, it works! I didn’t think to try embedding a passage in the header line, but that’s exactly what I needed. Thanks so much, I really appreciate the help!

Don’t feel bad. I didn’t know that any of my solution was possible, until I tried answering your question… :slight_smile:

2 Likes

Another (but a little messy) solution, perhaps.

  1. Link to inventory

config.header.center :“{link to: Inventory, label: ‘Inventory’}”.

To store in a var in each passage that is not a menu/inventory page, the current passage name.

last_ingame_passage: passage.name.

The first page of the menu/inventory may have a link with that var as an argument:

{link to: last_ingame_passage, label: ‘Continue’}

2 Likes

In harlowe the (display:) macro also allows you to embed a passage in another passage, which is what I did to show inventory, health, held items etc

My solution was a bad one. If you start the inventory/menu from a passage that has an “strength: strength+1” in its var section, x will be incremented again when you return from the menu. Even if you, intead, use “ghost passages” (my name for passages that only change variables values an have embeded inside them the real passages) then passage.name will refer to the host passage’s name (not the guest, embeded one) so x will be incremented again anyway.

My new, much better, and working (i think) solution.

  1. Add a “menu” tag to each MENU/INVENTORY passage.

  2. Add a link to inventory/menu at header.
    Place this code in vars section: config.header.center :"{link to: Inventory, label: 'Inventory'}"

  3. Paste this code in JavaScript section of story

comesFromMenu = function (){
      if (trail.length>1){
          if (engine.story.passageNamed(trail[trail.length-2]).tags.includes("menu")){
              return true;
          }else{
              return false;
        }
  } else {
        return undefined;  
  }
  };

  get_last_ingame_passage =function(){
   let trail_clone=Object.assign([],trail);
   let rtrail=trail_clone.reverse(); 
   let result = rtrail.find(el => !engine.story.passageNamed(el).tags.includes("menu"));
   return result;
  }

  1. At the bottom of the inventory/menu, or wherein you want to insert your link back to ingame, paste the following:
[JavaScript]
engine.state.set("last_ingame_passage",get_last_ingame_passage());
[continue]
{link to: last_ingame_passage, label: 'Continue'}
  1. UPDATE:
    In order to avoid (for example) the same vars been incremented again when you return from the inventory/menu passage/s to the last ingame passage, you must express that condition at vars section:

strength (comesFromMenu() != true): strength+ 1

You can also perform those operations inside a javascript tag in any passage:

[JavaScript]
if (!comesFromMenu()) { 
strength = strength +1; 
}
[continue]
2 Likes

@javiermobile Damn! *mind blown*

Love seeing all the creative ways to tackle Chapbook. So many methods at play here. Thanks so much for sharing!

1 Like