diff --git a/Tutorial.md b/Tutorial.md
index 271e641..43b85a2 100644
--- a/Tutorial.md
+++ b/Tutorial.md
@@ -72,14 +72,14 @@ Finally, we get to the custom properties. In this case there's just one:
* `character`: This is the specific character that'll be bound to this storylet instance.
-Now that we have the storylet generator, all that's left to do is to query it in the appropriate Twine passage, and then do something with each possible storylet. We can get the array of available instantiated storylets with `window.SM.getAllStorylets()`.
+Now that we have the storylet generator, all that's left to do is to query it in the appropriate Twine passage, and then do something with each possible storylet. We can get the array of available instantiated storylets with `window.SM.getStorylets()`.
One typical thing to do with this list is create a link associated with each possible storylet for the player to choose from. We can do it like this:
```
:: Start
You stand at the edge of the grand ballroom in the Duchess's palace.
-<>
+<>
<>
<>
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]
@@ -87,7 +87,7 @@ You stand at the edge of the grand ballroom in the Duchess's palace.
<>
```
-This creates one link per available storylet. Each link will have the storylet description as its text, link to the storylet's passage, and when selected will story the storylet's data in the `$currentStorylet` variable, so that the storylet passage itself can access it. This pattern is (expected to be) common enough that there's a widget for it: `<>`. (**TODO:** Make this a macro). We may also not want to show *all* the available storylets. When there are just three guests it isn't so bad, but if the party has five, or ten, or more NPCs, giving the player the entire list will get overwhelming fast. We can randomly choose a subset, to emulate how people randomly circulate during the party. Instead, maybe we want to choose only some number of storylets to display. We can do this with `window.SM.getNStorylets(n)` where `n` is the number of storylets to get. Storylets are selected in order of priority, so that the list is filled with higher-priority storylets first.
+This creates one link per available storylet. Each link will have the storylet description as its text, link to the storylet's passage, and when selected will story the storylet's data in the `$currentStorylet` variable, so that the storylet passage itself can access it. This pattern is (expected to be) common enough that there's a widget for it: `<>`. (**TODO:** Make this a macro). We may also not want to show *all* the available storylets. When there are just three guests it isn't so bad, but if the party has five, or ten, or more NPCs, giving the player the entire list will get overwhelming fast. We can randomly choose a subset, to emulate how people randomly circulate during the party. Instead, maybe we want to choose only some number of storylets to display. We can do this by passing a number to `getStorylets`indicating the maximum number of storylets to get. Storylets are selected in order of priority, so that the list is filled with higher-priority storylets first.
#### Putting it all together
@@ -133,7 +133,7 @@ StoryManager.storylets["Conversation"] = {
:: Start
You stand at the edge of the grand ballroom in the Duchess's palace.
-<>
+<>
<>
@@ -145,6 +145,10 @@ You make polite conversation with $talkingTo.name.
To compile this with Tweego, run:
```
-tweego storymanager.js storymanager-widgets.tw examples\at_the_party.tw -o at_the_party.html
+> tweego storymanager.js storymanager-widgets.tw examples\at_the_party.tw -o at_the_party.html
```
+### Adding interruptions
+
+Is it even a real party if you aren't buttonholed by another guest at some point or another? In many games you'll want to allow some storylets to override the other options and require the player to engage with them now. We do this via a storylet that has the `interrupt==true` property.
+
diff --git a/at_the_party.html b/at_the_party.html
index 6e3b3ab..5179fda 100644
--- a/at_the_party.html
+++ b/at_the_party.html
@@ -121,19 +121,39 @@ StoryManager.getAllStorylets = function() {
return allStorylets;
}
-StoryManager.getNStorylets = function(n) {
+StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true)
+{
/*
- Get N storylets, prioritizing the highest-priority ones first.
+ Get n storylets, prioritizing the highest-priority ones first.
+
+ n: if not null, return at most n storylets
+ tag: Only get storylets matching this tag
+ respect_interrupt: if true, any interrupt storylet overrides n and priority
+
For now assume that priorities are integers, but it would be nice
to be more flexible.
*/
- let allStorylets = this.getAllStorylets();
- n = Math.min(n, allStorylets.length);
- if (n == 0) return [];
+ let allStorylets;
+ if (tag == null) allStorylets = this.getAllStorylets();
+ // TODO: get tagged storylets
+
+ // Check for interruptions
+ // TODO: Handle more than one interruption
+ if (respect_interrupt)
+ for (let storylet in allStorylets)
+ if (storylet.interrupt) return [storylet];
+
+ // Get n stories in priority order
+ if (n != null) {
+ n = Math.min(n, allStorylets.length);
+ if (n == 0) return [];
+ }
+ else n = allStorylets.length;
let selectedStorylets = [];
// First sort by ascending priority:
allStorylets.sort((a, b) => b.priority - a.priority);
+
let currentPriority = allStorylets[0].priority;
while (selectedStorylets.length < n) {
let priorityStorylets = allStorylets.filter(s => s.priority==currentPriority);
@@ -180,7 +200,7 @@ StoryManager.storylets["Conversation"] = {
<</capture>>
<</for>>
<</widget>>You stand at the edge of the grand ballroom in the Duchess's palace.<br>
-<<set _possibleStories = window.SM.getNStorylets(3)>>
+<<set _possibleStories = window.SM.getStorylets(3)>>
<<ShowStoryletLinks _possibleStories>><<set $talkingTo = $currentStorylet.character>>
You make polite conversation with $talkingTo.name. <br>
[[Keep circulating | Start]]
diff --git a/examples/at_the_party.tw b/examples/at_the_party.tw
index 1003a3b..67b3523 100644
--- a/examples/at_the_party.tw
+++ b/examples/at_the_party.tw
@@ -37,7 +37,7 @@ StoryManager.storylets["Conversation"] = {
:: Start
You stand at the edge of the grand ballroom in the Duchess's palace.
-<>
+<>
<>
diff --git a/storymanager.js b/storymanager.js
index 58066e6..48be318 100644
--- a/storymanager.js
+++ b/storymanager.js
@@ -18,19 +18,39 @@ StoryManager.getAllStorylets = function() {
return allStorylets;
}
-StoryManager.getNStorylets = function(n) {
+StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true)
+{
/*
- Get N storylets, prioritizing the highest-priority ones first.
+ Get n storylets, prioritizing the highest-priority ones first.
+
+ n: if not null, return at most n storylets
+ tag: Only get storylets matching this tag
+ respect_interrupt: if true, any interrupt storylet overrides n and priority
+
For now assume that priorities are integers, but it would be nice
to be more flexible.
*/
- let allStorylets = this.getAllStorylets();
- n = Math.min(n, allStorylets.length);
- if (n == 0) return [];
+ let allStorylets;
+ if (tag == null) allStorylets = this.getAllStorylets();
+ // TODO: get tagged storylets
+
+ // Check for interruptions
+ // TODO: Handle more than one interruption
+ if (respect_interrupt)
+ for (let storylet in allStorylets)
+ if (storylet.interrupt) return [storylet];
+
+ // Get n stories in priority order
+ if (n != null) {
+ n = Math.min(n, allStorylets.length);
+ if (n == 0) return [];
+ }
+ else n = allStorylets.length;
let selectedStorylets = [];
// First sort by ascending priority:
allStorylets.sort((a, b) => b.priority - a.priority);
+
let currentPriority = allStorylets[0].priority;
while (selectedStorylets.length < n) {
let priorityStorylets = allStorylets.filter(s => s.priority==currentPriority);