0 votes
by (200 points)
closed by

Hello everyone,

I'm trying to use a general construct to not type in hundreds or thousands of variable names by myself.

The general idea is using variables that start with $Door and then simply adding a number to them, to form variable names like $Door1, $Door240, and so on. The variables are meant to be simple integers, reflecting the state of the door, like 0 for locked, 1 for unlocked so that I can check against them from everywhere in the game.

For testing, I have set up a widget that simply takes the first argument provided and should use it to set the variable.

<<widget "doortest">>
 <<set $Door+`args[0]` = 1>>

I also tried variations of the backquotes like `$Door+args[0]` but I'm still getting the same error.

Giving the widget the argument 4 should assign the variable $Door4 the value 1.

Sadly it's not working, and sugarcube is only throwing 

Error: <<set>>: bad evaluation: invalid assignment left-hand side

I guess either the backquote (`) usage is wrong, or I'm not getting what they're supposed to do. I have other passage in my code where a simple printing of stuff via backquotes work, but have not successfully used it to describe the variable name itself.

closed with the note: Problem solved by using arrays instead of what I wanted to use. I simply added a bit on top of what greyelf suggested.

1 Answer

0 votes
by (159k points)
selected by
Best answer

I would suggest using an JavaScript Array of integer values instead of trying to dynamically generate the names of your story variables.

1. Initialise the $door Array within your project's StoryInit special passage.

The following sets up the equivalent of your Door0 to Door20, if you want more doors then increase the 20 in the below <<for>> macro to the number your need.

/* Initial the door variable to an empty array. */
<<set $door to []>>

/* Assign a zero to the equivalent of Door0 to Door20. */
<<for _i to 0; _i <= 20; _i++>>
	<<set $door[_i] to 0>>

note:JavaScript Array indexes are zero-based. eg. the first element is 0, the second element is 1 and so on.

2. The following passage content shows how reference and output the current state of a Door, how to change it's state, and how to compare it's current state to a known value.

Door1: $door[1]
Door12: $door[12]
Door20: $door[20]

<<set $door[12] to 1>>

<<if $door[12] is 1>>Door12 is unlocked.<<else>>Door12 is locked.<</if>>


by (200 points)
I just finished working on refactoring my code, when I read your comment.

I had SOME success reading (read <<printing>>) from dynamically named variables using ['$Door'[$number]] syntax, but the exact same syntax just spat out error when using <<set>> on them.

But I ultimately abandoned the idea. It seems to be too deep in "code magic territory" to be worth maintaing it.

So I basically did what you just suggested, but added some handling to preserve memory. I plan on using a lot of those doors, and I am fine with creating them ad-hoc instead of pre-generating them. So I just "checkDoor" via a global javascript function, provide the number and the handler takes care of everything else.

Problem solved, still thanks for your time!