Objects that point to each other

edited June 2014 in Help! with 1.x
Paul and Joe are just two dudes making their way in life.

<<$paul = {name: "paul"}>>
<<$joe = {name: "joe"}>>

One day Paul becomes angry at Joe over some perceived slight. It gets kind of out of hand.

<<$paul.mortalEnemy = $joe>>

(This works exactly as expected. For example, <<print $paul.mortalEnemy.name>> returns "joe")

Joe finds out about this. He doesn't like not being liked. It gets kind of out of hand.

<<$joe.mortalEnemy = $paul>>

Hate leads to hate, and Paul and Joe destroy each other.

(this works as I expect in the passage it's written in, but in every future passage $joe and $paul are undefined. The problem seems to arise whenever an object is changed after it's been made a property of another object.)

::Start
<<$paul = {name:"paul"}>>
<<$joe = {name:"joe"}>>

<<$paul.mortalEnemy = $joe>>
<<print $paul.mortalEnemy.name>>
<<$joe.mortalEnemy = $paul>>
<<print $joe.mortalEnemy.name>>
[[end]]

::end
<<print $joe>>

the passage <<end>> displays as "0"

edit: I said that <<$paul.mortalEnemy = $joe>> worked as I was expecting until $joe was modified. I just noticed that this actually breaks the back button.

Comments

  • You currently can't store cyclic objects in Twine variables - the game state has to be serialisable as a string so that the bookmark link can be generated and the back/undo button can behave correctly even after navigating away from the page. (1.4.2 does a few ad-hoc tricks to allow "pure" functions to be serialisable, but other than that it's basically the same as JSON.stringify's restrictions.)

    (I say "currently" but I'm not sure how comfortable I feel about lifting this restriction for stories that opt-out of undo and serialisable state via StorySettings.)
  • Just to throw my 2 in.  Cyclic references should be avoided as a general rule.  Besides unnecessarily complicating the back-end header code, unless authors are extremely careful it's all too easy to do something which will lead to a recursive death spiral.

    Beyond that, you don't need cyclic references to accomplish what you want.

    One solution would be to put all your characters into a object and then use symbolic references.  For example:

    :: Start
    <<set $chars = {
    paul : { name : "Paul MacIver" },
    joe : { name : "Joe Blow" }
    }>>\
    <<set $chars.paul.enemy = "joe">>\
    <<set $chars.joe.enemy = "paul">>\
    [[Check your work]]

    :: Check your work
    ''paul says:''
    I am <<print $chars.paul.name>> and my mortal enemy is <<print $chars[$chars.paul.enemy].name>>.

    ''joe says:''
    I am <<print $chars.joe.name>> and my mortal enemy is <<print $chars[$chars.joe.enemy].name>>.
Sign In or Register to comment.