[Twine2 Sugarcube2] Using [if visited] with multiple passages

Twine Version: 2.3.9
Story Format: Sugarcube 2.31.1

Sorry about this extremely new-to-coding question, but I’m stuck on the logic of how to make something particular happen.

I’m trying to add a scavenger element to my game. Here’s the scenario (using apples as an example):

When a player goes to a passage (sceneA here) with an apple, I’ve written:

<<if visited("sceneA") is 1>><<set $apples to $apples + 1>><<endif>>

If it’s the first time visiting the passage, they add one apple to the pile. If it’s less than 1 or more than 1, no apple gets added to the pile. So far so good. I mean, maybe it’s not, but this seems to be functioning correctly when I test.

My problem is, some apples you can find in multiple passages. Since you can find the SAME apple in sceneA and sceneB, I want to make it so $apples only increases once when you visit EITHER sceneA or sceneB for the first time.

<<if visited("sceneA", "sceneB") is 1>><<set $apples to $apples + 1>><<endif>>

seems wrong, as does

<<if visited("sceneA", "sceneB") lt 2>><<set $apples to $apples + 1>><<endif>>

What am I missing? Am I way off base? I swear I tried to google this, but I wasn’t getting anywhere. Thanks a bunch.

Yeah, I don’t think this approach will work: visited("sceneA", "sceneB") is 1 will become true when you’ve visited either A or B at least once, as you say, but it will remain true until you’ve visited both scenes at least twice, which is almost certainly not what you want. Even with a single scene, this will probably cause problems: it will keep incrementing $apples until you visit the scene for the second time (depending on where you’re putting the code).

I can see two ways to do this:

In sceneA and sceneB, do:

<<if not hasVisited("sceneA", "sceneB")>><<set $apples to it + 1>><</if>>

OR if you want to have the code in one central place, you could instead compute apples each time you need it:

<<set _apples to hasVisited("sceneA","sceneB") + hasVisited("sceneC") + ...>>
1 Like

Assuming that you only use the code in the “sceneA” and the “sceneB” passages, what you want is this:

<<if visited("sceneA") + visited("sceneB") === 1>>
	<<set $apples++>>
<</if>>

That will only trigger when one passage or the other has been visited once. Also, the ++ operator acts as a shorthand way of adding one to the value.

Oh, and one more thing, <<endif>> is the old SugarCube v1 way of ending a macro. You should use <</if>> to end the <<if>> macro, per the SugarCube v2 documentation. You can use SugarValidator to help catch things like that.

Hope that helps! :grinning:


That won’t work. For example, if they go to “sceneA” twice, then it will trigger both times, instead of only the first time. Also, “it” is Harlowe code, not SugarCube, so that would trigger an error there.

This also won’t work, because the hasVisited() function only returns true and false values, so you can’t add them together like that. Also, hasVisited("sceneA","sceneB") would only return true if both passages had been visited, so that wouldn’t work anyways.

So neither of those would have worked.

2 Likes

This is EXACTLY what I needed! My properly counted apples and I thank you!!

Oh, geez, that was horribly sloppy of me; thanks for the corrections.

In Harlowe you can’t add true and false values together to get a number (usually), but it does work in SugarCube (since it just passes through to the JavaScript behavior: true acts as 1, false as 0). I know some people consider that to be bad style, but in my (somewhat limited) experience artists and writers have no trouble with that: it’s only programmers who look down on it…

But yeah, I totally missed that hasVisited() works differently from visited(), so that solution still wouldn’t work anyway…