By FAQ, I mean FAQTIA. Frequently asked questions that I ask.
1 - How does one 'install Sugarcube' for their game?
2 - Will it have any unpleasant side effects for my currently-made project?
3 - I'm told there is a saving feature and I'd really love to implement that in my game. Is that true? If so, how do I implement it?
4 - Not related to Sugarcube: How can I implement macros in my game? I read somewhere that some guy got his game to play music in the background during a passage.
5 - What can Sugarcube do that the default layouts can't?
Keep in mind I have no idea what Sugarcube is, just that it's a layout that does a lot of nice stuff.
Comments
In your Twine installation, in the "target" directory, create a subdirectory named "sugarcube". In that subdirectory, place the SugarCube "header.html" file.
Installing it will not affect any of the other story formats. Projects will continue to use the same story format as before unless you manually switch them.
If you switch your project to use SugarCube instead of the story format it was using originally, there are some differences you should look out for. They are mentioned in the SugarCube documentation. Among others, make sure your variables are initialized before you use them, the current state in JavaScript is named differently and a few CSS selectors are different.
I don't know if you'd love it, but I certainly do
All you have to do is select SugarCube as the story format for your game, then you automatically get the save feature.
Macros are added by fragments of JavaScript. There are some ready-made macros that people like to use, for example from Leon's blog.
The save feature that you already mentioned. Random number generation that is consistent across back/forward and saves. Defining widgets, which is like a simpler version of macros (less powerful but also a lot easier to create). It also has some useful macros and JavaScript functions built-in, see the documentation for details.
It looks a lot like SugarCane, but it has more features.
The code I used:
<<textinput "$name" "cac2" "Enter">>
What I got in the game:
[IMG]http://i.imgur.com/YtOU8Cd.png[/img]
~
Stats menu, hitting back should return you to the previous passage.
The code I used:
[[Back|previous()]]
What I got in the game:
[IMG]http://i.imgur.com/AmKp6cG.png[/img]
Then...
[IMG]http://i.imgur.com/cihTJ3W.png[/img]
EDIT: Found out what I was doing wrong with the textinput. Instead of...
<<textinput "$name" "cac2" "Enter">>
It needs to be...
<<textbox "$name" " " "cac2">>
I wouldn't use a space as the default argument, unless that's actually what you want. You can simply use the empty string: Additionally, if you also wanted an "Enter" button (which you don't need,
<<textbox>>
updates live and supports the Enter/Return key), you could add one like this: There's also a non-built-in version of the<<textbox>>
macro on SugarCube's website, under Extras, which includes a button argument, but simply using the<<button>>
macro (as shown above) works just as well.Use the
<<back>>
or<<return>>
macros. They're functionally equivalent except in how they modify the history.
In this case, IIRC, the equivalent to<<back>>
: Goes back by popping the history stack, essentially undoing the popped state(s). It's like using your browser's Back button.<<return>>
: Goes back by pushing the destination state onto the history stack. It's like following a link to the destination state.[[Back|previous()]]
would be: Simply using<<return>>
would make the link text "Return".Alternatively, if you wanted most/all of your
<<return>>
calls to have the same non-default link text, you could do this in yourStoryInit
special passage: Then simply using<<return>>
would make the link text "Back".That said, if you're using this on some kind of statistics display passage and that passage doesn't modify the game state at all (i.e. it's only to display the stats), then you may be better off using the
<<back>>
macro instead.One last question, once again unrelated to Sugarcube. Macros - I've seen people paste a macro that allows YouTube videos to play in the background, usually music.
Can anyone provide a step-by-step tutorial on how to implement such a thing? It would really bring about a great atmosphere to my game.
1. Contains two links to articles (with code) on how to do sound. (local file and youtube)
http://twinery.org/forum/index.php/topic,1586.msg3436.html#msg3436
2. Contains simple steps explaining the local file type in point 1.
http://twinery.org/forum/index.php/topic,1586.msg3455.html#msg3455
3. Simple change required to make code in point 1 compatible with SugarCube.
http://twinery.org/forum/index.php/topic,1593.msg3541.html#msg3541
Searching Forum is your friend. lol
I asked for step-by-step but I can try to make sense of all these links...
EDIT: Yeah these aren't clear directions. I'm getting errors.
EDIT: I don't even know what a macro is, all I want is to play hidden YouTube videos in my game and I'm getting so much weird stuff and
One question though: What should I do to insert a given macro/widget in every passage body?
As I've read, Sugarcube is able to access any element on the page, but I not familiar with html, and css enough to figure out how...
I'm going to assume that you're not simply talking about how to call a macro/widget within a passage, but that there's some macro/midget you want called for every navigated to passage. If that's the case, the obvious answer is to simply call the macro/widget within each passage, but I assume you'd rather avoid all that boilerplate.
That leads me to some questions: Do you either simply want the macro/widget called or do you want it called and its output inserted somewhere into the passage? Assuming the latter, where do you want the output inserted at? First thing at the top, last thing at the bottom, or either somewhere in-between or in a variable location? The first two could be done without a target element, though you could use one if you chose, the latter would require one.
Okay, to be more specific: I've read in this topic (http://twinery.org/forum/index.php?topic=763.0) a method to insert a new element on a page using the replace macro. My question is how the passage content itself can be modified using a similar approach.
So let's assume I have these passages: And I want the inventory widget to get included in every passage's body, before (or after) the passage content. I.e. I want passages to get displayed as if they would look like this: but without manually inserting the inventory widget in every single passage's body. Can this be done in Sugarcube?
Yes.
Prepend the inventory (before): Append the inventory (after): Now, both of those will add the content to every normally rendered passage. If you only want the
<<inventory>>
content added to some subset of those passages, then you'll need a little extra code.Yes, I guess that might be necessary, but I guess that part can as well be handled within the widget itself by using some conditional parts for tags and whatnot.
Thanks for the help again!
Yes. As a simple example, here's a prepend version which produces no output if the passage is tagged with
hideinventory
: I suppose I should also mention that, for what you're doing here, you could just as easily display an entire passage for your inventory instead of a widget. For example: Six of one, half-a-dozen of the other.No, it doesn't currently, you aren't missing anything. Why do you want the title of the previously visited passage (yes, the reason is important to my answer)?
For instance, the primarily purpose of
previous()
in the vanilla headers is for use in constructs like[[Back|previous()]]
, which link back to the previously visited passage. If you wanted it for a reason like that, then you probably don't need it, simply use<<return>>
or its history undoing sibling<<back>>
(which one would depend on how you want the link to work; the equivalent to[[Back|previous()]]
is<<return "Back">>
).If you wanted it for some non-navigational reason, then you can get the title of the immediately previously visited passage like so: (assuming there is one!) [EDIT] Updated the code.
Thanks again for the quick answer! Keep it up, man!
You have been teleported temporarily to the treasure cave! There's lots to do here!
<<set $returnhere to {state.peek(1).title}>>
// lots of other choices...
Go back where you [[came from|$returnhere]]
Like that?
On to your question. If "lots of other choices" means that the player will be navigating to an arbitrary number of other passages (e.g. via
<<actions>>
, links, or whatever), then yes you'd need something like that. Though setting the return location is generally done on the passage you want to return to and not a later passage (e.g.[[Step into the portal|Treasure Cave][$returnLoc to passage()]]
). Maybe that's not possible with your setup though. /shrugAs to your code. It's almost correct, however, you have some spurious curly braces in there, it should look like:
I need to set where to return to because I'm hoping to have an inventory link in the sidebar, so there is no way to predict from where or when the player clicked it, thus I need to keep track of the Previous passage. Similarly I have an item that lets someone teleport to a location, and I'd like to be able to replace them when they're done.
My next question --
Oh, hi everyone, by the way. I didn't introduce. I tend to lurk and then burst into full activity like the baby alien in John Hurt's chest.
-- It was sort of asked earlier in the thread, and I don't know if this is a Sugarcube issue or Twine issue. I want to have a game clock that can cause things to happen in the story. Say if the count gets to six, the sun sets. I have no problem running a silent passage in the StoryTitle or wherever, but I didn't think about how to get the text of what happens into the main window. Is there a way to direct text from the sidebar to the main passage?
This also applies to my inventory sidebar thing too...I'd like when the player clicks Inventory that they get a list of items in the main window that they can then interact with, and then return where they were by way of the state.peek trick above.
Firstly, please don't use
StoryTitle
. SugarCube uses the story's title as the basis for the key used to store and load data used when playing the story and for saves. Because of this, the story title is not included in updates and it is strongly recommended that you do not add any kind of dynamic code to it.Secondly, don't use the other UI passages for this either, there are better passages for such work. As I noted in another thread (likely the one you're thinking of), in SugarCube I'd suggest using
PassageReady
/PassageDone
for such things (or theprerender
/postrender
task objects).And the answer is, yes, there are a multitude of ways to get content into the main passage container. Where do you want this content to appear (yes, that's important)? It can be prepended to the top, appended to the bottom, or injected into (or around) a selectable (probably, container) element that's part of the normal content. The sky's virtually the limit here, so you need to narrow things down a bit. Also, what are you wanting added? Just some text or something more grandiose?
If you're needing to return, then it's because you've navigated to another passage. If that's the case, simply list your items in (and, importantly, from) that passage. I'm not understanding the issue here.
As far as the timer, my idea is that there's a general passage of code that increments the time, and then can also trigger things based on the time, or based on other variables. For example if the timer gets to "morning" I'd like to display a passage that says "The sun is rising" as part of the main window text...end or beginning...wherever seems the most appropriate. If the player is wounded, (for example) this timing passage will also count how many turns the player has been bleeding and provide appropriate messages mentioning this.
I don't know what PassageReady/Done really does...I'm guessing PassageReady does things before displaying the text and PassageDone does things after displaying the text? Is there way I can put my time-management stuff in PassageReady and then have the main text displayed, and then PassageDone add remarks like "You've been bleeding a while, by the way, you might want to find a bandage." ...or something.
Let me explain how I do this inventory-time thingy and maybe you can use it also (or propose a better solution).
The basic concept is that I mark passage types with tags. A passage can be an entrance of an area (tagged:area) leading to multiple rooms, it can be a room (tagged: room) within that area, it can be an object's description (tagged:object) or anyhting else. I have a variable called $current to track the status of all those types so the setup is something like this: Now every time the player goes to a passage tagged with , the $current.room variable gets updated. Knowing this I can define a passage called Inventory or Menu and put this link at the end of it: it will always lead the player back to the latest room passage he was in.
You can also insert your timer logic in PassageReady and update the time every on every passage transition. When combining this with the prerender-postrender stuff TheMadExile described earlier, you can have a setup like: Yes, you're right about PassageReady doing stuff before rendering the passage and PassageDone after that, but note, that you can't insert text into the passage itself with them. You need the prerender-postrender trickery to do so.
Got it in one.
[quote="SugarCube docs Reserved & Special Names Passage Names"]
PassageReady
: Used for pre-passage-rendering tasks, like redoing dynamic changes (happens just before the rendering of each passage).PassageDone
: Used for post-passage-rendering tasks, like redoing dynamic changes (happens just after the rendering of each passage).They and the
prerender
/postrender
task objects are similar in that they both allow you to do dynamic things around the display of a passage (by navigation, the<<display>>
macro does not trigger these). The main differences being:
The order of execution typically looks something like this:PassageReady
/PassageDone
are passages, whileprerender
/postrender
are JavaScript objects used as repositories of functions (which I generally refer to as tasks).PassageReady
/PassageDone
are executed before/after the passage is rendered, while the functions within theprerender
/postrender
objects are called during passage render, just before/after the passage content is generated.[list type=decimal]
State history updated for the incoming passage
PassageReady
executed, if not rendering "offscreen
"Incoming passage is rendered
[list type=upper-alpha]
prerender
tasks calledIncoming passage content generated
postrender
tasks calledTransition from outgoing passage to incoming passage, if not rendering "
offscreen
"PassageDone
executed, if not rendering "offscreen
"Update the UI elements, if not rendering "
offscreen
"Now you know. And knowing is half the wait, my '80s is showing.
Yes, certainly. You can use the DOM (Content) macros within
PassageDone
to prepend and/or append your dynamic content to the main passage container. If needed, you can even add target elements into a passage's content, so that once it's rendered you'll have targets which you can select to inject content into arbitrary areas of the main content area, rather than simply prepending/appending to it.As a contrived example, to handle time of day and bleeding messages, you might do something like this in
PassageDone
: n.b. The content additions are ordered in the reverse of how they're displayed to the player, since all of the additions are prepends in the example.You have a couple of issues with your examples there:
1. This has the
prerender
object's name title-capped and you're nesting the same type of quotes: Don't do either of those. Case is important,prerender
should be in all lowercase, and don't nest the same type of quotes, at least not without encoding them.It should be something like this:
2. This has spurious single quote in the
<<if>>
and you don't need to<<print>>
a plain string literal: It should be something like this: Tip: Keep an eye on your whitespace usage, particularly line-breaks, as they are copied to the output (e.g. the above adds a line-break before "The sun is rising", which may be unwanted).That's not entirely accurate. You are (essentially) correct about
PassageReady
, however,PassageDone
most certainly can manipulate the main passage area and the content within. It doesn't have a direct reference to the content container likeprerender
/postrender
do, no, but you can easily select the main passage container element via the selector ".passage .content
" (among many others) and go from there (with the DOM (Content) macros or JavaScript, with or without jQuery). As shown in my previous reply to this thread.I'm a little lost on concepts like "boilerplate" and 'wikifier", so perhaps I'm reaching a bit too far out of my ability level to try and do any type of story this complicated in Twine/Sugarcube. I will experiment with these more extensively and see if I can make sense of it.
boilerplate, n. : (computing) A standard set of text or program code incorporated into several places within a computer program or its output, either dynamically or manually.
Your boilerplate is the common content which you want added to all of your standard passages (e.g. your bleeding and time of day code).
wikifier : (in this context) The
Wikifier
is the engine at the heart of all of the current Twine 1.x headers, which are based on TiddlyWiki. It's what turns the TiddlyWiki wiki text/markup into plain text output.Except for CK's recent experimental format Snowman, which is based on Markdown, and whose engine is a JavaScript-hosted Markdown processor.
The current vanilla headers and SugarCube have made extensions to the base TiddlyWiki markup syntax.
::StoryInit
<<set $current to {
scene: "Opening Scene",
area: "Home",
room: "Living Room",
object: "",
}>>
What are you doing with the "object" tag? I guess you could have several passages interacting with an object and pop back to it. This also would work really great for in-hand or wielding objects. You have to select the key before you get the option to open the door.
I got a bit confused - I think MadExile was helping Novbert with high-level concepts when Novbert was helping me with specifics. When I try this I'll watch the capitalization as he's specified and hopefully I can insert the correct code.
Another question, along the same lines. Is there a way I can tag rooms to affect the player under certain conditions?
For example, the player becomes a vampire and acquires a sensitivity to garlic with the $garlicallergy = true flag. If I have an area of my game in a garlic bread factory, I would like his health to decrease slowly when in this area. I'd like the passages to work the same way, but for the player to get messages this is happening appended to the room description. What's the sanest way to go about this?