Randomtest and gosub_scene

I’m having trouble with randomtest.

The error I’m getting is:

RANDOMTEST FAILED: Error: international13 line 1338: invalid return; we’ve already returned from the last gosub

The issue is that there shouldn’t be an error. The only way to get to the scene is via gosub_scene. I have one instance of gosub_scene international13 in another scene and I don’t have goto_scene international13 anywhere. In international13, there is only 1 instance of *return. In practice the game runs fine and there are no problems.

I believe the error is occurring now that all scenes have to be listed in startup. The randomtest will fail on all scenes that are only accessible via gosub_scene. Can anyone think of another reason and suggest how to proceed? The best way I can think of would be to remove the pointless new rule of all scenes having to be declared in startup…

Perhaps, via “jumps”, you can actually go reach the *return?
(Like *fake_choice and multiple *if that can be “jumped through” without using *goto or *gosub)

You shouldn’t have to do this, but…
Have you tried replacing *gosub with *goto and just return it manually instead of using a *return?

I had a similar problem – a gosub had a gosub_scene within it, and Randomtest got stuck after it returned to the original scene (the second scene, btw, still isn’t listed in startup and I haven’t seen any problems with it otherwise). I’d had the code running fine, and hadn’t been using randomtest, so I’m not sure what triggered it (because I think it’d passed randomtest before – my guess would be adding a *fake_choice confused things). Never figured out why, but, like @Carlos.R suggested, ended up using goto’s to get rid of it.

If y’all think there’s a bug in ChoiceScript, please provide a sample game that reproduces the bug and we can investigate. In general, if Randomtest got to the scene, then it found an actual way to get there; a human could get there the same way. Follow the log of choices to see how it did it.

Most likely, you accidentally got to the end of the file when you intended to *goto somewhere else, *return, or end the game with *ending. international13 was probably the next scene in the *scene_list, which is why it broke.

To be clear, declaring all scenes in the *scene_list isn’t a new “rule,” it just works around a QuickTest issue. There are other ways to workaround the QT issue which you may prefer.

  1. You can just delete the gosub-only scenes from the *scene_list. QT will automatically test the scenes in *scene_list and any scenes that you explicitly refer to with *goto_scene or *gosub_scene, e.g. *goto_scene animal. QT will ignore scenes that you refer to in curly braces, e.g. *goto_scene {next_scene}.
  2. In response, you can create an *if choice_quicktest section, like this:
    *if choice_quicktest
        *gosub_scene x mylabel
        *gosub_scene y label2
        *gosub_scene z whatever
  3. But all of that is weird and confusing for most authors, so the easiest thing to do is just put all of your scenes in the *scene_list. Consider putting a *bug command at the top of the scene, like: *bug This scene should be unreachable except by *gosub_scene. Then you can *gosub_scene subscene mylabel to use your scene.

Hmm, I tried to undo my fix and now it’s not giving an error anymore. Can’t remember everything else I’ve changed about the sequence since then (it was also before I installed CSIDE, so there may be other factors here…) The subroutine was just after *finish, so if the game somehow managed to skip the finish command, that is where it’d get stuck.

So the only reason I’d have to put something in the scene_list would be to make sure it got tested by quicktest (which would only be a problem if it wasn’t referenced by another scene somewhere)? I’ve got a (long) chapter planned that has two completely different versions, and was planning to leave them both out of the list and access them only with a goto_scene…

That should work. Let me know if you run into trouble.


Edit: Ignore this message. Improved demo listed below.

Have you tried adding a *finish at the bottom of that *return just to see what happens?

Adding finish wouldn’t work as it would never be reached. The *return command would always take prescedence.

I recreated your code on my end, here, and randomtest runs just fine.

It goes into infini-loop.
Even with only 5 iterations :thinking:
The seed number doesn’t change either.

I think randomtest don’t detect the *ending tag (which I added at the very last line of startup.txt), or perhaps the randomtest chooses the #Play again option when it reached the *ending tag.

Perhaps this is the case, @dfabulich?

I’ve revised the demo as it could be suggested that quicktest is failing as the scene loaded after startup is gosubtest.

This new demo has 3 scenes - the second of which is a goto_scene that bypasses the gosubtest scene at the end of startup.
It’s now impossible to reach gosubtest without the gosub in startup. Randomtest still fails with the same error message.


*title The Kepler Colony: Evacuation
*author Andy Why

This is the startup page for gosub_scene testing.
  #Test gosub_scene
    *gosub_scene gosubtest
    *goto label1
  #Reload this page.
    *goto label1
*label label1
This is the end of the test
*goto_scene final


This is the final scene.


This is the test page for gosub_scene.


I can pass randomtest by removing gosubtest from the scenelist. The game then fails quicktest.
It’s becoming ever more clear that randomtest is testing each scene individually…

FYI, *finish is basically *page_break and *goto_scene combined, so I don’t expect it to terminate/end all blablatest runs :"

Yes, *finish should take you to the next scene in the scene_list. The way I have it now, there is no scene after final.

This isn’t happening with quicktest. If I do not include the scene in the scene_list, I get this error:
ERROR: couldn’t open gosubtest.txt

Using {} for the scene name throws up an unknown variable error.
Adding the variable to startup and naming it the scene name throws up another new error:
ERROR: couldn’t open gosubtest.txt

Could you clarify what you expect/desire to happen in this test vs. what actually happens? A good bug has all three components: steps to reproduce, expected behavior, and actual behavior.

As I read the sample, the sample is indeed buggy code. Randomtest will catch the bug, but you can find the bug yourself manually just by playing the game.

To reproduce: Open the sample game in a browser. Select either option, then click “Next Chapter.”

Actual: After you click “Next Chapter,” the game fails with an error message, “gosubtest line 2: invalid return; we’ve already returned from the last gosub”

Expected: At the end of the final.txt scene, there should be an ending menu (Play Again, Share this game, etc.)

You can reproduce this bug with randomtest, too.

*****Seed 0
startup *choice 9#2 (line 13) #Reload this page.
RANDOMTEST FAILED: Error: gosubtest line 2: invalid return; gosub has not yet been called

Fixing the bug in the sample is straightforward: change the *finish at the end of final.txt into an *ending command. That fixes randomtest and fixes the bug in your browser.

Does any of this have anything to do with your international13 problem? It’s hard to say, without knowing your intended expected vs. actual behavior in the sample.

EDIT: Ohhhhh, I get it. The sample you posted as-is is buggy, but if you remove gosubtest from *scene_list, you’d expect all tests to succeed, but instead, quicktest fails, and that is a bug in quicktest. I just fixed it in the latest version of ChoiceScript up on github!

If you upgrade, start with your sample, and remove gosubtest from *scene_list, the game works fine in the browser and passes randomtest and quicktest, but quicktest gives you a warning:

final line 2: WARNING there is no next scene; *finish will end game. Use *ending instead.

It’s a good warning! Be sure to use *ending when you mean to end the game; don’t just *finish and rely on that to end the story.

Thanks for your patience and your help reproducing the issue.


…And that is indeed the error I made! :). The scene prior to international13 is huge and does have one game ending option within the scene. I had closed with *finish instead of ending so of course it didn’t like it. Thankfully (okay, stupidly) I made the same error in the post here which highlighted it. Everything works as intended now :slight_smile: