Twine Integration Guide
toggle TOC (ctrl + ⇔)
This guide is for integrating DAD into a Twine game (with the SugarCube 2 story format). You should read this while going through the demo (download it and Import From File inside Twine). For more general tips, refer to the usage guide.
A caveat is that I'm not a SugarCube expert, so there are probably better ways to do some things. Take a look at Twine sample code and the SugarCube reference for help.
Requirements ¶
- SugarCube version 2.31.x or newer
- DAD version 1.28.x or newer.
Recommended setup ¶
You can either work inside Twine 2 (the app), or compile the story from external files using Tweego. I recommend the second option for reasonably sized projects because the text editor inside Twine is not great… You might resort to doing the editing in something else (e.g. WebStorm, sublime) and copying it back to test, but this makes debugging slow.
However I will explain things assuming you are working inside the Twine app since it's the easiest way for you to get started, and there aren't that many differences.
Components ¶
There are 2 major components of interactivity to a Twine game
- Story JS
- runs at the start of the story
- defined at the start in a special place
- can create macros for use inside TwineScript
- has to access the state through the
State
API likeState.variables.PC
- TwineScript
- runs when you play the passage
- embedded in the passages
- can only use macros, but
<<run {pure JS}>>
and<<script>>{pure JS}<</script>>
allows you to run pure JS - can access the state directly through special syntax like
$PC
Unless something is easier to do in TwineScript, I recommend implementing it in JS because it could be reusable outside of your story, or if you decide to switch story formats.
Import ¶
The first thing is to import the da
module.
The simplest method is through the importScripts
function near
the start of your Story JS after including other external libraries like:
This has the advantage of always pointing to the latest version of DAD, but you may not want that.
If you want a specific version, you can download dist/da.js
from the
repository by searching
the history for the commit, like "1.29.1".
You would then copy the content of that to the top of story javascript.
Note that the da
module is placed in the global frame so you can refer to it in TwineScript like
<<run da.{...}>>
.
Alternatively, you can clone the DAD repository (or as a submodule) and either import the latest
dist/da.js
, or directly from source as modules such as
import {...} from "dynamic-avatar-drawer/src/player/player.js"
and bundle everything together with webpack.
This has the advantage of allowing an IDE (like WebStorm) to make coding a lot easier.
I recommend you create assets directly as modules inside src/clothes
. This allows you
to make pull requests to share your templates with other people.
Before Loading ¶
Code extending the library should be placed before da.load()
. As seen above, it should be
placed at // extend the da module here
. See the extension guide and
the demo's code for what to do. Patterns can also be defined here as
Which you can later specify as the color for fill
, stroke
, and similar properties like
Which would translate to TwineScript inside a passage like
<<set _belt = da.Clothes.create(da.SimpleBelt, {
fill: da.getPattern("red plaid", 100),
});>>
<<run $PC.wearClothing(_belt)>>
After Loading ¶
We can now get canvas groups for drawing. In the demo, properties of drawing the PC is stored
in settings
, which is saved across sessions, but you can put it somehwere else.
You might also want to look at focused windows for drawing
high resolution portraits for dialogs.
Outside Loading ¶
You can place methods here that don't depend on immediately having access to da
properties.
The most standard function would be something like drawToMenu(PC)
in the demo. These functions
have to be attached to window
to be usable inside passages, so define them as
Placing Canvas Group ¶
If you want to relocate the canvas group, first you have to choose an existing DOM element as the parent. To help with that, you can open developer tools (F12 for chrome) and click on the arrow icon to the left:
This lets you mouse over elements on the page
For example here we see that this DOM element has ID "menu" and is of type nav
(we can ignore this).
If we want to place the drawing canvas inside this group, we'll change the StoryJS around lines 107:
To
If instead we want to place the canvas above the menu, we can do this: (the menu and the canvas are siblings under the same parent "ui-bar-body")