@@ -6,7 +6,7 @@ You can use it in the Twine interactive editor, but at the moment it's probably
|
|||||||
|
|
||||||
## How to use it
|
## How to use it
|
||||||
|
|
||||||
Add `storymanager.js` (and optionally `storymanager-widgets.tw`) to your Twine project. In JavaScript, add some story data if needed, and then add a storylet with a name, some tags (optionally), and a `generate` generator function* that `yield`s one or more instantiated storylet objects, like this:
|
Add `storymanager.js` to your Twine project. In JavaScript, add some story data if needed, and then add a storylet with a name, some tags (optionally), and a `generate` generator function* that `yield`s one or more instantiated storylet objects, like this:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|
||||||
@@ -54,12 +54,9 @@ And finally, you need to have a passage where you query for available storylets
|
|||||||
:: Jump
|
:: Jump
|
||||||
|
|
||||||
You prep your ship to jump.
|
You prep your ship to jump.
|
||||||
<<set _possibleStorylets = window.SM.getStorylets()>>
|
<<getStoryletLinks>>
|
||||||
<<ShowStoryletLinks _possibleStorylets>>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
(This example uses the `<<ShowStoryletLinks>>` widget from `storymanager-widgets.tw`)
|
|
||||||
|
|
||||||
You can see this complete example in the `examples\` folder ([twee](https://github.com/dmasad/StoryletManager/blob/main/examples/tutorial.tw) or [playable HTML](https://dmasad.github.io/StoryletManager/examples/simple_space_example.html)).
|
You can see this complete example in the `examples\` folder ([twee](https://github.com/dmasad/StoryletManager/blob/main/examples/tutorial.tw) or [playable HTML](https://dmasad.github.io/StoryletManager/examples/simple_space_example.html)).
|
||||||
|
|
||||||
There's also a [more detailed tutorial](https://github.com/dmasad/StoryletManager/blob/main/docs/Tutorial.md)
|
There's also a [more detailed tutorial](https://github.com/dmasad/StoryletManager/blob/main/docs/Tutorial.md)
|
||||||
@@ -85,7 +82,7 @@ I have a few Twine hobby projects in various stage of completion, and I found my
|
|||||||
- [ ] Storylet with any binding
|
- [ ] Storylet with any binding
|
||||||
- [X] Storylet tagging and filtering (i.e. pull from only a subset of storylets)
|
- [X] Storylet tagging and filtering (i.e. pull from only a subset of storylets)
|
||||||
- [X] Widget for displaying storylet links
|
- [X] Widget for displaying storylet links
|
||||||
- [ ] Make the widget into a macro
|
- [X] Make the widget into a macro
|
||||||
- [ ] Weighted random choice
|
- [ ] Weighted random choice
|
||||||
- [X] Explore replacing storylet generators returning arrays with the `yield` keyword? **Pro:** produces cleaner code; **Con:** requires users to understand `yield` and remember to use the function * notation.
|
- [X] Explore replacing storylet generators returning arrays with the `yield` keyword? **Pro:** produces cleaner code; **Con:** requires users to understand `yield` and remember to use the function * notation.
|
||||||
- [ ] Add storylet code to passages (as comments, a-la Tiny-QBN?)
|
- [ ] Add storylet code to passages (as comments, a-la Tiny-QBN?)
|
||||||
|
|||||||
+23
-9
@@ -85,7 +85,7 @@ You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
|||||||
<</for>>
|
<</for>>
|
||||||
```
|
```
|
||||||
|
|
||||||
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: `<<ShowStoryletLinks>>`. (**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.
|
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 macro for it: `<<getStoryletLinks>>`. 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 `getStoryletLinks`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
|
#### Putting it all together
|
||||||
|
|
||||||
@@ -112,8 +112,7 @@ State.variables.characters = [
|
|||||||
StoryManager.storylets["Conversation"] = {
|
StoryManager.storylets["Conversation"] = {
|
||||||
name: "Conversation",
|
name: "Conversation",
|
||||||
tags: [],
|
tags: [],
|
||||||
generate: function() {
|
generate: function*() {
|
||||||
let storylets = [];
|
|
||||||
for (let i in State.variables.characters) {
|
for (let i in State.variables.characters) {
|
||||||
let character = State.variables.characters[i];
|
let character = State.variables.characters[i];
|
||||||
let storylet = {
|
let storylet = {
|
||||||
@@ -123,16 +122,14 @@ StoryManager.storylets["Conversation"] = {
|
|||||||
character: character
|
character: character
|
||||||
|
|
||||||
}
|
}
|
||||||
storylets.push(storylet);
|
yield storylet;
|
||||||
}
|
}
|
||||||
return storylets;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
:: Start
|
:: Start
|
||||||
You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3)>>
|
<<getStoryletLinks 3>>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
|
||||||
|
|
||||||
|
|
||||||
:: Conversation
|
:: Conversation
|
||||||
@@ -143,7 +140,7 @@ You make polite conversation with $talkingTo.name. <br>
|
|||||||
|
|
||||||
To compile this with Tweego, run:
|
To compile this with Tweego, run:
|
||||||
```
|
```
|
||||||
> tweego storymanager.js storymanager-widgets.tw examples\tutorial.tw -o tutorial.html
|
> tweego storymanager.js examples\tutorial.tw -o tutorial.html
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding interruptions
|
## Adding interruptions
|
||||||
@@ -217,8 +214,25 @@ StoryManager.storylets["Buttonholed"] = {
|
|||||||
// ...etc
|
// ...etc
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Now we need to have the `getStoryletLinks` macro only look for storylets with matching tags. To specify a tag, add it in quotation marks after the number of storylets to get, like this:
|
||||||
|
|
||||||
We also need to update our world model to account for this mechanic: we need to track the protagonist's knowledge, and update the characters to account for their favorite topics and level of knowledge.
|
```
|
||||||
|
:: Start
|
||||||
|
You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
||||||
|
<<getStoryletLinks 3 "circulating">>
|
||||||
|
```
|
||||||
|
|
||||||
|
We'll also update the `Conversation` passage to look for `"during conversation"` storylets:
|
||||||
|
|
||||||
|
```
|
||||||
|
:: Conversation
|
||||||
|
<<set $talkingTo = $currentStorylet.character>>
|
||||||
|
You talk with $talkingTo.name. <br>
|
||||||
|
<<getStoryletLinks 3 "during conversation">>
|
||||||
|
[[Keep circulating | Start]]
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we need to create the conversation-topic storylet generator. First we need to track the protagonist's knowledge, and update the characters to account for their favorite topics and level of knowledge.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
State.variables.playerKnowledge = {poetry: 0, industry: 0, astronomy: 0};
|
State.variables.playerKnowledge = {poetry: 0, industry: 0, astronomy: 0};
|
||||||
|
|||||||
+27
-17
@@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
|
|||||||
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
||||||
<div id="init-loading"><div>Loading…</div></div>
|
<div id="init-loading"><div>Loading…</div></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- UUID://BE18C022-A213-466C-8DD1-DCCD5CB1DF48// --><tw-storydata name="At the Duchess's Party" startnode="2" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="BE18C022-A213-466C-8DD1-DCCD5CB1DF48" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
<!-- UUID://BE18C022-A213-466C-8DD1-DCCD5CB1DF48// --><tw-storydata name="At the Duchess's Party" startnode="1" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="BE18C022-A213-466C-8DD1-DCCD5CB1DF48" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
||||||
|
|
||||||
// Set up the general narrative manager
|
// Set up the general narrative manager
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -166,6 +166,24 @@ StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true) {
|
|||||||
return selectedStorylets;
|
return selectedStorylets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up macros
|
||||||
|
|
||||||
|
Macro.add("getStoryletLinks", {
|
||||||
|
handler: function() {
|
||||||
|
let n, tag;
|
||||||
|
[n=null, tag=null] = this.args;
|
||||||
|
State.temporary.nextStorylets = StoryManager.getStorylets(n, tag);
|
||||||
|
$(this.output).wiki(`
|
||||||
|
<<for _storylet range _nextStorylets>> \
|
||||||
|
<<capture _storylet>> \
|
||||||
|
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
||||||
|
<</capture>> \
|
||||||
|
<</for>> \
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
window.SM = StoryManager;
|
window.SM = StoryManager;
|
||||||
/* twine-user-script #2: "duchess_party.js" */
|
/* twine-user-script #2: "duchess_party.js" */
|
||||||
|
|
||||||
@@ -298,22 +316,14 @@ StoryManager.storylets["Seeing the duchess"] = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
/* twine-user-script #3: "Story JavaScript" */
|
/* twine-user-script #3: "Story JavaScript" */
|
||||||
Config.passages.nobr = true; // Deal with linebreaks.</script><tw-passagedata pid="1" name="StoryManager Widgets" tags="widget" position="100,100" size="100,100"><<widget ShowStoryletLinks>>
|
Config.passages.nobr = true; // Deal with linebreaks.</script><tw-passagedata pid="1" name="Start" tags="" position="100,100" size="100,100">The footmen at the door to the duchess's city residence bows over your forged invitation, seemingly not examining at all. The uniform you wear is authentic, at least, though Frin had found a tailor who would accept some extra florins to not demand to see a letter of appointment before sewing on captain's bars. And just like that, you're in. Could it be that easy, you wonder? <br> <br>
|
||||||
<<for _storylet range $args[0]>>
|
|
||||||
<<capture _storylet>>
|
|
||||||
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
|
||||||
<</capture>>
|
|
||||||
<</for>>
|
|
||||||
<</widget>></tw-passagedata><tw-passagedata pid="2" name="Start" tags="" position="225,100" size="100,100">The footmen at the door to the duchess's city residence bows over your forged invitation, seemingly not examining at all. The uniform you wear is authentic, at least, though Frin had found a tailor who would accept some extra florins to not demand to see a letter of appointment before sewing on captain's bars. And just like that, you're in. Could it be that easy, you wonder? <br> <br>
|
|
||||||
|
|
||||||
Of course it isn't. The hall is filled with aristocrats in evening-wear, making small talk in an ever-shifting constellation. Across the room, the doors to the duchess's private rooms are firmly closed. No way to sneak in without being seen. You're going to have to find a way to [[talk your way in | Circulating]].</tw-passagedata><tw-passagedata pid="3" name="Circulating" tags="" position="350,100" size="100,100">You mingle through the crowd, keeping a wary eye around you.<br>
|
Of course it isn't. The hall is filled with aristocrats in evening-wear, making small talk in an ever-shifting constellation. Across the room, the doors to the duchess's private rooms are firmly closed. No way to sneak in without being seen. You're going to have to find a way to [[talk your way in | Circulating]].</tw-passagedata><tw-passagedata pid="2" name="Circulating" tags="" position="225,100" size="100,100">You mingle through the crowd, keeping a wary eye around you.<br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "circulating")>>
|
<<getStoryletLinks 3 "circulating">></tw-passagedata><tw-passagedata pid="3" name="Conversation" tags="" position="350,100" size="100,100"><<set $talkingTo = $currentStorylet.character>>
|
||||||
<<ShowStoryletLinks _possibleStories>></tw-passagedata><tw-passagedata pid="4" name="Conversation" tags="" position="475,100" size="100,100"><<set $talkingTo = $currentStorylet.character>>
|
|
||||||
You talk with $talkingTo.name. <br>
|
You talk with $talkingTo.name. <br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "during conversation")>>
|
<<getStoryletLinks 3 "during conversation">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
[[Keep circulating | Circulating]]</tw-passagedata><tw-passagedata pid="4" name="Being approached" tags="" position="475,100" size="100,100">$currentStorylet.character.name is coming toward you to talk. <br>
|
||||||
[[Keep circulating | Circulating]]</tw-passagedata><tw-passagedata pid="5" name="Being approached" tags="" position="600,100" size="100,100">$currentStorylet.character.name is coming toward you to talk. <br>
|
You can [[talk to them | Conversation]], or risk snubbing them by [[trying to get away | Circulating][$reputation = $reputation - 1]].</tw-passagedata><tw-passagedata pid="5" name="Conversation topic" tags="" position="600,100" size="100,100"><<set $topic = $currentStorylet.topic>>
|
||||||
You can [[talk to them | Conversation]], or risk snubbing them by [[trying to get away | Circulating][$reputation = $reputation - 1]].</tw-passagedata><tw-passagedata pid="6" name="Conversation topic" tags="" position="725,100" size="100,100"><<set $topic = $currentStorylet.topic>>
|
|
||||||
<<if $playerKnowledge[$topic] < $talkingTo[$topic] >>
|
<<if $playerKnowledge[$topic] < $talkingTo[$topic] >>
|
||||||
$talkingTo.name tells you about <<print $conversationTopics[$topic][$playerKnowledge[$topic]]>>.
|
$talkingTo.name tells you about <<print $conversationTopics[$topic][$playerKnowledge[$topic]]>>.
|
||||||
<<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>>
|
<<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>>
|
||||||
@@ -328,12 +338,12 @@ They listen intently, and seem impressed.
|
|||||||
<<set $reputation = $reputation + 2>>
|
<<set $reputation = $reputation + 2>>
|
||||||
<</if>><br><br>
|
<</if>><br><br>
|
||||||
|
|
||||||
[[Keep circulating | Circulating]]</tw-passagedata><tw-passagedata pid="7" name="Asked to leave" tags="" position="850,100" size="100,100">The footman demands to see your invitation.
|
[[Keep circulating | Circulating]]</tw-passagedata><tw-passagedata pid="6" name="Asked to leave" tags="" position="725,100" size="100,100">The footman demands to see your invitation.
|
||||||
Before you know it, you are firmly escorted through a back hallway, past the kitchens, and finally
|
Before you know it, you are firmly escorted through a back hallway, past the kitchens, and finally
|
||||||
out through the servant's entrance. A single guard glares at you, as of committing your face
|
out through the servant's entrance. A single guard glares at you, as of committing your face
|
||||||
to memory to make sure you'll never be able to come back.<br><br>
|
to memory to make sure you'll never be able to come back.<br><br>
|
||||||
|
|
||||||
FAILURE</tw-passagedata><tw-passagedata pid="8" name="Invited to see the Duchess" tags="" position="975,100" size="100,100">The footman discreetly bows his head under his high cap. "Her grace wishes to speak with you," he says. <br>
|
FAILURE</tw-passagedata><tw-passagedata pid="7" name="Invited to see the Duchess" tags="" position="850,100" size="100,100">The footman discreetly bows his head under his high cap. "Her grace wishes to speak with you," he says. <br>
|
||||||
You follow him as he leads you away from the main hall, and toward the Duchess's private rooms. <br><br>
|
You follow him as he leads you away from the main hall, and toward the Duchess's private rooms. <br><br>
|
||||||
|
|
||||||
VICTORY</tw-passagedata></tw-storydata>
|
VICTORY</tw-passagedata></tw-storydata>
|
||||||
|
|||||||
@@ -16,15 +16,12 @@ Of course it isn't. The hall is filled with aristocrats in evening-wear, making
|
|||||||
|
|
||||||
:: Circulating
|
:: Circulating
|
||||||
You mingle through the crowd, keeping a wary eye around you.<br>
|
You mingle through the crowd, keeping a wary eye around you.<br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "circulating")>>
|
<<getStoryletLinks 3 "circulating">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
|
||||||
|
|
||||||
|
|
||||||
:: Conversation
|
:: Conversation
|
||||||
<<set $talkingTo = $currentStorylet.character>>
|
<<set $talkingTo = $currentStorylet.character>>
|
||||||
You talk with $talkingTo.name. <br>
|
You talk with $talkingTo.name. <br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "during conversation")>>
|
<<getStoryletLinks 3 "during conversation">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
|
||||||
[[Keep circulating | Circulating]]
|
[[Keep circulating | Circulating]]
|
||||||
|
|
||||||
:: Being approached
|
:: Being approached
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
|
|||||||
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
||||||
<div id="init-loading"><div>Loading…</div></div>
|
<div id="init-loading"><div>Loading…</div></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- UUID://2EE3728E-B079-4539-9A9C-97CD8474B4C5// --><tw-storydata name="Simple Space Example" startnode="2" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="2EE3728E-B079-4539-9A9C-97CD8474B4C5" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
<!-- UUID://2EE3728E-B079-4539-9A9C-97CD8474B4C5// --><tw-storydata name="Simple Space Example" startnode="1" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="2EE3728E-B079-4539-9A9C-97CD8474B4C5" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
||||||
|
|
||||||
// Set up the general narrative manager
|
// Set up the general narrative manager
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -166,6 +166,24 @@ StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true) {
|
|||||||
return selectedStorylets;
|
return selectedStorylets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up macros
|
||||||
|
|
||||||
|
Macro.add("getStoryletLinks", {
|
||||||
|
handler: function() {
|
||||||
|
let n, tag;
|
||||||
|
[n=null, tag=null] = this.args;
|
||||||
|
State.temporary.nextStorylets = StoryManager.getStorylets(n, tag);
|
||||||
|
$(this.output).wiki(`
|
||||||
|
<<for _storylet range _nextStorylets>>
|
||||||
|
<<capture _storylet>>
|
||||||
|
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
||||||
|
<</capture>>
|
||||||
|
<</for>>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
window.SM = StoryManager;
|
window.SM = StoryManager;
|
||||||
/* twine-user-script #2: "Story JavaScript" */
|
/* twine-user-script #2: "Story JavaScript" */
|
||||||
Config.passages.nobr = true; // No unspecified linebreaks.
|
Config.passages.nobr = true; // No unspecified linebreaks.
|
||||||
@@ -187,18 +205,11 @@ StoryManager.storylets["Go somewhere"] = {
|
|||||||
yield storylet;
|
yield storylet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}</script><tw-passagedata pid="1" name="StoryManager Widgets" tags="widget" position="100,100" size="100,100"><<widget ShowStoryletLinks>>
|
}</script><tw-passagedata pid="1" name="Start" tags="" position="100,100" size="100,100">You find yourself in $currentLocation. You should probably [[jump | Jump]].</tw-passagedata><tw-passagedata pid="2" name="Jump" tags="" position="225,100" size="100,100">You prep your ship to jump.
|
||||||
<<for _storylet range $args[0]>>
|
<<getStoryletLinks>></tw-passagedata><tw-passagedata pid="3" name="Orbit" tags="" position="350,100" size="100,100"><<set $currentLocation = $currentStorylet.planet>>
|
||||||
<<capture _storylet>>
|
|
||||||
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
|
||||||
<</capture>>
|
|
||||||
<</for>>
|
|
||||||
<</widget>></tw-passagedata><tw-passagedata pid="2" name="Start" tags="" position="225,100" size="100,100">You find yourself in $currentLocation. You should probably [[jump | Jump]].</tw-passagedata><tw-passagedata pid="3" name="Jump" tags="" position="350,100" size="100,100">You prep your ship to jump.
|
|
||||||
<<set _possibleStorylets = window.SM.getStorylets()>>
|
|
||||||
<<ShowStoryletLinks _possibleStorylets>></tw-passagedata><tw-passagedata pid="4" name="Orbit" tags="" position="475,100" size="100,100"><<set $currentLocation = $currentStorylet.planet>>
|
|
||||||
You orbit around $currentLocation.
|
You orbit around $currentLocation.
|
||||||
|
|
||||||
[[Explore the surface]] or [[Jump]] somewhere else.</tw-passagedata><tw-passagedata pid="5" name="Explore the surface" tags="" position="600,100" size="100,100">You take your shuttle down to the surface of $currentLocation.
|
[[Explore the surface]] or [[Jump]] somewhere else.</tw-passagedata><tw-passagedata pid="4" name="Explore the surface" tags="" position="475,100" size="100,100">You take your shuttle down to the surface of $currentLocation.
|
||||||
|
|
||||||
Return to [[Orbit]]</tw-passagedata></tw-storydata>
|
Return to [[Orbit]]</tw-passagedata></tw-storydata>
|
||||||
<script id="script-sugarcube" type="text/javascript">
|
<script id="script-sugarcube" type="text/javascript">
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ You find yourself in $currentLocation. You should probably [[jump | Jump]].
|
|||||||
|
|
||||||
:: Jump
|
:: Jump
|
||||||
You prep your ship to jump.
|
You prep your ship to jump.
|
||||||
<<set _possibleStorylets = window.SM.getStorylets()>>
|
<<getStoryletLinks>>
|
||||||
<<ShowStoryletLinks _possibleStorylets>>
|
|
||||||
|
|
||||||
:: Orbit
|
:: Orbit
|
||||||
<<set $currentLocation = $currentStorylet.planet>>
|
<<set $currentLocation = $currentStorylet.planet>>
|
||||||
|
|||||||
+30
-14
@@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
|
|||||||
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
<div id="init-lacking">Your browser lacks required capabilities. Please upgrade it or switch to another to continue.</div>
|
||||||
<div id="init-loading"><div>Loading…</div></div>
|
<div id="init-loading"><div>Loading…</div></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- UUID://BE18C022-A213-466C-8DD1-DCCD5CB1DF48// --><tw-storydata name="At the Duchess's Party" startnode="2" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="BE18C022-A213-466C-8DD1-DCCD5CB1DF48" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
<!-- UUID://BE18C022-A213-466C-8DD1-DCCD5CB1DF48// --><tw-storydata name="At the Duchess's Party" startnode="1" creator="Tweego" creator-version="2.1.0+9ea2fab" ifid="BE18C022-A213-466C-8DD1-DCCD5CB1DF48" zoom="1" format="SugarCube" format-version="2.30.0" options="" hidden><style role="stylesheet" id="twine-user-stylesheet" type="text/twine-css"></style><script role="script" id="twine-user-script" type="text/twine-javascript">/* twine-user-script #1: "storymanager.js" */
|
||||||
|
|
||||||
// Set up the general narrative manager
|
// Set up the general narrative manager
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -166,6 +166,24 @@ StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true) {
|
|||||||
return selectedStorylets;
|
return selectedStorylets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up macros
|
||||||
|
|
||||||
|
Macro.add("getStoryletLinks", {
|
||||||
|
handler: function() {
|
||||||
|
let n, tag;
|
||||||
|
[n=null, tag=null] = this.args;
|
||||||
|
State.temporary.nextStorylets = StoryManager.getStorylets(n, tag);
|
||||||
|
$(this.output).wiki(`
|
||||||
|
<<for _storylet range _nextStorylets>>
|
||||||
|
<<capture _storylet>>
|
||||||
|
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
||||||
|
<</capture>>
|
||||||
|
<</for>>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
window.SM = StoryManager;
|
window.SM = StoryManager;
|
||||||
/* twine-user-script #2: "Story JavaScript" */
|
/* twine-user-script #2: "Story JavaScript" */
|
||||||
Config.passages.nobr = true; // Deal with linebreaks.
|
Config.passages.nobr = true; // Deal with linebreaks.
|
||||||
@@ -188,6 +206,12 @@ State.variables.characters = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Choose one of an array
|
||||||
|
var randomChoice = function(vals) {
|
||||||
|
return vals[Math.floor(Math.random() * vals.length)];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
StoryManager.storylets["Conversation"] = {
|
StoryManager.storylets["Conversation"] = {
|
||||||
name: "Conversation",
|
name: "Conversation",
|
||||||
tags: ["circulating"],
|
tags: ["circulating"],
|
||||||
@@ -238,20 +262,12 @@ StoryManager.storylets["Conversation topic"] = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};</script><tw-passagedata pid="1" name="StoryManager Widgets" tags="widget" position="100,100" size="100,100"><<widget ShowStoryletLinks>>
|
};</script><tw-passagedata pid="1" name="Start" tags="" position="100,100" size="100,100">You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
||||||
<<for _storylet range $args[0]>>
|
<<getStoryletLinks 3 "circulating">></tw-passagedata><tw-passagedata pid="2" name="Conversation" tags="" position="225,100" size="100,100"><<set $talkingTo = $currentStorylet.character>>
|
||||||
<<capture _storylet>>
|
|
||||||
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
|
||||||
<</capture>>
|
|
||||||
<</for>>
|
|
||||||
<</widget>></tw-passagedata><tw-passagedata pid="2" name="Start" tags="" position="225,100" size="100,100">You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "circulating")>>
|
|
||||||
<<ShowStoryletLinks _possibleStories>></tw-passagedata><tw-passagedata pid="3" name="Conversation" tags="" position="350,100" size="100,100"><<set $talkingTo = $currentStorylet.character>>
|
|
||||||
You talk with $talkingTo.name. <br>
|
You talk with $talkingTo.name. <br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "during conversation")>>
|
<<getStoryletLinks 3 "during conversation">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
[[Keep circulating | Start]]</tw-passagedata><tw-passagedata pid="3" name="Being approached" tags="" position="350,100" size="100,100">$currentStorylet.character.name is coming toward you to talk. <br>
|
||||||
[[Keep circulating | Start]]</tw-passagedata><tw-passagedata pid="4" name="Being approached" tags="" position="475,100" size="100,100">$currentStorylet.character.name is coming toward you to talk. <br>
|
You can [[talk to them | Conversation]], or risk snubbing them by [[trying to get away | Start]].</tw-passagedata><tw-passagedata pid="4" name="Conversation topic" tags="" position="475,100" size="100,100"><<set $topic = $currentStorylet.topic>>
|
||||||
You can [[talk to them | Conversation]], or risk snubbing them by [[trying to get away | Start]].</tw-passagedata><tw-passagedata pid="5" name="Conversation topic" tags="" position="600,100" size="100,100"><<set $topic = $currentStorylet.topic>>
|
|
||||||
<<if $playerKnowledge[$topic] < $talkingTo[$topic] >>
|
<<if $playerKnowledge[$topic] < $talkingTo[$topic] >>
|
||||||
<<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>>
|
<<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>>
|
||||||
(They tell you about $topic) (Knowledge of $topic goes up)
|
(They tell you about $topic) (Knowledge of $topic goes up)
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ State.variables.characters = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Choose one of an array
|
||||||
|
var randomChoice = function(vals) {
|
||||||
|
return vals[Math.floor(Math.random() * vals.length)];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
StoryManager.storylets["Conversation"] = {
|
StoryManager.storylets["Conversation"] = {
|
||||||
name: "Conversation",
|
name: "Conversation",
|
||||||
tags: ["circulating"],
|
tags: ["circulating"],
|
||||||
@@ -82,15 +88,12 @@ StoryManager.storylets["Conversation topic"] = {
|
|||||||
|
|
||||||
:: Start
|
:: Start
|
||||||
You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
You stand at the edge of the grand ballroom in the Duchess's palace.<br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "circulating")>>
|
<<getStoryletLinks 3 "circulating">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
|
||||||
|
|
||||||
|
|
||||||
:: Conversation
|
:: Conversation
|
||||||
<<set $talkingTo = $currentStorylet.character>>
|
<<set $talkingTo = $currentStorylet.character>>
|
||||||
You talk with $talkingTo.name. <br>
|
You talk with $talkingTo.name. <br>
|
||||||
<<set _possibleStories = window.SM.getStorylets(3, "during conversation")>>
|
<<getStoryletLinks 3 "during conversation">>
|
||||||
<<ShowStoryletLinks _possibleStories>>
|
|
||||||
[[Keep circulating | Start]]
|
[[Keep circulating | Start]]
|
||||||
|
|
||||||
:: Being approached
|
:: Being approached
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
:: StoryManager Widgets [widget]
|
|
||||||
<<widget ShowStoryletLinks>>
|
|
||||||
<<for _storylet range $args[0]>>
|
|
||||||
<<capture _storylet>>
|
|
||||||
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
|
||||||
<</capture>>
|
|
||||||
<</for>>
|
|
||||||
<</widget>>
|
|
||||||
@@ -63,4 +63,22 @@ StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true) {
|
|||||||
return selectedStorylets;
|
return selectedStorylets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up macros
|
||||||
|
|
||||||
|
Macro.add("getStoryletLinks", {
|
||||||
|
handler: function() {
|
||||||
|
let n, tag;
|
||||||
|
[n=null, tag=null] = this.args;
|
||||||
|
State.temporary.nextStorylets = StoryManager.getStorylets(n, tag);
|
||||||
|
$(this.output).wiki(`
|
||||||
|
<<for _storylet range _nextStorylets>> \
|
||||||
|
<<capture _storylet>> \
|
||||||
|
[[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br>
|
||||||
|
<</capture>> \
|
||||||
|
<</for>> \
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
window.SM = StoryManager;
|
window.SM = StoryManager;
|
||||||
Reference in New Issue
Block a user