How to stop repeat macro

Tweego 2.1.1 Twee3 , SugarCube 2.33.2

why i cant stop the repeat macro ?

:: Sleep
<<repeat 1s>>
	<<include "Clock">>
        /% $totalEnergy value is 130 but $energy value is dynamic %/
	<<if $energy gte $totalEnergy>>
		<<stop>>
	<</if>>
<</repeat>>

:: Clock
/% this will fill the $energy by 8 point %/
<<set $energyLoss to -8>>

and here’s my macro on js file

/*
	<<statusbar "identifier" "$maximum" "$current" "$changer">>

	identifier - The UNIQUE identifier used as the HTML element ID of this bar.
	$maximum   - The story variable that contains the maximum value this bar can be.
	$current   - The story variable than contains the current value of this bar.
	$changer   - The story variable this bar monitors to determine how much the current value should change by.

	eg. <<statusbar "sanity-bar" "$totalSanity" "$sanity" "$abuse">>
*/
Macro.add('statusbar', {
	skipArgs : false,
	handler  : function () {
		/* Check if correct parameters were passed. */
		if (this.args.length < 4) {
			return this.error('not enough parameters specified');
		}
		/* TODO: Validate each of the four parameters being passed to the macro. */

		var identifier  = this.args[0],
			maximum     = State.getVar(this.args[1]),
			// current     = State.getVar(this.args[2]),
			xstat       = State.getVar(this.args[2]),
			current      = Math.clamp(xstat, 0, maximum),
			change      = State.getVar(this.args[3]),
			barWidth    = (current / maximum) * 100,
			changeWidth = 0,
			delayReset  = false;

		/* Generate the HTML structure. */
		const $parent = jQuery(document.createElement('div'));
		$parent
			.addClass("status-bar")
			.attr({
				'id': identifier,
				'data-maximum': maximum,
				'data-current': current
			});

		const $bar = jQuery(document.createElement('div'));
		$bar
			.addClass("bar")
			.css('width', barWidth + "%")
			.appendTo($parent);

		const $change = jQuery(document.createElement('div'));
		$change
			.addClass("change")
			.css('width', changeWidth + "%")
			.appendTo($bar);

		$parent.appendTo(this.output);

		/* Handle any required change to the current value. */
		if (change != 0) {
			changeWidth = (change / current) * 100;

			// current -= change;
			// current     = (current - change).clamp(0, maximum);
			current 	= Math.clamp((current - change), 0, maximum);

			barWidth    = (current / maximum) * 100;
			State.setVar(this.args[2], current);
			State.setVar(this.args[3], 0);
			delayReset = true;
		}

		/* Apply the change visual effect if needed. */
		if (delayReset) {
			setTimeout(function(){
				$change.css({'width': '0'});
				$bar.css('width', barWidth + "%");
			}, 500);
		}
	}
});

im so confused, what im missing? thx before

1 Like

I’m confused by why you’re using <<include "Clock">> instead of just putting the code to change the variable on that line. I also have no idea why you included the code for your <<statusbar>> macro, since it appears to be totally unrelated to the problem you asked about.

Regardless, the problem is that your <<if>> statement is checking the values of $energy and $totalEnergy, but the “Clock” passage is changing $energyLoss. Since there doesn’t appear to be any connection between either of the first two variables and the last one, that’s why it’s never stopping.

I’m assuming that what you actually want is something like this:

:: Sleep
<<repeat 1s>>
	<<set $energy += 8>>
	/* $totalEnergy value is 130 but $energy value is dynamic */
	<<if $energy gte $totalEnergy>>
		<<stop>>
	<</if>>
<</repeat>>

That <<repeat>> would then stop when $energy is >= 130. (Which also confuses me. If $totalEnergy is apparently always 130, as indicated by the comment, why not just put 130 there instead?)

I don’t know. I feel like I’m missing something here because you’ve included a number of apparently unrelated puzzle pieces, but I believe that that’s the answer you’re looking for. If not, please clarify for me what it is you’re trying to communicate here that I’m missing.

Hope that helps! :grinning:

2 Likes

Thx for the reply, and:

  1. im using include because the Clock passage have so many code on it and i want this Clock reusable for the other passage such as storyCaption to show the clock and count the energy loss too
  2. im showing the <<statusbar>> macro because maybe it has something to do with it LOL
  3. when $energyLoss has negative value, it will increase the $energy. so i thought it will works if i put the if argument on Sleep passage even though the mutation is happen in Clock passage

so what im getting is we can’t process the argument in other passage when the action is happen in another passages yes ? is that how it works ? because i think it will happen globally because the variable is changing too when i do inspectVar

If that’s what you’re using the “Clock” passage for, then you should turn that into a widget instead.

I don’t see how it could.

How? I don’t see any code which does that.

I can’t debug code that you don’t show.

What “argument” are you talking about? And no, it shouldn’t matter.

The problem in the code that you showed is that it never changes the value of $energy.

If there is some other code which changes it, then you need to show that code so that we can understand what’s going on.

Basically, it seems like you included some irrelevant code in your post, but also left out other highly relevant code which is necessary to solve your problem.

If I had to guess, based on what you’ve suggested, you’re adding $energyLoss to $energy, when you should be subtracting it if you ever want a value of -8 $energyLoss to increase $energy.

But that’s just a total shot in the dark without seeing your code.

hmm im a bit confuse about this, here’s my full code about this issues … maybe i should turn the clock in storyCaption into widget yes ?
test.zip (143.0 KB)

The variable $energy appears in the code four times:

:: StoryInit
<<set $energy to 100>>

:: Sleep
<<if $wakeup eq 1 or $energy gte $totalEnergy>>

:: StatsCondition
<<if $energy > 10 >>

:: StoryCaption
<<statusbar "energi-bar" "$totalEnergy" "$energy" "$energyLoss">>

You never mentioned that last one, which is the one that changes $energy and thus gives the reason to include the <<statusbar>> code.

However, the actual problem is that the “Sleep” passage includes the “Clock” passage, and the “Clock” passage includes the “StatsCondition” passage, and the “StatsCondition” passage does:

<<goto `passage()`>>

which, since you’re currently in the “Sleep” passage, that <<goto>> just sends you to the “Sleep” passage again. So that’s the source of your infinite loop, not the <<repeat>> macro, since it never gets an opportunity to repeat more than once anyways.

None of which I could tell since you left out all of that code.

Anyways, fix it so that it goes elsewhere when the energy gets to what you want, and that will stop the loop.

Have fun! :grinning:

Oh ic so thats why i cant stopped the loop. Thx and btw do you think this time system and status bar stuff is ideal for the long run? I mean it wouldnt get laggy in the long run right? Or maybe i should change the Clock passage into widget as you said before. Thx again for the help

The game shouldn’t get “laggy”, however, if you aren’t using the code in the “Clock” or “StatsCondition” passages anywhere else, there’s no point in giving it its own passage. Doing it the way you’re doing it only makes it more difficult to debug, because the code is spread out across multiple passages. If the code is only used once, then you should simply move it into the passage that uses it, otherwise turning it into a widget is a good idea, since you can have all of your widgets in a single passage.

That said, if you get too many passages (somewhere around 700+) then the Twine editor might get laggy, so it’s generally a good idea to minimize the number of passages you use anyways for large games.

Hope that helps! :grinning:

1 Like