How using args to indicate a variable

Hello. I making map by this guide. Right now its looks like that

<<for $i to 0; $i lt $loc_home.length; $i++>>
	<<for $k to 0; $k lt $loc_home[$i].length; $k++>>
		<<if $k eq $positionX and $i eq $positionY>>@@.map_player;P@@
			<<elseif $loc_home[$i][$k] eq 1>>&nbsp;
			...
			<<elseif $loc_home[$i][$k] eq 9>>O
		<</if>>
	<</for>>
<</for>>

So i have a question. I have some places with differents maps with a different widgets. And now i wanna merge all widgets to one (if it possible).

For example, I set variable $loc_home and set map inside and set $loc_street. Its two differents maps. Next, i wanna making one widget, who will take arg and set it as a variable. For the arg i wanna use passage() for taking passage name and use it in condition for forming map on page. The name of map variables and passages names are equivalent

For example

<<map `passage()`>>

And then

<<for $i to 0; $i lt $args[0].length; $i++>>
	<<for $k to 0; $k lt $args[0][$i].length; $k++>>
		<<if $k eq $positionX and $i eq $positionY>>@@.map_player;P@@
			<<elseif $args[0][$i][$k] eq 1>>&nbsp;
			...
			<<elseif $args[0][$i][$k] eq 9>>O
		<</if>>
	<</for>>
<</for>>

But map is just not showing, Please tell me where i was wrong and is this even possible?

If I understand correctly you have two ‘location’ related Passages named loc_home and loc_street, and the meta data associated with those two Passages are contain within the $loc_home and $loc_street Story Variables respectively.

You will need to use the State.variables collection object to gain access to the data contain within the $loc_home and $loc_street Story Variables, using the passed in Passage Name argument to indicate which ‘Story Variable’ you want the data of.

<<set _loc = State.variables[$args[0]]>>

The following code shows a possible implementation of a ‘map’ widget containing your second code example.

<<widget 'map'>>
	<<if $args.length > 0>>
		<<set _loc = State.variables[$args[0]]>>
		<<for $i to 0; $i lt _loc.length; $i++>>
			<<for $k to 0; $k lt _loc[$i].length; $k++>>
				<<if $k eq $positionX and $i eq $positionY>>@@.map_player;P@@
					<<elseif _loc[$i][$k] eq 1>>&nbsp;
					...
					<<elseif _loc[$i][$k] eq 9>>O
				<</if>>
			<</for>>
		<</for>>
		<<unset _loc>>
	<</if>>
<</widget>>

warning: The above code has NOT been tested, as I was unsure of the exact contents of the Story Variables you referenced in your examples. It also doesn’t check to make sure that the Passage Name being passed into the ‘map’ widget has an associated Story Variable.

1 Like

You can do that, however you can’t use $args[0] directly that way. If you add this to the start of your widget:

<<set _tempMap = State.getVar("$" + $args[0])>>

and then use the array in _tempMap (i.e. swap $loc_home for _tempMap in your first example), it should work fine. (See State.getVar() for details.)

Also, instead of using the story variables $i and $k for your loop variables, you should use the temporary variables _i and _k, because you should only use story variables when absolutely necessary to keep data across passage transitions. This is because story variables increase the size of the game history which has to be kept track of, which in turn slows down passage transitions, saves, and loads.

One other thing I’d suggest is that, instead of doing <<elseif _tempMap[_i][_k] eq #>> for each number, you could shorten that like this:

<<switch _tempMap[_i][_k]>>
	<<case 1>>&nbsp;
	...
	<<case 9>>0
<</switch>>

See the <<switch>> macro for details.

Hope that helps! :grinning:

1 Like

Thanks for answering. I just couldn’t find way to use a binding argument with a variable, but I tried something similar with state.variable. In any case, it partially helped. But!

I try two ways as you say, using first <<set _loc = State.variables[$args[0]]>> and then <<set _tempMap = State.getVar("$" + $args[0])>> but in both ways i have an error Error: <<map>>: error within widget contents (Error: <<for>>: bad conditional expression: Cannot read property 'length' of undefined).

Right now code looks like

<<widget 'map'>>
	<<set _loc = State.variables[$args[0]]>>
	<<set _loc = State.getVar("$" + $args[0])>>
		<span id='maptab'>
			<div id='map'>
				<<for _i to 0; _i lt _loc.length; _i++>>
					<<for _k to 0; _k lt _loc[_i].length; _k++>>
						<<if _k eq $positionX and _i eq $positionY>>@@.map_player;P@@
						<<elseif _loc[_i][_k] eq 1>>&nbsp;
						<<elseif _loc[_i][_k] eq 0>>■
						<<elseif _loc[_i][_k] eq 2>>X
						<<elseif _loc[_i][_k] eq 3>>E
						<<elseif _loc[_i][_k] eq 4>>t
						<<elseif _loc[_i][_k] eq 5>>K
						<<elseif _loc[_i][_k] eq 6>>S
						<<elseif _loc[_i][_k] eq 7>>W
						<<elseif _loc[_i][_k] eq 8>><span style="color:yellow;">i</span>
						<<elseif _loc[_i][_k] eq 9>>O
						<</if>>
					<</for>>
					<br>
				<</for>>
			</div>
		</span>		
		<<unset _loc>>
<</widget>>

where string 2 and 3 is mutually exclusive

I try <<print passage()>> and it works correctly, showing the name of current passage, so i try both way with widget <<map passage()>> and <<map 'passage()'>>

yeah i need to optimise that, but only after when it works! Thanks :slightly_smiling_face:

Just to clarify first, but in case you weren’t aware, this part of your code is redundant. You should use one or the other. (I assume you’re aware, I’m just covering my bases.)

This tells me that the name of the variable (not including the “$”) and the name of the passage aren’t the same.

If the name of the variable is “$loc_home”, then the name of the passage has to be “loc_home” for the above code to work with:

<<map `passage()`>>

(Note that the characters around passage() are not apostrophes, they’re backquotes, found on the ~ key in the upper-left corner of most keyboards. You have this correct in your first post, but I thought it was worth mentioning for others.)

If the name of the passage is actually “$loc_home”, then you could just change my code to:

<<set _loc = State.getVar($args[0])>>

(You’d need to strip out the “$”, either from the passage names or from the $args[0] value, to get Greyelf’s code to work with passage names like that.)

Hopefully that should work and make sense now. :grinning:

1 Like

yes, i understand

god what a dumb, i forgot to edit variable $loc_home. It was with old name. Now that works perfectly with your and Greyelf examples! Thank you guys so much :slightly_smiling_face: I need learn more about hows args works