Hello!
How can I check existence of particular passage in Sugarcube?
I saw that Harlowe has system variable "$Passages" which can solve this task, but is there any way to do it in Sugarcube?
To check if a passage exists within the story history, you may use the visited() utility function (I suggest reading the linked docs). For example:
<<if visited() is 3>>…this is the third visit to the current passage…<</if>>
<<if visited("Bar")>>…has been to the Bar at least once…<</if>>
<<if visited("Café") is 1>>…has been to the Café exactly once…<</if>>
<<if visited("Bar", "Café") is 4>>…has been to both the Bar and Café at least four times…<</if>>
<<if visited() is 3>>…this is the third visit to the current passage…<</if>>
<<if visited("Bar")>>…has been to the Bar at least once…<</if>>
<<if visited("Café") is 1>>…has been to the Café exactly once…<</if>>
<<if visited("Bar", "Café") is 4>>…has been to both the Bar and Café at least four times…<</if>>
Hm, but what difference will it give if one passage exists, but never visited, and other never existed?
Why would you ever check for the existence of a passage which you, the author, know doesn't exist within the story?
Regardless. The answer is none (i.e. there is no difference). The visited() utility function doesn't check if passages exist within the story, it checks if they exist within the story history (exactly the same as checking Harlowe's $Passages variable, AFAIK). If a passage doesn't exist within the story history, regardless of whether or not it exists within the story, then its count is 0 (zero).
I'm trying to emulate parser-games-like behaviour, when several objects share similar action between them. So I have default response for that action. But I also have individual responses for couple of objects.
And when I decide what to show, I check - does object have own response or I should use default.
It would be trivial if responses were strings. But I have links in them and should use <<display "passage">> instead. And here I have my is-passage-exist check.
Can you just make it check a variable/object property for whether or not it has its own response?
Yeah, it was my Plan B - make switches for every case and check them. But number of switches = number of objects * number of common actions and it doesn't really motivates.
Anyway, I think I found some dirty solution - check for those passages in "store-area" of compiled webpage with JS.
I'm trying to emulate parser-games-like behaviour, when several objects share similar action between them. So I have default response for that action. But I also have individual responses for couple of objects.
And when I decide what to show, I check - does object have own response or I should use default.
Anyway, I think I found some dirty solution - check for those passages in "store-area" of compiled webpage with JS.
I just told you how you can do what you want to do, by using tale.has(). It does exactly what you want (checking to see if the passage exists at all), there's absolutely no need to brute force check the passage store area. For example:
Additionally, a suggestion. Since passage titles are case-sensitive, you may want to title all of your
passages in lowercase and force the player's input to lowercase, otherwise player's may become frustrated by things like "Go west" not matching "go west".
I just told you how you can do what you want to do, by using tale.has(). It does exactly what you want (checking to see if the passage exists at all), there's absolutely no need to brute force check the passage store area. For example:
Additionally, a suggestion. Since passage titles are case-sensitive, you may want to title all of your
passages in lowercase and force the player's input to lowercase, otherwise player's may become frustrated by things like "Go west" not matching "go west".
Actually, I don't use input - I don't really believe in parser-based IF in its current form - my game uses links. But I try to emulate object model of parser games. Still, thanks for the tip.
Comments
Hm, but what difference will it give if one passage exists, but never visited, and other never existed?
Regardless. The answer is none (i.e. there is no difference). The visited() utility function doesn't check if passages exist within the story, it checks if they exist within the story history (exactly the same as checking Harlowe's $Passages variable, AFAIK). If a passage doesn't exist within the story history, regardless of whether or not it exists within the story, then its count is 0 (zero).
I think I'll try my luck with custom macro. Thanks for your time.
Regardless. You may use the Tale API's has() method to do so, like so:
And when I decide what to show, I check - does object have own response or I should use default.
It would be trivial if responses were strings. But I have links in them and should use <<display "passage">> instead. And here I have my is-passage-exist check.
I hope I made it clear?
Can you just make it check a variable/object property for whether or not it has its own response?
Yeah, it was my Plan B - make switches for every case and check them. But number of switches = number of objects * number of common actions and it doesn't really motivates.
Anyway, I think I found some dirty solution - check for those passages in "store-area" of compiled webpage with JS.
I just told you how you can do what you want to do, by using tale.has(). It does exactly what you want (checking to see if the passage exists at all), there's absolutely no need to brute force check the passage store area. For example:
Additionally, a suggestion. Since passage titles are case-sensitive, you may want to title all of your
passages in lowercase and force the player's input to lowercase, otherwise player's may become frustrated by things like "Go west" not matching "go west".
Oh... All this time I thought that whole API section in manual relates to JS only... Now I see, thank you.
Actually, I don't use input - I don't really believe in parser-based IF in its current form - my game uses links. But I try to emulate object model of parser games. Still, thanks for the tip.