Okay, this was a huge help. I've discovered that this works:
:: Widgets
<<widget "chain">>
<<for _i, _a range $args>>
<<set $args[_i][0] = State.getVar($args[_i][1])>>
<</for>>
<</widget>>
:: PassageReady
<<chain $target $subject>>
:: a-passage
[[Testing][$target = [$enemies[0],"$enemies[0]"];$subject = [$enemies[1],"$enemies[1]"]]]
By storing the name of the variable as a string and attaching it like this, I can maintain the object reference for any variable I want. Using the test you gave me here, $target and $subject both read as "same reference" when compared to what they should be referencing, no matter how many passages I go through. This is very good.
However, I'm running into a weird issue when I try to pass this as an argument to a widget. I made the command buttons widgets for... some reason I don't remember, and it looks like this:
:: Widgets
<<widget "act">>[[Act|actions][$subject = $args[0]]]<</widget>>
<<widget "rest">>[[Rest|confirm phase][$subject = $args[0]; $action = "rest"; $target = null; $cost = 0]]<</widget>>
<<widget "items">>[[Item|items][$subject = $args[0]]]<</widget>>
:: command phase
<span class="actors">
<<for _i, _puppet range $puppets>>
<div class="commands">
<<if _puppet.dead is true>>
/* If puppet is defeated, display no commands. */
<<else>>
<<act [$puppets[_i],"$puppets["+_i+"]"]>><br />
<<rest [$puppets[_i],"$puppets["+_i+"]"]>><br />
<<items [$puppets[_i],"$puppets["+_i+"]"]>><br />
<</if>>
</div>
<</for>>
</span>
When I try clicking the command buttons for the character at index 0, it gives me this error:
<<chain>>: error within widget contents (Error: <<set>>: bad evaluation: Cannot assign to read only property '0' of string '[$puppets[_i],').
And $subject has indeed been set to "[$puppets[_i]," , the string, for no reason I can discern.
In this case I can just un-widget this functionality and add the links to the command phase directly (which seems to work fine even though I don't change anything else), but this is going to be a problem if I ever need to manually set a target or subject through a widget. Do any of you know what's going on here?
But otherwise, thanks, this actually works:
<<widget "damagecalc">>
<<if $pierce is false>>
<<set $dmg to 50+(($weight*$subject[0].atk)-$target[0].def)>>
<<elseif $pierce is true>>
<<set $dmg to 50+($weight*$subject[0].atk)>>
<<set $pierce to false>>
<</if>>
<</widget>>
<<widget "echodamage">>
<<if $target[0].dead is false>>
$target[0].name takes $dmg damage!<br />
<<set $target[0].hp -= $dmg>>
<</widget>>
Now I won't have to worry about mixing up the target and subject every time I call a damage function.