Quicktest Failing; Randomtest and playthrough work fine

I’m running Quicktest on my project and it’s failing, even though Randomtest and playing through both work fine.

The error I’m getting is: “Error: wilderness line 1504: Non-existent variable ‘gr_3_10’”

My code (which I will admit is a bit baroque for ChoiceScript, but it does work beautifully) is designed to describe a particular location on a grid. We enter the “wilderness” scene with *goto_scene wilderness leave_city. Since the city’s coordinates on the grid are 3 x 10, we set the grid_x and grid_y variables to 3 and 10 respectively. We then go to the build_map subroutine, and then proceed to navigation.

*label leave_city
*temp grid_x 3
*temp grid_y 10
*gosub build_map
*goto navigation

build_map is a long list of *temp variables. The relevant one is gr_3_10.

*temp gr_3_10 "[City Name]"

navigation uses some charming variable hacks to figure out what’s on tile 3 x 10. The second of these lines is 1504, where the Quicktest fails.

*temp ref_this "gr_${grid_x}_${grid_y}"
*temp tile_this {ref_this}

In other words, the first line sets the variable ref_this to the string “gr_3_10”. The second line sets the variable tile_this to the value of the variable gr_3_10, which should be “[City Name]”. There’s a reason this technique is described in the “truly bizarre references” section of CoG’s Advanced Choicescript page - but I swear it does the job perfectly in playthrough. However, Quicktest thinks that gr_3_10 doesn’t exist, even though it’s set in the build_map subroutine which runs before navigation.

Is it possible that Quicktest isn’t waiting for the build_map subroutine to finish before moving on to navigation? Or does it have a problem with the curly braces syntax? I know that QT will skip any *goto_scene or *gosub_scene that uses curly braces like this, but build_map is a regular old *gosub. I’d hate to lose the power of QT entirely on this work because of this. I suppose, in a pinch, I could intentionally exploit the fact that QT won’t *goto_scene with curly braces and keep it out of the wilderness scene altogether, but that seems like… not a great solution.

(I swear most of my code isn’t nearly as weird as this example makes it look. It’s only one very particular little subsection that does things like this.)

‘gr_3_10’ is different then gr_3_10 … remove the ’ before g and after 10 in line 1504 or make your temporary variable match by adding them.

This is what I would try first.

I’d love to help, but trying to figure this out makes my brain hurt. :confounded:

I’m pretty sure that’s just how Quicktest reports the error. For example, I just added a line to my startup:
*set just_to_demonstrate 50
Quicktest, as expected, says that variable doesn’t exist - and it puts single quotes around the variable name.
Error: startup line 4: Non-existent variable 'just_to_demonstrate'

In any case, line 1504 is:
*temp tile_this {ref_this}
There are no single quotes.

If I recall correctly, Quicktest do the testing by running multiple instances of “playthrough” each time it encounters a conditional check. But I’m not sure if this is your problem, tho.

Quicktest itself is often reported to be clunky; both normal playthrough and randomtest can pass, while quicktest can’t. So, I’m not sure what will be the solution of your problem, but as long as you’re sure you can play that section manually, you’ll be fine.

Is there any reason you are using temp variables for grid_x grid_y ref_this and tile_this? Surely these are repeatedly used so setting them as permanent variables would be better.
Reading through your post it shouldn’t make a difference but it wouldn’t hurt to change it - especially if you add further goto_scene refs later.

1 Like

They’re only used within the wilderness scene; what would be the advantage
of putting them in the global namespace?That would just clutter things up.

The difference between having them as permanent or temp variables would be almost zero. At most, a tiny fraction of a second longer loading time. I have around 700 permanent variables in my game and loading times are absolutely fine. Nothing would be cluttered. If anything, it would be less cluttered as all your variables are in one place. My thinking is that this could possibly be causing you a problem as you used goto_scene. Granted, once in the scene, they should work fine, but you are using some unusual code, so it wouldn’t hurt to simplify it.

Correct me if I’m wrong, but I’m guessing the wilderness scene is used many times during a playthrough. If so, you would be creating those variables every time you go to the scene. It’s possible this is where quicktest is failing as the variables are being reset. Again, having them as permanent variables would be simpler.

Regardless, I understand that different people have different styles of coding and using temp variables is your preferred way. Still, would it really hurt to try changing it to see if it helps with your problem?

3 Likes

At this early stage, there is only one entry point into the wilderness scene. Quicktest is only running it once. Even if that weren’t the case, there’s no reason why the use of temp variables would be the thing causing this problem, as you pointed out.

Avoiding global variables is not just about performance. Global variables increase the complexity of a program dramatically; one offhand use of a variable called tile_this in a completely different scene and my wilderness scene stops working. Avoiding action at a distance is a best practice even in ChoiceScript. If a variable is only relevant to one scene, it really, really shouldn’t be in the global namespace. In any case, it sounds like we agree that the use of temp variables almost certainly isn’t the problem Quicktest is running into.

Looking at your updated first post, I see you have used a gosub command to create the temp variables. While I’m pretty sure that the temp variable would stay active until you leave the scene, I have never tried with a gosub. It’s possible that quicktest isn’t taking them into account when you return. Try making them as permanent variables - if I’m right that would solve your problem.

Note: keeping track of variables to make sure you don’t reuse them is pretty straight-forward, but if you are still not sure, use *comment to help you identify them better.

I’m not sure what you mean by “my updated first post”; I haven’t edited it.

The scope of a temp variable is a scene, not a subroutine - and again, this works just fine when played. If I were having trouble on playthrough, that would indicate that maybe my variable wasn’t initialized properly. But this is a problem limited to Quicktest. I don’t want to refactor my entire novel (which will, by placing everything in the global namespace, make its structure worse) unless I’m actually fixing a problem with gameplay. Mostly, what I’m asking here is “is this a known Quicktest bug, and what exactly is causing it?” I’d rather use the workaround I mentioned originally to cause Quicktest to skip this scene than move more than 200 new variables into the global namespace unnecessarily.

Yes, I understand that the problem is with quicktest and not the code. However it only takes a minute to move 1 variable to see if it makes a difference to quicktest. I understand the reluctance to make the changes wholesale, but I don’t understand the reluctance to try to see if that is the issue. Quicktest doesn’t play the game in a logical way - it makes sense to me that the gosub could be confusing it.

Regarding the original post, my mistake - I reread it and it seemed a little different.

I’ve also noticed Quicktest returning the “Non-existent variable” error for code that (1) works normally for Randomtest and normal play and (2) uses curly brackets to set or call by reference. I don’t want to speculate too much about your code without seeing more of it, but in my case I was able to restructure the code to avoid the Quicktest error (at the cost of a bit of inefficiency).

It sounds like you might be dealing with something similar. I’d like to get a better sense of when this error does and doesn’t occur - not every game needs set/call by reference, but for certain types of code it can be very useful indeed. Feel free to post more, or just PM me!