From e1e89322079fbb809412bc953b3b4b7420845a3b Mon Sep 17 00:00:00 2001 From: David Masad Date: Sat, 20 Feb 2021 21:11:19 -0500 Subject: [PATCH 1/4] Creating and testing macro --- examples/duchess_party.html | 44 ++++++++++++++++++------------ examples/duchess_party.tw | 7 ++--- examples/simple_space_example.html | 33 ++++++++++++++-------- examples/simple_space_example.tw | 3 +- examples/tutorial.html | 44 ++++++++++++++++++++---------- examples/tutorial.tw | 13 +++++---- storymanager.js | 18 ++++++++++++ 7 files changed, 108 insertions(+), 54 deletions(-) diff --git a/examples/duchess_party.html b/examples/duchess_party.html index e45a7b9..fb691cb 100644 --- a/examples/duchess_party.html +++ b/examples/duchess_party.html @@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
Loading…
- diff --git a/examples/duchess_party.tw b/examples/duchess_party.tw index a3ad561..9be2e9e 100644 --- a/examples/duchess_party.tw +++ b/examples/duchess_party.tw @@ -16,15 +16,12 @@ Of course it isn't. The hall is filled with aristocrats in evening-wear, making :: Circulating You mingle through the crowd, keeping a wary eye around you.
-<> -<> - +<> :: Conversation <> You talk with $talkingTo.name.
-<> -<> +<> [[Keep circulating | Circulating]] :: Being approached diff --git a/examples/simple_space_example.html b/examples/simple_space_example.html index 5b58789..3259378 100644 --- a/examples/simple_space_example.html +++ b/examples/simple_space_example.html @@ -100,7 +100,7 @@ var saveAs=saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||f
Your browser lacks required capabilities. Please upgrade it or switch to another to continue.
Loading…
- <<widget ShowStoryletLinks>> - <<for _storylet range $args[0]>> - <<capture _storylet>> - [[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]<br> - <</capture>> - <</for>> -<</widget>>You stand at the edge of the grand ballroom in the Duchess's palace.<br> -<<set _possibleStories = window.SM.getStorylets(3, "circulating")>> -<<ShowStoryletLinks _possibleStories>><<set $talkingTo = $currentStorylet.character>> +};You stand at the edge of the grand ballroom in the Duchess's palace.<br> +<<getStoryletLinks 3 "circulating">><<set $talkingTo = $currentStorylet.character>> You talk with $talkingTo.name. <br> -<<set _possibleStories = window.SM.getStorylets(3, "during conversation")>> -<<ShowStoryletLinks _possibleStories>> -[[Keep circulating | Start]]$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]].<<set $topic = $currentStorylet.topic>> +<<getStoryletLinks 3 "during conversation">> +[[Keep circulating | Start]]$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]].<<set $topic = $currentStorylet.topic>> <<if $playerKnowledge[$topic] < $talkingTo[$topic] >> <<set $playerKnowledge[$topic] = $playerKnowledge[$topic] + 1>> (They tell you about $topic) (Knowledge of $topic goes up) diff --git a/examples/tutorial.tw b/examples/tutorial.tw index fddc870..374b6fd 100644 --- a/examples/tutorial.tw +++ b/examples/tutorial.tw @@ -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"] = { name: "Conversation", tags: ["circulating"], @@ -82,15 +88,12 @@ StoryManager.storylets["Conversation topic"] = { :: Start You stand at the edge of the grand ballroom in the Duchess's palace.
-<> -<> - +<> :: Conversation <> You talk with $talkingTo.name.
-<> -<> +<> [[Keep circulating | Start]] :: Being approached diff --git a/storymanager.js b/storymanager.js index 42d782f..130f705 100644 --- a/storymanager.js +++ b/storymanager.js @@ -63,4 +63,22 @@ StoryManager.getStorylets = function(n=null, tag=null, respect_interrupt=true) { 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(` + <> \ + <> \ + [[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]
+ <
> \ + <
> \ + `); + } +}) + + window.SM = StoryManager; \ No newline at end of file From fa6b69dec50b9ecb6da8a0056a90780cea8e32a6 Mon Sep 17 00:00:00 2001 From: David Masad Date: Sat, 20 Feb 2021 21:33:51 -0500 Subject: [PATCH 2/4] Updating documentation --- Readme.md | 5 ++--- docs/Tutorial.md | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Readme.md b/Readme.md index c7c625e..145f1e7 100644 --- a/Readme.md +++ b/Readme.md @@ -6,7 +6,7 @@ You can use it in the Twine interactive editor, but at the moment it's probably ## 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 @@ -54,8 +54,7 @@ And finally, you need to have a passage where you query for available storylets :: Jump You prep your ship to jump. -<> -<> +<> ``` (This example uses the `<>` widget from `storymanager-widgets.tw`) diff --git a/docs/Tutorial.md b/docs/Tutorial.md index 1122685..d84831a 100644 --- a/docs/Tutorial.md +++ b/docs/Tutorial.md @@ -85,7 +85,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 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: `<>`. 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 @@ -131,8 +131,7 @@ StoryManager.storylets["Conversation"] = { :: Start You stand at the edge of the grand ballroom in the Duchess's palace.
-<> -<> +<> :: Conversation @@ -143,7 +142,7 @@ You make polite conversation with $talkingTo.name.
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 From 35419a039036d429a79753b5dd8130928192e894 Mon Sep 17 00:00:00 2001 From: David Masad Date: Sun, 21 Feb 2021 14:04:37 -0500 Subject: [PATCH 3/4] Updating tutorial --- Readme.md | 4 +--- docs/Tutorial.md | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Readme.md b/Readme.md index 145f1e7..965ac03 100644 --- a/Readme.md +++ b/Readme.md @@ -57,8 +57,6 @@ You prep your ship to jump. <> ``` -(This example uses the `<>` 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)). There's also a [more detailed tutorial](https://github.com/dmasad/StoryletManager/blob/main/docs/Tutorial.md) @@ -84,7 +82,7 @@ I have a few Twine hobby projects in various stage of completion, and I found my - [ ] Storylet with any binding - [X] Storylet tagging and filtering (i.e. pull from only a subset of storylets) - [X] Widget for displaying storylet links - - [ ] Make the widget into a macro + - [X] Make the widget into a macro - [ ] 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. - [ ] Add storylet code to passages (as comments, a-la Tiny-QBN?) diff --git a/docs/Tutorial.md b/docs/Tutorial.md index d84831a..31f70a8 100644 --- a/docs/Tutorial.md +++ b/docs/Tutorial.md @@ -112,8 +112,7 @@ State.variables.characters = [ StoryManager.storylets["Conversation"] = { name: "Conversation", tags: [], - generate: function() { - let storylets = []; + generate: function*() { for (let i in State.variables.characters) { let character = State.variables.characters[i]; let storylet = { @@ -123,9 +122,8 @@ StoryManager.storylets["Conversation"] = { character: character } - storylets.push(storylet); + yield storylet; } - return storylets; } }; @@ -216,8 +214,25 @@ StoryManager.storylets["Buttonholed"] = { // ...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.
+<> +``` + +We'll also update the `Conversation` passage to look for `"during conversation"` storylets: + +``` +:: Conversation +<> +You talk with $talkingTo.name.
+<> +[[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 State.variables.playerKnowledge = {poetry: 0, industry: 0, astronomy: 0}; From 5c1c9f0fdd10ce76b9a1c77cebe363728f5c504a Mon Sep 17 00:00:00 2001 From: David Masad Date: Sun, 21 Feb 2021 14:08:17 -0500 Subject: [PATCH 4/4] Remove widget --- storymanager-widgets.tw | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 storymanager-widgets.tw diff --git a/storymanager-widgets.tw b/storymanager-widgets.tw deleted file mode 100644 index fa691cf..0000000 --- a/storymanager-widgets.tw +++ /dev/null @@ -1,8 +0,0 @@ -:: StoryManager Widgets [widget] -<> - <> - <> - [[_storylet.description|_storylet.passage][$currentStorylet=_storylet]]
- <
> - <
> -<
> \ No newline at end of file