Making Quicktest work with set-by-reference

I’m trying to give the player the option to pick a few stats to increase. It’s something like this:

*title sbr-test
*author atiaxi

*temp str 0
*temp dex 0
*temp int 0

*temp to_increase ""

*label repeat

Increase which stat?
*fake_choice
    #Strength
        Are you sure you want to increase strength?
        *set to_increase "str"
    #Dexterity
        Are you sure you want to increase dexterity?
        *set to_increase "dex"
    #Intelligence
        *set to_increase "int"
        Are you sure you want to increase intelligence?
    *if (to_increase != "") #I'm sure, let's go with it.
        *goto decided
*goto repeat

*label decided
*set {to_increase} + 50

Okay ${to_increase} is now ${{to_increase}}.

*stat_chart
    percent str
    percent dex
    percent int

*finish

That’s not exactly it, but does demonstrate the problem. I can randomtest this all day without issue, but when I quicktest it, I get:

QUICKTEST FAILED
Error: startup line 28: Non-existent variable ''

I believe this is happening because quicktest will spawn off a copy of itself for every branch in the choice, whether or not that branch is actually reachable (as the fourth branch wouldn’t be if the player hadn’t picked a stat). What I’d like to know is:

(A) Is there some way I can tell quicktest to ignore that line? It’s just setting a stat so I’ll be relying on randomtest for actual correctness there anyway, and/or

(B) Is there a clever way to refactor this such that quicktest thinks all its bases are covered?

The fallback is just to write a long series of if (to_increase = str) *set str + 50 style commands, which I’d rather not do if I can do it the more direct way.

There’re recently some topics that asked the same issue as yours. But the point is…

Is this :point_down:t4:

Quicktest refuses this line. So to work around this, put the *if statement on its own line.

IIRC, the error msg will now displays proper message on the latest ChoiceScript.

Changing those lines to:

    *if (to_increase != "")
        #I'm sure, let's go with it.
            *goto decided

Results in the same error, it seems.

(Edit: And running it manually, I get the “illegal to fall out of a *choice statement” error, which makes very little sense given that it’s not a choice and there’s already a goto there)

Hmm… that’s new :eyeglasses:
We’ll see if I can reproduce it once I get my hands on my laptop.

This is a bit complicated but let’s see if I can explain it…

{to_increase} points to something.
Once you set to_increase to something, like str, then {to_increase} will point towards str.

However, you did this: *temp to_increase ""
This is just a space.

You don’t have any “just a space” variables, so when quicktest tries to see what you’re pointing to, and sees “just a space,” it doesn’t like that (it ignores order).

Try this instead:
*temp to_increase "str"

The to_increase variable will change when you pick something, and this way quicktest shouldn’t freak out.
However, if you do this, “str” will be “selected” by default, so you just need to make sure to note that to the player.

Alright! I guess I finally sorted it out (I think).

This is kinda silly, but let’s see if I can explain it coherently.
So, we got this code :point_down:t4:

Code
*title sbr-test
*author atiaxi
*scene_list
	startup

*temp str 0
*temp dex 0
*temp int 0

*temp to_increase ""

*label repeat

Increase which stat?
*fake_choice
	#Strength
		Are you sure you want to increase strength?
		*set to_increase "str"
	#Dexterity
		Are you sure you want to increase dexterity?
		*set to_increase "dex"
	#Intelligence
		*set to_increase "int"  << !!! >>
		Are you sure you want to increase intelligence?
	*if (to_increase != "")
		#I'm sure, let's go with it.
			*goto decided
*goto repeat

*label decided
*set {to_increase} + 50

Okay ${to_increase} is now ${{to_increase}}.

*stat_chart
	percent str
	percent dex
	percent int

*ending

And what happens inside the code is that you’ll encounter the bug only and if only you pick the Intelligence as your first pick.

You see, when you choose [str] or [dex], the code will jump straight to the *goto repeat and do the routine just fine. However, if you choose [int] (as the first pick), you’ll get <to_increase = "int"> and thus it will pass the conditional check (I put a << !!! >> tag on said line of code)

Due to some reason that I don’t know, the *choice command is conflicting with this *if (to_increase != "") because the code thinks that they’re not “leaving the choice body” yet they encounter an *if.

Of course one of the possible workaround is to put an individual *goto under the [int] option.

@dfabulich, mind if I summon you to take a look at this?

Wasn’t it that you can’t use *if in a # fakechoice?

1 Like

I tried it with normal *choice and use the *create implicit_control_flow true, but the result is still the same :/

Bother.
Would a new label work as a work-around in a choice? Maybe?

IDK.
What kind of label do you mean for the workaround?

Either one for every individual stat asking if one is sure. Or put a subchoice in there asking if one is sure and then setting it to the stat (i’m on mobile. Typing code here is a pain. Sorry)

Oh, I see. You mean something like

code
*label up

*choice
  #Opt A
  #Opt B
  #Opt C
*goto surelysure

*label surelysure
*choice
  #Sure
    K
  #Not sure 
    *goto up

Hurray

There is a way to make Quicktest/Randomtest skip lines of code! I can’t double check my own code right now, but I think it’d be:

*if (choice_quicktest)
    *goto elsewhere
*if (choice_randomtest)
    *goto elsewhere

I’m not sure if this is in the wiki; I just saw someone else using it and copied it (I think in one of the demos that came with CSIDE)

2 Likes

As @Alexandra said, you’re going to need to use the testing variables for this:

*temp to_increase ""
*if choice_quicktest
  *set to_increase "str"
2 Likes

In the actual project, I’m choosing three stats out of five, and I’m using the ‘blank’ as a “hasn’t chosen yet”, so having defaults would be tricky… but there’s no reason I couldn’t just have a string that means the same thing, e.g. “TODO”. I like this as a workaround, thanks!

Ah, that makes sense; I can see how falling into an option that wasn’t even displayed before could result in some undefined behavior! This also explains some transient bugs I was experiencing during development (having conversation options open up as you pick individual choices is something I’m doing a lot of)

Ah-ha! The wiki mentions choice_randomtest but the quicktest equivalent isn’t mentioned anywhere. I’ve got a solid workaround elsewhere in the thread but this will help with other issues I was having around gosub_scene. Thanks!

1 Like