twinejs icon indicating copy to clipboard operation
twinejs copied to clipboard

Feature: Sub-Storys, or Passage Grouping

Open JGwilliams opened this issue 2 years ago • 5 comments

Is your feature request related to a problem? Please describe.

It can be awkward to deal with a story containing a large number of individual passages, especially when many of those passages are only intended to 'break up' long sequences of text into discrete pages for the purposes of readability, or when the story has several discrete 'Chapters' that are jumped between in a complex fashion.

Describe the solution you'd like.

I propose the creation of passage groups, in which a set of passages can be joined together into a single icon. This would look similar to a regular passage - maybe give it a thicker border or a different colour to set it apart - but when clicked, would load up the passages it contains as if it were a miniature story of its own, with arrows pointing in and out of it to show how it links to other elements in the 'parent'.

Such a passage group could then contain more passage groups in a true hierarchical manner. The compiler would unstack all of this when converting to a particular story format, so no changes to format would be required.

The feature could be used by selecting the passages you want to group and selecting 'group'. Further passages might then be added by double-clicking it to access its own sub-story view, or by dragging them on top of it. An 'ungroup' option would also be available. Another nice-to-have feature would be the ability to add another story into the current one as a sub-story, or export a sub-story as its own entity.

Furthermore, links to passages within sub-stories could be implemented using dot notation, i.e. if you have a sub-story called 'Prologue' with a passage called 'Introduction', you could link to it directly with [[Intro->Prologue.Introduction]]. Only putting the name of the sub-story itself would link to that sub-story's designated 'first passage' instead. Connecting out of the current story could be done using the keyword 'parent', i.e. [[Done->Parent.Next Page]]. The word 'Parent' could also be chained in hierarchies that are several layers deep, i.e. [[Done->Parent.Parent.Parent.Next Page.Start]] would walk up the hierarchy three stages, look for a sub-story called 'Next Page' and link to a passage called 'Start' residing within it.

Describe alternatives you've considered.

I am currently using a system whereby a case statement referencing a local variable called 'Page' are used, along with links back to the same passage, to have one passage simulate several. This is fine and good, but there's more boilerplate code than I'd like and it is not as adaptable as the above-mentioned feature would be.

Additional context on this suggestion.

I am currently working on a large, branching narrative with several 'chapters'. There are over 200 passages in this story and they connect back and forth in a very complex way. This feature would make the main story screen look much clearer, make it easier for me to see which parts of the story connect to which other parts, and track the player's potential progress through the narrative much more quickly and accurately.

P.S. I would've offered to help with code, but I'm a Mac OS programmer and not very conversant in JavaScript, so I don't think I'd be able to help much.

Presubmission checklist

  • [ ] I am interested in working on code that would implement this feature request. (This is not required to submit a suggestion.)
  • [X] I have done a search and believe that an issue does not already exist for this idea in the GitHub repository.
  • [X] I have read and agree to abide by this project's Code of Conduct.

JGwilliams avatar Mar 03 '23 06:03 JGwilliams

@JGwilliams

Such a passage group could then contain more passage groups in a true hierarchical manner. The compiler would unstack all of this when converting to a particular story format, so no changes to format would be required.

All information about a project created in the Desktop release of the Twine 2.x application is stored within the <tw-storydata> element of the generated Project / Story HTML file, see the Twine 2 HTML Output (v1.0.1) specification.

This means that for there to be "passage groups" of any kind, hierarchical or not, there will need to be changes:

  • to the structure of the <tw-storydata> element that gets embedded within the story format's template file, and to the above linked specification.
  • to the Twine & TWEE Notation compilers used to generate Project and Story HTML files.

This isn't to say your idea isn't a good one, just that it will affect more things than you might of expected.

Furthermore, links to passages within sub-stories could be implemented using dot notation, i.e. if you have a sub-story called 'Prologue' with a passage called 'Introduction', you could link to it directly with [[Intro->Prologue.Introduction]].

Altering how the Target Passage component of a Markup based Link behaves will definitely affect all story format engines, as those engines are responsible for converting the markup into an selectable link. And for executing any associated behaviour when that link is selected.

greyelf avatar Mar 03 '23 07:03 greyelf

Just to be clear, when I said it wouldn't require changes to a format, I meant only the Story Formats. In other words, it wouldn't require third-party changes if it was treated as a compile-time feature.

As for links, those would also need some work at compile time. For example, replacing all grouped passage names with their dot-notation version, and all links to that passage with the same name.

Now, I've not seen the internals of the project so I don't know how feasible it is to do this, but I don't see why it wouldn't be possible to perform these changes prior to converting to a specific story format?

JGwilliams avatar Mar 03 '23 08:03 JGwilliams

Each Story Format template is a self contained singe-page web-application into which the different meta-data types of a project gets embedded into at "compile" time.

Each project in the Desktop release of the application is stored as a "compiled" HTML file.

The current "compiling" process can be inferred from the Twine 2 HTML Output (v1.0.1) specification I linked to earlier. But it basically consists of the following steps:

  • wrapping the content of each Passage, after specific characters have been encoded, in a <tw-passagedata> element that has specific attribute values assigned to it.
  • wrapping the content of the Story JavaScript area in a <script> element that has specific attribute values assigned to it.
  • wrapping the content of the Story Stylesheet area in a <style> element that has specific attribute values assigned to it.
  • wrapping each Passage Tag colour assignment in a <tw-tag> element that has specific attribute values assigned to it.
  • wrapping all of the above elements within a <tw-storydata> element that has specific attribute values assigned to it.
  • embedding the above structure within a copy of the selected Story Format's template, and saving that as a HTML file.

As you can see, the "compiler" currently doesn't do much with the project meta-data, and in some ways it could be considered more of "packager" than a compiler.

greyelf avatar Mar 03 '23 22:03 greyelf

Welcome to the most popular issue in this repo (at the moment).

See also: #1354, #1345, #190, #412, #583, #707, #714, #282, #520

hituro avatar Mar 06 '23 22:03 hituro

https://github.com/klembot/twinejs/issues/1354#issuecomment-1401200249 has my most recent thoughts on this idea.

klembot avatar Mar 13 '23 22:03 klembot