New in ChoiceScript: Limits on infinite loops in Randomtest

It’s possible to write an “infinite loop” bug in ChoiceScript, where the game keeps running the same lines of code over and over again, forever. These bugs can be hard to find and fix.

In the latest version of ChoiceScript up on Github, there’s a new error message you can get when your game goes into an infinite loop during Randomtest.

RANDOMTEST FAILED: Error: startup line 34: visited this line too many times

This error occurs when a line has been run (“visited”) 1,000 times in a single Randomtest playthrough, which is a strong indication that your game has an infinite loop. Without this, Randomtest would just run forever if you hit an infinite loop.

I thought it might be possible that somehow you’d actually want to run a line 1,000 times in a single playthrough, so there’s a command to support that, *looplimit, which you can use like this:

*looplimit 1000000000

*looplimit lets you raise or lower the limit to any number you like. EDIT: You can can also turn off the looplimit with *looplimit 0, but I don’t recommend it. Running a line a billion times should be good enough for anybody. (The maximum possible looplimit is approximately one trillion (12 zeroes), but, seriously?!)

In addition, the latest version of ChoiceScript fixes a bug where text wouldn’t appear in randomtest-output.txt if the game ran forever in an infinite loop.

If you’re having trouble debugging an infinite loop in Randomtest, try running Randomtest with the “full text” option enabled. That will let you see exactly what’s happening during the loop.



Fantastic, thank you for implementing this!


Does this mean that I have to download ChoiceScript from github again?

Oh good. I’ve definitely run into this over the years.

Yes, any time there’s new features you’ll need to do this to use them. You should be able to just replace the new “scenes” folder with your old one and everything should work the same, though.


When I go to, I see that the last “commit” was on Feb 4th. Is the latest version always noted by the date of the last “commit,” and in this case it being Feb 4th?

It says February, but that was the date I made those changes internally, to make sure nothing broke. I published our work in February just today. Before that, the last published change was from August.


Since it says Feb 4th … is it possible the month and day got transposed? They perhaps use the Euro system of dating or visa-versa?

1 Like

One thing I found in the version from last year, and it’s not working in this version either, is that I can’t run the “Show full text during game” option in Randomtest on Firefox. I have to use the command-line version for that (which I prefer anyway, since I can save the output to an external file).

Specifically, the page doesn’t display any output; it just stays blank.

1 Like

I thought I read that there was a new code that was introduced: *next_curl_goes_back, yet it is not working for me. Has this not been introduced, or have I typed it incorrectly?

I have no idea what you’re referring to. *next_curl_goes_back is not a real ChoiceScript command.

What problem are you trying to solve? You’re trying to make the next … “curl” … go “back”? What do you mean by “curl”? Go back to what??

I saw a comment that I thought was resolved that showed how transitions of pages that went from right to left could go from left to right, as if flipping a page backwards, such as has been seen from “show stats” to “return to game.” This command, from my understanding would be able to be used by authors for when they have an “undo” option, such as when a player wants to go back a page when they change their mind on a choice, and the author wants to make it look like the player is flipping back a page in their book.

No, that’s not currently a feature of ChoiceScript. (Maybe someone wrote some modification code that could do it?)

1 Like


I am making narrative fighting games (such as street fighter 2 gams) using choicescript. So combats use many repetitive routines with *gosubs.
Whatever the number of looplimit i choose random tests interrupt due to repetition of rounds in combas.
With previous versions of xhoicescript it worked fine.
So would you please additionnaly allow to simply disable looplimit ?


Can you help me understand your code here? You’re hitting a single line of code more than a million times in a single playthrough? And yet your game actually works, and isn’t stuck in an infinite loop?


Exact, some lines such as the display of life and energy of each fighter -a GOSUB routine) is hit tons of tons of times.



A configurable looplimit would be nice, although I agree that hitting a million seems unlikely in 99% of games.

On a semi-related note, @dfabulich are you aware that nested gosub_scene and return pairs will eventually lead to exceeding the JavaScript callstack limit? Due to how “*return” actually just essentially creates a new (old) scene, rather than actually returning.

Reason I mention this is that I can think of cases where games might bust the looplimit, where there is a heavy use of utility routines, but they’re probably more likely to hit that error first, before they hit the looplimit. So if there’s no plan to fix that, then adjusting the looplimit seems less important too.

1 Like

*return doesn’t pop the stack? That seems… suboptimal.

1 Like

So I believe…
I can reproduce with the following:


*create n 0
*label loop
*if n < 1000
    *gosub_scene scene2
    *goto loop


*set n + 1

Which whilst being a rather atypical example, this should be perfectly fair CS, in my mind.

Browser Errors



However, one thing I have just noticed now, is that I can only seem to reproduce this in ‘compiled’ games. If you run a local web server, or ‘upload’ your files, it seems to work OK. So maybe the problem is more to do with how the scenes are loaded, rather than how the return logic itself is implemented.


I was not able to reproduce the issue when running locally (or uploading on The maze generation (Advanced programming - randomized maze) is fully recursive, and it can get more than 2000-level deep. The engine seems to hold fine.

Does this hold? And note that it would only apply to recursive use of gosub_scene. Recursive gosubs are fine.