Tried to code a fight but it freezes the browser

First of all: Much of this code may be unnecessarily complicated. I’m still new at coding, so sorry for that. I tried to make a sort of turnset, a “if roll is 1 it’s the players’ turn but if it’s 2 it’s the companion’s turn”. The idea is to add more companions later on.

I get no bugs on quicktest, but it freezes when I run it on Node, after the first choice I make. Why does it freeze?

My code looks like this:

*label turnset
*rand d4 1 2       
*comment This ^^ should say "rand d4 1 4" but just Jura has stats as of now, so
*if d4 = 1
  *goto player
*if (d4 = 2) and (juraalive)
  *set Juraturnvar true 
  *goto juraturn
*else
  *goto player

*label player 
A wolf attacks!
*label fight
*if wolfturn 
  The wolf attacks!
  *rand d20 0 20
  *if d4 = 1
    *set minushealth phealth - (wolfattack + d20)
    *set wolfturn false
    *if phealth <= 0
      *goto death
  *if phealth > 0
    The wolf bits you!
    *goto player
  *if d4 = 2
    *set minushealth jhealth - (wolfattack + d20)
    *set wolfturn false
    *if jhealth <= 0
      *goto jdeath
  *if jhealth > 0
    The wolf bits Jura!
    *goto turnset

Your health: ${phealth}

Jura's health (placeholder): ${jhealth}

It's health: ${wolfhealth}
  
What do you choose? 

*label juraturn
*if juraturnvar and juraalive
  It's Jura's turn.
*fake_choice
  *if (sword = true) #Attack it with my sword!
    *rand d20 0 20
    *set totalattack addstrenght + (swordat + d20)
    You rolled ${totalattack}!
    *if totalattack >= 20
      *set wolfhealth -30
      You hit! 
      *if (wolfhealth <= 0) 
        *goto win
      *elseif (wolfhealth > 0) and (phealth > 0) 
        *set wolfturn true
        *goto fight
    *if (totalattack > 15) and (totalattack < 20)
        *set wolfhealth -20
        You hit! 
        *if wolfhealth <= 0
          *goto win
        *elseif (wolfhealth > 0) and (phealth > 0)
          *set wolfturn true
          *goto fight
    *if (totalattack > 10) and (totalattack < 15)
      You don't hit!
      *set wolfturn true
      *goto fight
    *else
      You don't hit! 
      *set wolfturn true
      *goto fight
	  
  *if (jsword = true) #He'll attack with a sword!
    *set juraturnvar false
    *rand d20 0 20
    *set totalattack addstrenght + (swordat + d20)
    You rolled ${totalattack}!
    *if totalattack >= 20
      *set wolfhealth -30
      You hit! 
      *if (wolfhealth <= 0) 
        *goto win
      *elseif (wolfhealth > 0) and (phealth > 0) 
        *set wolfturn true
        *goto fight
    *if (totalattack > 15) and (totalattack < 20)
        *set wolfhealth -20
        You hit! 
        *if wolfhealth <= 0
          *goto win
        *elseif (wolfhealth > 0) and (phealth > 0)
          *set wolfturn true
          *goto fight
    *if (totalattack > 10) and (totalattack < 15)
      You don't hit!
      *set wolfturn true
      *goto fight
    *else
      You don't hit! 
      *set wolfturn true
      *goto fight
	  
  *if (ironsword = true) #Attack it with my ironsword!
    *rand d20 0 20
    *set totalattack jaddstrenght + (jswordat + d20)
    You rolled ${totalattack}!
    *if totalattack >= 20
      *set wolfhealth -30
      You hit! 
      *if (wolfhealth <= 0) 
        *goto win
      *elseif (wolfhealth > 0) and (phealth > 0) 
        *set wolfturn true
        *goto fight
    *if (totalattack > 15) and (totalattack < 20)
        *set wolfhealth -20
        You hit! 
        *if wolfhealth <= 0
          *goto win
        *elseif (wolfhealth > 0) and (phealth > 0)
          *set wolfturn true
          *goto fight
    *if (totalattack > 10) and (totalattack < 15)
      You don't hit!
      *set wolfturn true
      *goto fight
    *else
      You don't hit! 
      *set wolfturn true
      *goto fight
	  

  #Flee
    *goto flee

*label win
You win
*ending

*label flee
You flee
*ending 

*label death
You die
*ending

*label jdeath
Jura died! Dang it!
*set juraalive false
*goto turnset

Is there any particular reason you’re using *fake_choice instead of *choice? On top of that, there shouldn’t be newlines between the end of an #option and the beginning of the next #option.

As a note, if the browser freezes, it’s a good sign you have an infinite loop somewhere. Speaking of which, what first choice did you make?

↑needs to be closed with an *if or *else or *elseif right before " Your health: ${phealth}"

↑All of those should use *elseif

That’s what I can see with a quick glance, try it if you want, I might be wrong though, I’m not a master at coding

@trevers17 uh, you’re right… I might as well use the usual *choice. And for some reason, I just assumed that breaks between things weren’t taken into account by the code. I’ll check if that fixes it.

@Szaal Oh. That kind of makes sense. I’ll check If it loops weirdly somewhere.

Edit: I choose “He fights with a sword.”… I think. Haven’t tried fleeing yet.

@Loudbeat Do I really need to, though? I’ve always used lots of *ifs instead of *else (although I never tried to code something with this many variables) I can’t recall exactly what it says, but it always tells me I’m missing a *goto or something like that which I’m actually not. Though, I’ll go roam the wiki and try to understand elseifs and elses. Thank you all!

The difference between both combinations isn’t significant, though it’s always a good practice to stay on the safe side (which is *if/*elseif/*else)


A simple trick to recognize an unending loop is simply by adding *page_break under *labels you have. This way, you can notice if something is repeating without freezing the browser.

Line breaks and newlines can affect code sometimes. It’s always a safe bet to avoid adding unnecessary ones. If you end an #option with a *goto, then you don’t need a newline or line break after it because you’re already moving on to another section of code.

If you’re talking about the “It is illegal to fall in to an *else statement; you must *goto or *finish before the end of the indented block.” error, it’s because in CS if you use *elseif or *else then your entire structure needs *goto at the end for some reason.

Its a requirement that can be removed and allow you to use *elseif and *else normally instead of using a lot of mutually excluding *ifs (which is bad practice and something that may give you problems with Quicktest). To remove the requiement you can use this:

If someone’s curious (which I know no one is, probably, but I’m here to brag a bit) it was caused by an infinite loop: The character could die and the game would go “now what?” on me, and keep re-rolling like crazy, causing the loop. So I think this thread can be closed now?

Thank you all!