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
(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.)
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: