EDIT: fixed bugs
Taking a look at some of the code behind Squiffy, I wonder if there's a neater way to make passages work. Changing the function to something like this might make some easier stuff possible:
squiffy.story.passage = function(passageName) {
var masterSection = squiffy.story.sections[''];
var passage = squiffy.story.section.passages[passageName];
if (passage) {
// This is the function `setSeen`; which is local so needs to be copied
// into this code. I think it might be better to remove this, but it's
// in the original code
var seenSections = squiffy.get('_seen_sections');
if (!seenSections) seenSections = [];
if (seenSections.indexOf(passageName) == -1) {
seenSections.push(passageName);
squiffy.set('_seen_sections', seenSections);
}
} else if (masterSection && masterSection.passages[passageName]) {
passage = masterSection.passages[passageName];
} else {
return;
}
var passages = [passage];
var masterPassage = masterSection && masterSection.passages[''];
if (masterPassage) {
passages.push(masterPassage);
}
var master = squiffy.story.section.passages[''];
if (master) {
passages.push(master);
}
$.each(passages, function (i, p) {
squiffy.story.run(p);
});
$.each(passages.reverse(), function (i, p) {
squiffy.ui.write(p.text);
});
squiffy.story.save();
};
A few things changed here. The order of operations changes for master passages. Basically, the scripts run and then the test is displayed, rather than sctipt-text-script-text.
And secondly, a passage in the master section can be called from anywhere, if the section doesn't have a passage with the same name. So you could have stuff like links to [inventory]
, [stats]
, or [help]
in the master section and those links will then work anywhere in the game.
It needs to run before any links that use it. I'd suggest at the start of the game; but then I'm not sure how that will interact with loading saved games. You could put it in the master section; it would be inefficient, but probably not enough to be noticeable.
OK, I tested it myself now, putting it in the master section.
Corrected two variable names in the code above (careless typo, my phone isn't good at capitals), and included the body of the function setSeen
because it can't be called from user code.
Works for me now :)
The passage works:
[[]]:
<button onclick="window.story.passage('inventory');">Inventory</button>}
[inventory]:
You have Gold x {gold}
But to avoid my header [] being filled up with lots of passages as I add buttons into the header, would it be better to use sections outside of it? I get the sections to run, but then I don't know how to "return" to the original section:
[[]]:
<button onclick="window.story.go('inventory');">Inventory</button>}
[[inventory]]:
You have Gold x {gold}
[[section 1]]:
Section 1 appeared, player pressed inventory, once completed, how do I get control back here?
So they can now go to [[section 2]]
but then I don't know how to "return" to the original section:
You can only be in one section at a time. If you want to be able to click a link and do something but then go back, you need to use passages.
By default, passages have to be inside the current section. My modification makes it so that passages can be inside the current section or the master section.
I'm not sure why doing it with passages would be a problem. The code looks virtually the same whether it has single or double [brackets] in.
But, if you really want to do it that way, you could change:
} else if (masterSection && masterSection.passages[passageName]) {
passage = masterSection.passages[passageName];
to:
} else if (squiffy.story.sections[passageName]) {
passage = squiffy.story.sections[passageName];
This would mean that you can now use passage links that point to a section.
So, using window.story.go('inventory')
or [[inventory]]
will go to the inventory, and disable all other links to the current section.
But using window.story.passage('inventory')
or [inventory]
will display the inventory section, without changing the current section, and without disabling any links currently on the screen.
Is that what you were looking for?
(If there is a passage with that name, the behaviour will be as default. This modification just causes Squiffy to treat a section as a passage if the passage isn't found)
I'm not sure why doing it with passages would be a problem.
It might be my design or simply my understanding. I plan on having several buttons in the master section so they are always available so people can eat, inventory, take a potion etc. at any time regardless of the actual section they are in. Is this the best way to do this - is it good practice to do it that way, and then using your script, is it ok to have several large passages in the master section to be called by them? i.e. they are always going to be "referred to" (although ignored unless button pressed) every new section as the master is called every time?
is it ok to have several large passages in the master section to be called by them?
Efficiency wise, it could go either way. I can't see any problem having a section containing a large number of passages. It's like putting a bunch of files into a folder.
What I understand from looking at the code is that passages are designed to be things that you look at, while sections are things you go to. Squiffy keeps track of the 'current section', and once that changes all links in the old section are no longer usable. A passage doesn't affect what section you're in, and there is no concept of a current passage. You can look at a whole bunch of passages one after another, and all the links will remain active until you leave the section.
From this understanding, it seems that stuff the player can do anywhere is more like a passage than a section.
But, with the code above you could do it either way. Even include both if you want to. So you can structure your game whichever way is easier for you to understand.
mrangel, I agree. These would be extremely helpful changes to the next version.