+1 vote
by (130 points)

I usually write small amounts of feedback initially and a LOT of code. With the debug view on it's quite hard to see the text output because of the code showing. Using the debug on/off in the sidebar doesn't survive a F5 on the browser and I use F5 a lot because I use random events quite often.

So - to get the debug view to show only when I see an error (like Colonel Mustard stabbing the cook in the library with the rope) I have used DebugView.disable() on every page to suppress the initially active debug view but I wonder if there is maybe a better alternative to that.

So - is there a way to disable debug view by default so that it survives a browser F5 other than including DebugView.disable() on every page?

2 Answers

0 votes
by (63.1k points)
Did you remove the default UI? There's a button at the top of the UI bar that disables it.
by (130 points)
If you mean the green Button saying "Debug View" with a little bug on the left side ... yes. As I said - the problem is F5 on the browser as this will reset it to on.
by (63.1k points)

Sorry, I missed that somehow.

Here's a few options:

1. PassageReady

Create a passage and name it 'PassageReady', then place the following code in it:

<<run DebugView.disable()>>

2. Task Objects

Put this code in your story's JS:

predisplay['debug-disable'] = function (taskName) {

All things being equal, I'd use the task object.  Wrap it in comment syntax ( /* ... */ ) when you want it off.

I tested both options, both survive an F5.

by (130 points)
Ah, thanks - works like a charm. I *was* thinking predisplay might do the trick but I couldn't (and can't) for the life of me figure out how to use it :)

In your working example ... 'debug-disable'  is made up and can be replaced by anything - so no real official task-name needed, got that.

What I can't understand is the function(taskName) part. I assume that there are multiple tasks that can cause this function to be called and I pass it on as parameter though I am not making use of it?

If so - is there a list which "taskName"s are in use by Twine and Sugarcube?
by (63.1k points)
edited by

It's way less arcane than you seem to think.  The task objects are JavaScript objects (variables with variables inside of them--we call these internal variables 'properties', usually).  You can pass entire functions as variables in JavaScript, so when a new passage transition starts, each function inside of each task object is called.  From SugarCube's source code:

Object.keys(postdisplay).forEach(function (task) {
	if (typeof postdisplay[task] === 'function') {
		postdisplay[task].call(this, task);
}, passage);

And so on for each task in it's proper place.

So the code that creates a function in a task object creates a new property on the relevant object and assigns a function to it.

predisplay['name'] = function (taskName) {...};
// creates new property on the predisplay object called 'name' and assigns it an anonymous function

Functions can be called with arguments, and task objects are always called with an argument referencing the task's name.  This allows you to manipulate the task object in certain ways; for example, it allows you to delete tasks or create single use tasks:

predisplay['name'] = function (taskName) {
    delete predisplay[taskName]; // single-use task
    console.log('this task happens only once');

predisplay['name'] = function (taskName) {
    console.log('this task happens 10 times (assuming $var starts at 0)');
    if (State.variables.var > 10) {
        delete predisplay[taskName];
        // delete task after tenth time it's called
    } else {

You also don't have to use the variable taskName to store the task's name in the function:

predisplay['name'] = function (x) {
    delete predisplay[x];
    console.log('this is predisplay task ' + x);

However, I'd recommend using taskName because

  1. It's what the documentation uses.
  2. It's what everyone else uses.

You can get an array of any object's properties via the Object.keys() standard JavaScript method, by passing the name of the task object you want to look at to the method:

<<set $taskKeys to Object.keys(predisplay)>>
<<print $taskKeys.join(', ')>>

By default, all the task objects are empty, so you can use any names you want. 

Note: I didn't test any of  this code, so it's possible that there are errors in it.

by (130 points)
And you call this "less arcane" ... I'm still giggling :)

Bunch of thanks for all that input. I actually NEVER thought of dumping output to the console from within scripts ... now, that has given me a couple of ideas to play with.

Perfect answer + perfect solution

Thanks again!
0 votes
by (68.6k points)

Assuming you haven't removed/hidden the UI bar, the following JavaScript should do what you need by creating a test mode setting in the Settings menu: (Twine 1: goes in script-tagged passage; Twine 2: goes in Story JavaScript)

    Debug Settings.
(function () {
    Setting.addHeader("Debug Settings");

    function initSettingDebug() {
        Config.debug = settings.debug;
    Setting.addToggle("debug", {
        label    : "Enable test/debug mode?",
        default  : false,
        onInit   : initSettingDebug,
        onChange : function () {

Obviously, you will probably want to remove/disable that for public releases.