Can I get names of included passage?

regarding to documentation of sugarcube, I can get Passage names with passage() function.
but in included passage, it returns parent’s passage name not of included passage
how can I get the name of included passage?

If you’re <<include>>ing a passage, then you must already know the name of the passage in order to include it. Also, you don’t have to use the passage() function for a passage to know its own name, you could just hard-code the passage name into that passage’s code.

If you could explain what you’re actually trying to accomplish by doing this, that would be better, since not all ways to achieve what you’re asking for may help you, depending on what you’re doing with that data.

Also, please note if you’re ever including more than one passage at a time, since that may affect your answer.

The short answer is that there’s no built-in way to do that. SugarCube doesn’t track that information at all. I’ve wanted it for a few things, and I’ve looked through the source code, and it wouldn’t be a minor change.

But as HiEv said, if you explain why you want that info, we might be able to help you choose which of the possible work-arounds is best for you…

oh…
What I want to do is count how many times each passage which have ‘Perform’ tag, has been visited(or run maybe)
And every Perform taged passage will selected in parent 'Command ’ passage and return the result of each ‘Perform’ passage on dialog.

I made decades of passages with specific tag like ‘Perform’ and save it in a variable in storyinit passage

<<set _Per to Story.lookup('tags', 'Perform')>>
<<set $Per to []>>
<<for _i range Object.keys(_Per)>>
	<<set $Per.push(_Per[_i].title)>>
<</for>>
<<set $Char to {Stat:[].....and so on... Per:[]}>>
<<set $Char.Per[0] to []>>
<<set $Char.Per[1] to []>>
<<for _i to 0; _i < $Per.length ; _i++>>
	<<set $Char.Per[0][_i] to $Per[_i]>>
	<<set $Char.Per[1][_i] to 0>>
<</for>>

one of the Perform Passages will be

:: deadlift [Perform]
<<set _now to passage()>>
<<if $Char.Per[1][$Per.indexOf(_now)] > 0 >>
	<<set $Char.[1][$Per.indexOf(_now)] += 1>>
<<else>>
	<<set $Char.[1][$Per.indexOf(_now)] to 1>>
<</if>>

Deadlift!!
count: <<= $Char.Per[1][$Per.indexOf('Deadlift')]>>

but passage()will not work properly, so I instead that all to ‘Deadlift’
and I skipped dialog part because it is too complex with my other codes…

and Command passage will be

<<for _i = 0; _i < $Per.length;_i++>>
	<<capture _i>><<nobr>>
	<<link $Char.Per[0][_i]>>
		<<replace '#Per'>>
			<<include $Char.Per[0][_i]>>
		<</replace>>
	<</link>>
	<</nobr>><</capture>>
<</for>>

<span id='Per'></span>

and some other page, I’ll show $Char.Per variables.

so now,
how can I treat this with <> macro not write every dozens of Perform passages?

I’m still not 100% clear on what you need, but I think this should do the trick.

First, put this in your StoryInit passage:

<<set $PsgCount = {}>>

That will initialize the $PsgCount variable as an empty generic object.

Next, create a passage with “widget” and “nobr” tags, and put this <<count>> widget in it:

<<widget "count">>
	<<if ndef $PsgCount[$args[0]]>>
		<<set $PsgCount[$args[0]] = 1>>
	<<else>>
		<<set $PsgCount[$args[0]]++>>
	<</if>>
<</widget>>

When that widget is called, it will either add a property to the $PsgCount object with the passage’s name and set the count to 1 - or - it will add 1 to the existing count for that passage.

After that, all you need to do is put:

<<count "Passage Name">>

somewhere within every “Perform” passage where it will get executed, with the passage’s name (or whatever phrase you wish to use to track that passage) replacing where it says “Passage Name”.

After you’ve done that, if at any time you want to see the list of all actions performed and the count of how many times each have been performed, you can just do this:

<<for _name, _count range $PsgCount>>
	_name: _count
<</for>>

If you wanted that list sorted by passage name, you could do this instead:

<<set _names = Object.keys($PsgCount).sort()>>
<<for _name range _names>>
	_name: <<= $PsgCount[_name]>>
<</for>>

With the above code, tasks which have never been performed will not be displayed. However, if you want all “Perform” tagged passages to be displayed and initialized to a count of 0, then you could put this in your StoryInit passage instead:

<<set $PsgCount = {}>>
<<set _Per to Story.lookup('tags', 'Perform')>>
<<for _i range Object.keys(_Per)>>
	<<set $PsgCount[_Per[_i].title] = 0>>
<</for>>

(Note: If you use this technique, then the names used when calling the <<count>> widget must match the passage names.)

Please let me know if you have questions on any of the above code.

Hope that helps! :slight_smile:

1 Like

It’s not exactly what I want, but got some insight
thank you

Theoretically, you could include code in “perform” to increase a variable each time it runs. In ASM whenever a remote passage is displayed, all the code in it fires. There’s also an IF VISITED(‘passage’) EQ # function - but I’m not sure if Twine has a built-in analogue.

If you could clarify what you want a bit more then I’ll try to help if you’re still having problems.

My purpose is to make simple code
my insight?
now I know that I should write every passage name on every included passage haha…
thanks for all of your answers