enter outcomes
-
+
:FEEDSTATUS:
-(("https://rollenspiel.social/@ArneBab/116184787946488782" t
- "e47b72dd65eca7dc6a938f230683f578c3706cd0")
- ("https://rollenspiel.social/@ArneBab/116184867343572536" t
+(("https://rollenspiel.social/@ArneBab/116184867343572536" t
"3aab3c84b0f76be11ec4a81fac608d8115e75a86")
("https://rollenspiel.social/@ArneBab/116188265207924926" t
"e1b6c634b0e06899d0d0ab2469a784e7d45ff5eb")
("https://rollenspiel.social/@ArneBab/116226808398233552" t
"8b2d77a7c3d7ac30097917342e5620b596eedda1")
("https://rollenspiel.social/@ArneBab/116227195094679272" t
- "7a38d448026206da50c91f1c6af80bff763997e6"))
+ "7a38d448026206da50c91f1c6af80bff763997e6")
+ ("https://rollenspiel.social/@ArneBab/116228573797280367" t
+ "340c8e4521a707301234e7a4777a6b0c07049b88"))
:END:
+** [2026-03-14 Sa 16:54]
+ Documented how to analyze the plot of an enter-three-witches #game:
+
+
+https://www.draketo.de/software/enter-three-witches#analyze
+
+
+The images in this post show the text-output of an analysis of a
+stripped down example, its diagram output, the diagram of Dryads
+Wake¹, and the code of the stripped down example.
+
+
+¹: https://dryads-wake.1w6.org
+
+
+Scenes are save-points that I still need to document in a later
+section, along with saving and loading a game, but outcomes work
+without them.
+
+
+#wisp gamedev programming scheme lisp writing
+
+ [[https://rollenspiel.social/@ArneBab/116228573797280367]]
+
+
** [2026-03-14 Sa 11:04]
#Youtube broke my privacy embed which shows a link in an iframe that
you click to get to the youtube page:
[[https://rollenspiel.social/@ArneBab/116184867343572536]]
-** [2026-03-06 Fr 23:19]
- Heute abend auf einer tollen Wahlveranstaltung mit Pascal
-Haggenmüller, Nicole Heger, und Ricarda Lang in Stutensee Büchig.
-
-
-Im Alt-Text stehen neben der Bildbeschreibung die Notizen aus den
-Reden (für den Fall, dass sie in meiner Handschrift zu schwer zu lesen
-sind, außerdem brauchen Blinde sie eh als Text).
-
-
-Das tolle Schlusswort noch hier:
-
-
-„Es ist gut, die schönen Momente zu nutzen“ -- Ricarda Lang
-
-
-#Buendnis90DieGruenen BadenWurttemberg Wahl RicardaLang sketchnotes
-#politik
-
- [[https://rollenspiel.social/@ArneBab/116184787946488782]]
-
-
* Gute Neuigkeiten
Korrekturen von Aussagen im Ostermann-Buch:
-- Jugendkriminalität lag früher deutlich höher
+- Jugendkriminalität lag anders als er schreibt früher deutlich höher
- Mord und Totschlag bleiben auf niedrigem Niveau
- Deutsche haben weniger Angst vor Straftaten als früher
- Zum Hambacher Forst gibt es keine Belege für von ihm genannte
#+BEGIN_SRC sh :eval yes :exports results :results output raw
- for i in $(ls software | grep \\.org$ | grep "^guix-config.org\\|^wisp.org\\|^guile-10x.org\\|^guile-snippets.org\\|^guix-specified-package.org\\|^guile-capture-stdout-stderr.org\\|^guile-fast.org\\|^zen-for-scheme.org\\|^wisp-snippets.org\\|^advent-of-wisp-code-2021.org\\|^install-on-guix.org\\|^package-guix.org" | sort -h); do echo '- [[file:software/'$i']['$(basename $i .org)']]' - $(grep '#+title:' "software/$i" | sed 's/#+title: *//'); done
+ for i in $(ls software | grep \\.org$ | grep "^guix-config.org\\|^wisp.org\\|^enter-three-witches.org\\|^guile-10x.org\\|^guile-snippets.org\\|^guix-specified-package.org\\|^guile-capture-stdout-stderr.org\\|^guile-fast.org\\|^zen-for-scheme.org\\|^wisp-snippets.org\\|^advent-of-wisp-code-2021.org\\|^install-on-guix.org\\|^package-guix.org" | sort -h); do echo '- [[file:software/'$i']['$(basename $i .org)']]' - $(grep '#+title:' "software/$i" | sed 's/#+title: *//'); done
#+END_SRC
/Short and unfinished:/
#+BEGIN_SRC sh :eval yes :exports results :results output raw
- for i in $(ls software | grep \\.org$ | grep -v "^vorlesung-verteilte-systeme.org\\|^guix-specified-package.org\\|^bsi-grundschutz.org\\|^language-empiric.org\\|^vorlesung-netztechnik.org\\|^p2p-talk.org\\|^decentralized-moderation.org\\|^kontaktinfos-mit-gnupg.org\\|^freenet-hidden-channel.org\\|^guix-work.org\\|guix-config.org\\|letterblock-diceware.org\\|^wisp.org\\|^guile-10x.org\\|^guile-snippets.org\\|^guile-capture-stdout-stderr.org\\|^guile-fast.org\\|^zen-for-scheme.org\\|^shell-tricks\\|^python-snippets\\|^mercurial-branching-strategy.org\\|^emacs-javascript.org\\|^wisp-code-katas.org\\|^wisp-snippets.org\\|^advent-of-wisp-code-2021.org\\|^org-mode-tipps\\|^emacs-tipps\\|^package-guix.org\\|^programming-with-wisp.org\\|^programming-scheme.org\\|^programming-basics-wisp.org\\|^putins-kriegsrede.org\\|^install-on-guix.org\\|^package-guix.org\\|^org-mode.org\\|^emacs-daytime.org\\|^emacs-javascript.org\\|^intellij-emacs.org\\|^mercurial-ediff3-emacs.org\\|^orgmode-markdown.org\\|^ferienplan.org\\|^latex-awesome.org\\|^latex-list-of-links.org\\|^stundenplan-wochenplan-latex.org\\|^privacy-embed.org\\|^stream-over-freenet\\|^video-channel-hyphanet.org\\|^m3u-player.org\\|^find-dorktower.org\\|^ffmpeg-compression-vp9-av1.org\\|^comment-your-code.org\\|^gpl-or-later.org\\|^langsame-simple-werkzeuge.org\\|^slow-simple-tools.org\\|^optimize-for-firefox.org\\|^programs-you-can-still-hack-when-dumb.org\\|^tinkering-stability.org\\|^volatile-infrastructure.org\\|^typescript-risks.org\\|^hurd-authorization-translator.org\\|^keyboard-layout-evolution.org\\|^gamedev-notes.org" | sort -h); do echo '- [[file:software/'$i']['$(basename $i .org)']]' - $(grep '#+title:' "software/$i" | sed 's/#+title: *//'); done
+ for i in $(ls software | grep \\.org$ | grep -v "^vorlesung-verteilte-systeme.org\\|^guix-specified-package.org\\|^bsi-grundschutz.org\\|^language-empiric.org\\|^vorlesung-netztechnik.org\\|^p2p-talk.org\\|^decentralized-moderation.org\\|^kontaktinfos-mit-gnupg.org\\|^freenet-hidden-channel.org\\|^guix-work.org\\|guix-config.org\\|letterblock-diceware.org\\|^wisp.org\\|^enter-three-witches.org\\|^guile-10x.org\\|^guile-snippets.org\\|^guile-capture-stdout-stderr.org\\|^guile-fast.org\\|^zen-for-scheme.org\\|^shell-tricks\\|^python-snippets\\|^mercurial-branching-strategy.org\\|^emacs-javascript.org\\|^wisp-code-katas.org\\|^wisp-snippets.org\\|^advent-of-wisp-code-2021.org\\|^org-mode-tipps\\|^emacs-tipps\\|^package-guix.org\\|^programming-with-wisp.org\\|^programming-scheme.org\\|^programming-basics-wisp.org\\|^putins-kriegsrede.org\\|^install-on-guix.org\\|^package-guix.org\\|^org-mode.org\\|^emacs-daytime.org\\|^emacs-javascript.org\\|^intellij-emacs.org\\|^mercurial-ediff3-emacs.org\\|^orgmode-markdown.org\\|^ferienplan.org\\|^latex-awesome.org\\|^latex-list-of-links.org\\|^stundenplan-wochenplan-latex.org\\|^privacy-embed.org\\|^stream-over-freenet\\|^video-channel-hyphanet.org\\|^m3u-player.org\\|^find-dorktower.org\\|^ffmpeg-compression-vp9-av1.org\\|^comment-your-code.org\\|^gpl-or-later.org\\|^langsame-simple-werkzeuge.org\\|^slow-simple-tools.org\\|^optimize-for-firefox.org\\|^programs-you-can-still-hack-when-dumb.org\\|^tinkering-stability.org\\|^volatile-infrastructure.org\\|^typescript-risks.org\\|^hurd-authorization-translator.org\\|^keyboard-layout-evolution.org\\|^gamedev-notes.org" | sort -h); do echo '- [[file:software/'$i']['$(basename $i .org)']]' - $(grep '#+title:' "software/$i" | sed 's/#+title: *//'); done
#+END_SRC
#+toc: headlines 1
* *Why this?* How the writing of Starcraft 1 got so good
+:PROPERTIES:
+:CUSTOM_ID: why
+:END:
#+begin_kasten
*writers could tinker till the end*
Does it work out? Read on, then give it a try.
-* *Why like this*? Minimize ceremony by starting from theater scripts
+* *Why like this*? Minimize ceremony as theater scripts do
+:PROPERTIES:
+:CUSTOM_ID: why-like-this
+:END:
Code encodes intent. Since it is written not only for humans but also
for machines, it always sprouts some ceremony: structures and patterns
games.
* *Who can tinker?* Keep writers at the helm
+:PROPERTIES:
+:CUSTOM_ID: who-can-tinker
+:END:
The clear syntax makes it easy to create the text to be shown, but a
game is more than linear text. You need to ask questions and show a
To write branching stories, =define= plot fragments as indented text.
Each fragment is self-contained, so speakers have to =Enter= at the
start of it.
-
+#+latex: \clearpage
#+begin_src wisp :tangle enter-three-witches--branch.w
define : deeper
Enter : The Narrator
The Narrator
You step deeper into the forest.
- After several steps,
- gloom envelops you
- and the ground under your feet
- becomes softer.
+ After several steps, gloom envelops you
+ and the ground under your feet becomes softer.
thank-you ;; continue in thank-you
-
define : wait-or-deepen
Enter : The Narrator
-
The Narrator
Where do you want to go?
- Ask
+ Ask ;; ^ can use single empty lines for structure
: deeper into the forest
Say
As you continue, the shadows darken.
Enter : The Narrator
The Narrator
As you’re watching the forest,
- the sun sets,
- the light fades.
+ the sun sets, the light fades.
and you smell water.
thank-you ;; continue in thank-you
-
define : thank-you
Enter : The Developer
The Developer
Thank you!
-
wait-or-deepen
#+end_src
#+RESULTS:
[[file:enter-three-witches-branching-example.png]]
-* *How to convert existing stories?* Use the multi-file format for a simpler start
+* *How to convert existing stories?* Use the multi-file format
:PROPERTIES:
:CUSTOM_ID: multi-file
:END:
+
+
The simplified multi-file format follows the Speaker-heading pattern:
The first paragraph introduces the Speakers, then each paragraph
starts with a line containing only the speaker and ends with an empty
Example with two files: =welcome= and =about=.
-=welcome= with the speakers “Robert” and “Arne”:
+The file =welcome= with the speakers “Robert” and “Arne”:
#+begin_example
Robert
Arne
Robert
-It would be nice to be able to turn stories into playable websites
+It would be nice to be able to
+turn stories into playable websites
Arne
I hope this works for you!
exit
#+end_example
-=about= with the speaker “Textfiles Format”:
+The file =about= with the speaker “Textfiles Format”:
#+begin_example
Textfiles Format
#+begin_example
Robert
- It would be nice to be able to turn stories into playable websites
+ It would be nice to be able to
+ turn stories into playable websites
Arne
I hope this works for you!
3 Exit?
#+end_example
-You can customize the created game by editing
-=enter/textfiles-to-game-header.w= and
-=enter/textfiles-to-game-footer.w=.
-* TODO *How to stay in control?* Store outcomes and analyze your game to keep ahead of complexity
+You can customize the created game by editing the files
+- =enter/textfiles-to-game-header.w= and
+- =enter/textfiles-to-game-footer.w=
+* *How to stay in control?* Store and analyze outcomes
:PROPERTIES:
:CUSTOM_ID: control-complexity
:END:
+
+
You can now tell a path through a story with decisions that affect the
next fragment your reach, but a story is more interesting if there are
long-term consequences.
Enter three witches provides three ways to add consequences: outcomes,
-skills, and wounds.
+skills, and wounds. Outcomes are described here, skills and wounds
+are described in the section [[#beyond-storytelling][*Where can I go?* Beyond storytelling]].
But first: tracking outcomes over multiple fragments requires keeping
state and passing it from fragment to fragment.
To pass them along fragments, add the =state= after the fragment name.
It is an =argument= of the fragment.
+#+latex: \clearpage
#+begin_src wisp
define : into-the-void state
Choose
return a state, either by calling a fragment that returns the state or
via =,(game-state state)=.
-To check the state during writing, you can display it (but only after
+To check the state during writing, you can display it (only after
=Enter=):
#+begin_src wisp
By adding imports to the file itself, you can get an early warning
about such errors and fix them before they can hit your players.
-An example:
+A minimal example:
#+begin_src wisp
;; the imports
:END:
Outcomes make it easy to react to player decisions. Seeing that their
-decisions have an effect is one of the major motivations for playing
+decisions have an effect, [[https://selfdeterminationtheory.org/wp-content/uploads/2019/10/2008_PatallCooperRobinson_PsychBulletin.pdf][that their choice matters (Patall, Cooper,
+and Robinson, 2008)]], is one of the major motivations for playing
games.
But a story with outcomes can easily balloon in complexity, so most
visually which outcomes you added but did not (yet) use in a later
scene.
-Use the file =outcome.w= to see a plain text analysis:
+We’ll analyze the file =outcome.w= to see the a plain text version:
#+begin_src bash
enter/analyze.w outcome.w
#+end_src
-It shows the plot in *fragments*, *scenes* (currently no content:
-discussed in section [[#savegames][*How to continue?* Save and load savegames]]) and
-*outcomes*.
+It shows the plot in *fragments*, *scenes* (empty here, because they
+are discussed later: in section [[#savegames][*How to continue?* Save and load
+savegames]]) and *outcomes*.
#+begin_example
(Plot (Fragments investigate trace-the-cracks)
Let’s see that visually: create a diagram of the plot:
#+begin_src bash
-enter/analyze.w --plantuml plot.png outcome.w
+enter/analyze.w --plot-diagram plot.png outcome.w
#+end_src
-#+caption: example plot output: a legend (example-fragment with unused and pending outcomes, example-scene) and “investigate” leading to “trace-the-cracks”.
[[file:enter-three-witches--plot-outcome.png]]
+/This analysis uses [[https://plantuml.com/][plantuml]] to render beautiful plot diagrams./
+
Since in =outcome.w= all outcomes are used, the diagram shows no
unused or pending outcomes (pending outcomes will be discussed in
section
[[#scale-up][*How to scale up?* Split into chapters and use pending outcomes]])
-Make sure to use most outcomes in every branch of the the set-piece in
-which you introduce them. Only carry a limited number of consequences
-into the next set-piece to keep the complexity of the plot manageable.
-
To show how the diagram looks with unused outcomes, let’s build the
shell of a plot: only use outcomes and leave out the game content.
Write this into a file like =unused.w= and create the diagram:
#+begin_src bash
-enter/analyze.w unused.w --plantuml unused.png
+enter/analyze.w unused.w --plot-diagram unused.png
#+end_src
-#+caption: plot output with an unused outcome: the fragment =locked-door= has a footer with the content =unlocked-door=.
[[file:enter-three-witches--plot-unused.png]]
+You can see at a glance that you did not take up the outcome
+=unlocked-door= yet, so you can easily get an overview of all the
+outcomes in the plot you did not take care of yet.
+
The plain text output shows this, too:
#+begin_src bash
(Unused unlocked-door)))
#+end_example
-You can see at a glance that you did not took take up the outcome
-=unlocked-door= yet, so you can easily get an overview of all the
-outcomes in the plot you did not take care of yet.
-
-** TODO Adding skills and rules
-:PROPERTIES:
-:CUSTOM_ID: skills-and-rules
-:END:
-
-Character skills are values attached to names of people. They come
-with a ruleset which allows checking whether some action succeeds, and
-they can improve with usage or by increasing them manually.
-
-** TODO Adding battle and wounds
-:PROPERTIES:
-:CUSTOM_ID: rules
-:END:
-
-
-
-(long-term consequences, …)
+Make sure to use most outcomes in every branch of either the set-piece
+in which you introduce them or in the one following it. Only carry a
+small number of outcomes from set-piece to set-piece to keep the
+complexity of the plot manageable.
-* TODO *How to continue?* Save and load savegames
-:PROPERTIES:
-:CUSTOM_ID: savegames
-:END:
-
-** TODO Creating savegames with name and secret
-:PROPERTIES:
-:CUSTOM_ID: name-and-secret
-:END:
-
-To enable people to play your story in smaller parts and take breaks
-in between, or to make it easy to release a story in episodes, you
-need savegames.
-
-Saving a game and loading it later needs a name to identify the state.
-
-(ask for the name, print the name and the secret, load from name and secret)
-
-** TODO Defining scenes as savepoints
-:PROPERTIES:
-:CUSTOM_ID: define-scene
-:END:
-
-#+begin_src bash
-define-scene
-#+end_src
+As support for choosing the kinds of choices to offer, section 2.2
+/Background: Choices/ of [[https://www.diva-portal.org/smash/get/diva2:1683197/FULLTEXT01.pdf][Kappler and Mellquist, 2022 “Meaningful
+choices”]] gives a practical overview of different classifications in
+use.
* TODO *How to reach people?* Deploy your game
:PROPERTIES:
(smallest ionos server for 300 simultaneous users 2€/month, 600 for
3€)
-* TODO *How to scale up?* Split into chapters and use pending outcomes
+* TODO *Where can I go?* Beyond storytelling with rules and code
+:PROPERTIES:
+:CUSTOM_ID: beyond-storytelling
+:END:
+
+** TODO Adding skills and rules
+:PROPERTIES:
+:CUSTOM_ID: skills-and-rules
+:END:
+
+Character skills are values attached to names of people. They come
+with a ruleset which allows checking whether some action succeeds, and
+they can improve with usage or by increasing them manually.
+
+** TODO Adding battle and wounds
+:PROPERTIES:
+:CUSTOM_ID: rules
+:END:
+
+
+
+(long-term consequences, …)
+
+** TODO Executing arbitrary code
+:PROPERTIES:
+:CUSTOM_ID: code
+:END:
+(..., always validate and cleanup all user-input meticuloulsy before
+using it for anything)
+*** In the commandline-version
+:PROPERTIES:
+:CUSTOM_ID: code-commandline
+:END:
+*** In the webbrowser
+:PROPERTIES:
+:CUSTOM_ID: code-webbrowser
+:END:
+
+* TODO *How to continue?* Save and load savegames
+:PROPERTIES:
+:CUSTOM_ID: savegames
+:END:
+
+** TODO Creating savegames with name and secret
+:PROPERTIES:
+:CUSTOM_ID: name-and-secret
+:END:
+
+To enable people to play your story in smaller parts and take breaks
+in between, or to make it easy to release a story in episodes, you
+need savegames.
+
+Saving a game and loading it later needs a name to identify the state.
+
+(ask for the name, print the name and the secret, load from name and secret)
+
+** TODO Defining scenes as savepoints
+:PROPERTIES:
+:CUSTOM_ID: define-scene
+:END:
+
+#+begin_src bash
+define-scene
+#+end_src
+
+* TODO *How to scale up?* Split into chapters and pending outcomes
:PROPERTIES:
:CUSTOM_ID: scale-up
:END:
visible in the plot diagram until you checked them in all branches of
the plot)
-* TODO *Where can I go?* Beyond gamebooks
-:PROPERTIES:
-:CUSTOM_ID: beyond-gamebooks
-:END:
-
-** TODO Executing arbitrary code
-:PROPERTIES:
-:CUSTOM_ID: code
-:END:
-(..., always validate and cleanup all user-input meticuloulsy before
-using it for anything)
-*** In the commandline-version
-:PROPERTIES:
-:CUSTOM_ID: code-commandline
-:END:
-*** In the webbrowser
-:PROPERTIES:
-:CUSTOM_ID: code-webbrowser
-:END:
-
* TODO *How to …?* Common solutions (FAQ)
:PROPERTIES:
:CUSTOM_ID: faq