Update 2020: In Dryads Wake I am starting a game using the way presented here to write dialogue-focused games with minimal ceremony. Demo: https://dryads-wake.1w6.org
Update 2018: Bitbucket is dead to me. You can find the source at https://hg.sr.ht/~arnebab/ews
Update 2017: A matured version of the work shown here was presented at FOSDEM 2017 as Natural script writing with Guile. There is also a video of the presentation (held by Chris Allan Webber; more info…). Happy Hacking!
Programming languages allow expressing ideas in non-ambiguous ways. Let’s do a play.
say Yes, I do!
Yes, I do!
This is a sketch of applying Wisp to a pet issue of mine: Writing the story of games with minimal syntax overhead, but still using a full-fledged programming language. My previous try was the TextRPG, using Python. It was fully usable. This experiment drafts a solution to show how much more is possible with Guile Scheme using Wisp syntax (also known an SRFI-119).
To follow the code here, you need Guile 2.0.11 on a GNU Linux system. Then you can install Wisp and start a REPL with
wget https://bitbucket.org/ArneBab/wisp/downloads/wisp-0.8.6.tar.gz
tar xf wi*z; cd wi*/; ./c*e; make check; guile -L . --language=wisp
For finding minimal syntax, the first thing to do is to look at how such a structure would be written for humans. Let’s take the obvious and use Shakespeare: Macbeth, Act 1, Scene 1 (also it’s public domain, so we avoid all copyright issues). Note that in the original, the second and last non-empty line are shown as italic.
SCENE I. A desert place.
Thunder and lightning. Enter three Witches
First Witch
When shall we three meet again
In thunder, lightning, or in rain?
Second Witch
When the hurlyburly's done,
When the battle's lost and won.
Third Witch
That will be ere the set of sun.
First Witch
Where the place?
Second Witch
Upon the heath.
Third Witch
There to meet with Macbeth.
First Witch
I come, Graymalkin!
Second Witch
Paddock calls.
Third Witch
Anon.
ALL
Fair is foul, and foul is fair:
Hover through the fog and filthy air.
Exeunt
Let’s analyze this: A scene header, a scene description with a list of people, then the simple format
person
something said
and something more
For this draft, it should suffice to reproduce this format with a full fledged programming language.
This is how our code should look:
First Witch
When shall we three meet again
In thunder, lightning, or in rain?
As a first step, let’s see how code which simply prints this would look in plain Wisp. The simplest way would just use a multiline string:
display "First Witch When shall we three meet again In thunder, lightning, or in rain?\n"
That works, but it’s not really nice. For one thing, the program does not have any of the semantic information a human would have, so if we wanted to show the First Witch in a different color than the Second Witch, we’d already be lost. Also throwing everything in a string might work, but when we need highlighting of certain parts, it gets ugly: We actually have to do string parsing by hand.
But this is Scheme, so there’s a better way. We can go as far as writing the sentences plainly, if we add a macro which grabs the variable names for us. We can do a simple form of this in just six short lines:
define-syntax-rule : First_Witch a ... format #t "~A\n" string-join map : lambda (x) (string-join (map symbol->string x)) quote : a ... . "\n"
This already gives us the following syntax:
First_Witch When shall we three meet again In thunder, lightning, or in rain?
which prints
When shall we three meet again
In thunder, lightning, or in rain?
Note that :
, .
and , are only special when they are preceded by
whitespace or are the first elements on a line, so we can freely use
them here.
To polish the code, we could get rid of the underscore by treating
everything on the first line as part of the character (indented lines
are sublists of the main list, so a recursive syntax-case macro can
distinguish them easily), and we could add highlighting with
comma-prefixed parens (via standard Scheme preprocessing these get
transformed into (unquote (...))
). Finally we could add a macro for
the scene, which creates these specialized parsers for all persons.
A completed parser could then read input files like the following:
SCENE I. A desert place. Thunder and lightning. Enter : First Witch Second Witch Third Witch First Witch When shall ,(emphasized we three) meet again In thunder, lightning, or in rain? Second Witch When the hurlyburly's done, When the battle's lost and won. ; ... ALL Fair is foul, and foul is fair: Hover through the fog and filthy air. action Exeunt
And with that the solution is sketched. I hope it was interesting for you to see how easy it is to create this!
Note also that this is not just a specialized text-parser. It provides access to all of Guile Scheme, so if you need interactivity or something like the branching story from TextRPG, scene writers can easily add it without requiring help from the core system. That’s part of the Freedom for Developers from the language implementors which is at the core of GNU Guile.
Don’t use this as data interchange format for things downloaded from the web, though: It does give access to a full Turing complete language. That’s part of its power which allows you to realize a simple syntax without having to implementent all kinds of specialized features which are needed for only one or two scenes. If you want to exchange the stories, better create a restricted interchange-format which can be exported from scenes written in the general format. Use lossy serializiation to protect your users.
And that’s all I wanted to say ☺
Happy Hacking!
PS: For another use of Shakespeare in programming languages, see the Shakespeare programming language. Where this article uses Wisp as a very low ceremony language to represent very high level concepts, the Shapespeare programming language takes the opposite approach by providing an extremely high-ceremony language for very low-level concepts. Thanks to ZMeson for reminding me ☺
Anhang | Größe |
---|---|
2015-09-12-Sa-Guile-scheme-wisp-for-low-ceremony-languages.org | 6.35 KB |
enter-three-witches.w | 1.23 KB |
Use Node:
⚙ Babcom is trying to load the comments ⚙
This textbox will disappear when the comments have been loaded.
If the box below shows an error-page, you need to install Freenet with the Sone-Plugin or set the node-path to your freenet node and click the Reload Comments button (or return).
If you see something like Invalid key: java.net.MalformedURLException: There is no @ in that URI! (Sone/search.html)
, you need to setup Sone and the Web of Trust
If you had Javascript enabled, you would see comments for this page instead of the Sone page of the sites author.
Note: To make a comment which isn’t a reply visible to others here, include a link to this site somewhere in the text of your comment. It will then show up here. To ensure that I get notified of your comment, also include my Sone-ID.
Link to this site and my Sone ID: sone://6~ZDYdvAgMoUfG6M5Kwi7SQqyS-gTcyFeaNN1Pf3FvY
This spam-resistant comment-field is made with babcom.