JavaScript $Return Issue in Sugarcube

Hey all. I’m pretty new to coding in general, so please bear with me here.
I’m trying to implement the return strategy described here: to enable the return command on a cheat/inventory page. The goal is to allow the player to return to the last passage they were on, instead of falling into a loop of inventory or cheat mode passages.

I’ve placed the code at the top of my story javascript:

	predisplay["Menu Return"] = function ($return) {
	if (! tags().contains("noreturn")) {
		State.variables.return = passage();
	}
};

And have applied the appropriate tags on the passages themselves. But when I go to play the game I get this error message:

Apologies! An error has occurred. You may be able to continue, but some parts may not work properly.

Error [tw-user-script-0]: missing } after property list.

I’ve done some googling to try and suss out what that error means, but the little things I’ve tried to fix the code (making sure there’s no missing/excess punctuation) doesn’t work. Any tips? Appreciated!

PS I’m using Twine 2.3.3 and Sugarcube 2.28.2.

Hrm…looks like the problem is elsewhere in your story javascript: If I paste the code into the story javascript of an empty project it works fine for me…

I have to agree with Josh. That’s not where your error is. Although, you wouldn’t want to use $return as your function parameter. Just use something like taskname like in the example since it’s not even used for that function.

Do you have other javascript that would be causing a tag matching error? Sometimes in javascript if you type something that it completely doesn’t expect (like too many closing parenthesis or missing an end quote, for example), it’ll not see the curly bracket and will erroneously report it as missing. It’s still a matching error, but it’s for the wrong one.

1 Like

Well, first thing, that code is really old and it’s not recommended you do things that way anymore.

Second thing, what you’re asking about is actually covered in the SugarCube documentation within the “Arbitrarily long return” section. Funny enough though, the sample code in that section still uses the old way of doing things. :stuck_out_tongue:

The modern version of that code would be:

/* Trigger the following code at the start of navigation to a new passage. */
$(document).on(":passagestart", function (event) {
	/* Make sure the current passage doesn't have a "noreturn" tag. */
	if (!tags().includes("noreturn")) {
		/* If it doesn't, then set $return to the current passage name. */
		State.variables.return = passage();
	}
});

That uses the :passagestart event to trigger that code every time you go to a new passage. It then stores the name of that passage so your code can go back to it, unless the passage has a “noreturn” tag, which you should add to any menu passages. (The comments in the code above explain what the next line of code does.)

Then, in all of your “noreturn” tagged menu passages, you’d just do something like this:

<<link "Return" $return>><</link>>

to provide a “Return” link, which would take you to the last non-menu passage you’d visited, since $return will hold the name of that passage.

Hope that helps! :slight_smile:

This is fantastic. Thank you so much (and to everyone else) for your help! It was in fact an issue with separate code, but HiEv’s code works flawlessly as well (the old code I was using was not).

Thanks again!

This works perfectly. But I have a problem.
I have a fighting system that uses variables in the body of the passage. For example:

[[Light Attack|the same passage][$passagechoice to 1; $atk to 1;  $enemydefense to random(1, 5)]]

<<if $passagechoice is 1>>\

<<if $atk is 1>>\
<<if $enemydefense is 1 or $enemydefense is 2>>\
<<set $enemyhp -= 10>>\
I do a light attack and hit him for some damage.
\
<<elseif $enemydefense is 3 or $enemydefense is 4>>
<<set $enemyhp -= 5>>\
I do a light attack but he blocked reducing the damage taken.
\
<<else>>
I do a light attack but he evaded and take take no damage.
\
<</if>>

The problem is that after performing an attack and entering some menu passage with the tag “noreturn”, when returning to the fight passage, the attack result is repeated, reducing the enemy’s hp again. So, the player enter and exit the menu several times after a successful attack until the fight is over without difficulty.
How can I prevent this?
I’m using Twine 1 and Sugarcube 2.

Thanks in advance.

Please use the </> Preformatted text option when including a code example in your posts, it stops the forum’s software from “eating” parts of your code. Like what has happen to the last code example you posted.

Sorry. I am new to the forum. I don’t know how to use this function. When I click on it it shows ‘Preformatedtext’, but I don’t know what to do with it.

When you selected the </> option it adds content like the following to your post.

```
type or paste code here
```

You need to paste or write your code example between the two sets of triple ``` back-quote character, replacing the “type or paste code here” text with your own code.

eg. If my code was the following…

<<if $variable is "value">>
[[Link Text|Target Passage Name]]
<</if>>

…then the related contents of my post would look like…

```
<<if $variable is “value”>>
[[Link Text|Target Passage Name]]
<</if>>
```

Thanks. Edited the post now.

For something like that, it may be simpler to make your menu passages and the like into overlays that appear temporarily overlaying the current passage, so that the current passage doesn’t need to reload when you go back and forth between them.

Take a look at the “SlideWin Overlay” section of my Twine/SugarCube sample code collection, and see if that does the trick for you.

Please let me know if you have any problems with it, since I just added that sample code to the collection and I may have missed something.

Enjoy! :slight_smile:

This really is an amazing job. But I was looking for something simpler. I already have a lot of menu passages ready and the fighting system is new. If it’s not possible to do something simple in the menus I’d rather have to change the fighting system than the menus. I accept suggestions for a simple fighting system that doesn’t fall into this problem.
Thanks.

I don’t know about Twine 1, but for my own combat systems in Twine 2/Sugarcube 2 I execute all the combat round code upon clicking a particular “attack” link (using the <<link>> macro, which lets you implement conditional actions and widgets). For combat messages, upon clicking the link, I assign them to a variable, like $playermessage and $enemymessage, then I print that variable within the body of the passage.

I’ve actually made a simple Sugarcube combat demo a while ago. I don’t know if it would be of any use to you, but you can take a look at it here: Twine/Sugarcube combat demo

Thank you HiEv and Agnieszka.
I solved the problem in a very simple way without having to change the menu or combat mechanics.
I just ran the $enemydefense variable in the previous setterlink (defence phase) and displayed a different attack menu for each result.
For example:

<<if $enemydefense is 1 or $enemydefense is 2>>\
[[Light Attack|the same passage][$passagechoice to 1; $atk to 1; $enemyhp -= 10]]
\
<<elseif $enemydefense is 3 or $enemydefense is 4>>
[[Light Attack|the same passage][$passagechoice to 1; $atk to 2; $enemyhp -= 5]]
\
<<else>>\
[[Light Attack|the same passage][$passagechoice to 1; $atk to 3]]
<</if>>\

<<if $passagechoice is 1>>\
<<if $atk is 1>>\
I do a light attack and hit him for some damage.
\
<<elseif $atk is 2>>\
I do a light attack but he blocked reducing the damage taken.
\
<<else>>\
I do a light attack but he evaded and take no damage.
\
<</if>>\
\
<<elseif $passagechoice is 2>>\

.... Rest of the code ....

<</if>>\
1 Like