-
Notifications
You must be signed in to change notification settings - Fork 5
The Stormrose TwineQuest Proposal
A plugin architecture for extending TwineQuest
This proposal covers a proposed plugin architecture for future TwineQuest extensions.
The twine macro system is not ideally suited for creating plugins.
- There is no defined way to share data between macros
- The syntax of macro parameters is not well defined
- The double triangle brackets are visually ugly which disturbs authoring
- There is no control over initialisation order so dependency control is difficult
- There is significant boilerplate
- Explicitly declaring objects in <> macros adds ickiness to authoring
- StoryFormat independent (as far a practicable)
What's great about Twine?
- Passages
- Passage tags These are great because authors already understand them.
TwineQuest.twee should contain useful code to make the life of TwineQuest plugin authors easy.
Code to register the plugin in the correct order, deliver passages related to the plugin, decode the data in those passage, call the plugin when it is activated in text. These things are all controlled by the TwineQuest core system.
As little as is useful should be in core TwineQuest.twee - as much as possible needs to be optional and even replaceable.
So we use plugins. Some plugins are "official" but authors are always encouraged to contribute their own.
The InterTwine system can link to TwineQuest plugins
TwineQuest makes extension use of the StoryIncludes passage to link to the TwineQuest plugins. StoryIncludes is simply a list of .twee or .tws formatted files to load into a Twine story before it is built. Currently StoryIncludes can load files from a local filesystem or over the internet by listing a URL.
Initialising data
TwineQuest works by looking for passages with special "tq.*" tags. Even TwineQuest plugins are added in this manner. Each plugin may register a tag and the TwineQuest system will then find passages with that tag and deliver them to the plugin for processing. This means that authors can initialise TwineQuest objects simply by creating a tagged passage with data inside.
Simple Data Syntax
TwineQuest data may use attribute-colon-newline syntax. This eliminates the need for messy quotes, brackets, braces and other things that don't look at all writerly. The TwineQuest core contains a utility function for converting this format into javascript objects. Plugins can use this to easily parse passages.
Consistent data store
TwineQuest objects should store their data in the regular Twine variable store. This makes the data accessible to Twine macros and makes debugging stories easier.
TwineQuest has a loose definition of object.
Objects are generally created by plugins and stored in the Twine variable store as javascript objects. This makes them accessible by Twines <>, <> and <> macros.
A TwineQuest object will have an id attribute which is also typically the TwineQuest label, the Twine variable name and the javascript object name stored in the Twine variable store. The id will normally come from the passage title that the object was created from by a plugin but this can be overridden by using the id: someid syntax inside the passage.
Labels are the basic syntactic unit. TwineQuest associates labels with a callback function which is called whenever the label is encountered inside {curly brackets}. Most plugins will want to register a label per object they create. For example each monster will need a different label. Labels can accept parameters which are separated by spaces (just like twine macros). By default, a label that is for an object and has zero parameters, should return a textual label for the object. For example; {Axe1} might display "Large Axe". Labels are not required to map to objects; they can also just be commands. In this mode they act just like Twine macros. When curly brackets are parsed by TwineQuest, first the registered labels are checked and then the callback activated. If no label is present then TwineQuest will attempt for find an ordinary Twine variable with the same name. Therefore {curly bracket syntax} can also be used as a shortcut for a simplified version of the Twine <> macro.