How I coded the "Dual Scene Scenario"

I’m making this thread because someone had asked about it over on the Writer’s Support Thread. That, and I am genuinely interested to see if people can workshop it into something more palatable. If you would like to see how the Dual Scene Scenario is played out, you can play my game jam entry here: HALLOWEEN JAM Entries **Beta thread Links** - #17 by poison_mara


Let me preface this by asking you a simple rhetorical question:

What is a ChoiceScript stats screen to you? Is it a place to keep track of character stats? Is it a place to put character descriptions? Is it a place to keep inventory? It certainly can be! However, my idea was something inspired by the premise of my game and by a little game called “The Medium”. In that game, you can swap between two worlds; the spiritual plane and the material plane. With a press of a button, what you’re seeing, what the player is experiencing, and what is happening can completely shift gears. I loved that idea, and I thought it could work very well with interactive fiction.

In Golden Eyes (my game jam submission), the stats screen is a scene the player can access at any time. Sometimes the scene will have nothing. Other times it will have hidden conversations, or choices. regardless of what it has, I treated the stats screen for this entry like a second scene that was continuously ongoing with the main one throughout the story.

Two scenes simultaneously available to the player at all times.

Now, normally this would be impossible, because if you *goto_scene out of the stats screen, the Return to Game button never changes back into a Show Stats button. So, the next time you would hit the show Stats button (which would actually be the Return to Game button) it would take you back to the page which you initially entered the stats screen to begin with. But through a bit of searching, I found a workaround.


A specific command made especially to go from the stats screen to the main story while changing the button back into Show Stats. It’s essentially a *goto_scene that works from the stats page. Here was the problem I ran into. Just like the *goto_scene command, if you want the story to pick up from a specific spot, you need a label. This was the problem with switching constantly between two scenes and having them move together simultaneously. I needed to make it so that every time the player went back to the main story from the stats screen, they would pick up on the page they left off on.

There are over 98 labels in a game with just over 20k words. Almost every single page has a label, and every scene starts off with a massive list of *goto commands that take the player back to the spot they were at before hitting that Show Stats button. Granted, there is one bug I could not fix, simply because of how everything works.

If a player hits Show Stats and uses the Return to Game button instead of the Next button from the page break, they get sent back to the first time they viewed the stats screen in the game. But I did put a warning about this at the very start, so hopefully I don’t get too many messages about it.


So, let’s start getting into how I did this. Firstly, I started with what I would need for the main concept to work and totally didn’t have to add checkpoints at the end because I didn’t think of it until later. Let’s make a list really quick:

A variable to change whenever an optional dialogue is available in the stats screen

A checkpoint variable to put at the beginning of >every page<

A variable to keep track of what scene the 'main story' is currently on

Variables to track when you've seen hidden scenes in the Stats Screen

Here is our scene list for posterity sake


  • So, now that we have our variables, let’s set up something in the Stats Screen in case nothing is happening in it when the player goes to check it.


    This will be at the very end of your stats page because this is what will be triggered if none of the other variables are currently true.

  • Next we’re going to put our currentscene variable at the top of our scene page, to keep track of what scene we’re on.


  • After that, we’re going to put an *if statement for a *redirect_scene command under our “Silence” label in the stats menu. This is the thing we put at the very end of the stats menu.



We’re going to do those last two steps for every scene in the game because in doing this, the stats menu will always be able to keep track of where the main story currently is. If we don’t do this and leave the “Silence” label without these redirects, then it will simply act as a second Return to Game button and take the player back to the first time they checked the stats screen in their playthrough, and we don’t want that.

An extra function of doing this is it means we can put the coding for the checkpoints inside the scene itself, and only have a few *redirect_scene commands in the stats menu. This is important, because you have to remember, we only get one stats screen page to work with. This is imperative to remember because a scene can only hold about 130,000 words before the file size gets too big to be uploaded into dashingdon.

Checkpoints and Optional Dialogue Variable Application

Now, let’s apply those variables we made earlier. First, make a bunch of these off the bat in the very beginning of your scene, underneath the “currentscene” variable.


You can do this immediately because you’re going to have a lot of them, since they’re going to be at the beginning of every page. Not every scene. Every page. Note that you’re not making multiple checkpoint variables that are active at the same time; you’re making one checkpoint variable that changes with each page.


The reason you see my “ICTemp” variable always equal “nothing” is because these are checkpoints for if your player goes back to where they were from the stats screen after checking and not getting a special scene. Essentially, the *currentscene variable tracks what scene they’re on. The *checkpoint variable tracks what page of that scene they’re on. Make sense?

So from the silence label, the game takes them to the correct scene, and at the beginning of that scene, the game checks every single *if checkpoint statement to take them back to their current spot. You can watch it do this in real time via the step system while testing your game in IDE for a better visual representation.

Getting them to see an extra scene is pretty simple; you simply set the ICTemp variable (or whatever you named yours) to “1, 2, 3, etc.” to keep track of what scene it’s triggering in the stats screen.


And in the stats screen

Notice at the end of that dialogue in the stats screen, we have a separate variable for making sure we know the conversation actually happened. This is because we want these scenes to matter and be remembered throughout the game. So, we make variables for each scene in the stats menu. In this case: “IC1, IC2, IC3, etc.” and we set those to “True” at the end of every full interaction in the stats menu. We also have the *redirect_scene command at the end of every full scene in the stats menu.

Those would take the player here, in the main scene of the game now:


By using this *if statement at the top of the scene page:
Note: the picture linked below is of a different conversation’s variables because I was dumb and picked a bad example with IC5.


In that picture, IC7 was just done in the stats menu, and the variable that took them there, ICTemp, is still set to “7”. It is important to NOT set ICTemp to “Nothing” before you get back to the main page, otherwise it’ll default to taking you back to your last checkpoint. It is important that you DO set ICTemp to “Nothing” at the beginning of the page the character is taken back to after they leave the stats page. This ensure the checkpoint system continues working as intended.

And I think that’s the barebones of it. Also, obviously, put the checkpoint labels at the beginning of every page as well, so the checkpoint commands have somewhere to take the player.

I would love to see this system turned into something… easier. I am by no means good at coding. In fact, I’m pretty awful at it. I’m sure with other commands, there are ways to do some of this stuff in a much more simple way, but unfortunately I do not know what they are.

I love innovating this system. I did it with text box investigations, and now I’m trying to do it with this. I’m hoping that by posting this here it shows people that there’s still probably a lot of different stuff we have yet to think of with this software, even if it is one of the simpler ones out there. Lemme know what you guys think and feel free to discuss amongst yourselves of any ways you found to make this process more streamlined!


Really clever. I’ll read through in more detail and try to copy your steps a little later as a challenge.

1 Like

This is really awesome! I love seeing people do cool new things with ChoiceScript.

As far as streamlining, the main opportunity IMO would be utilizing references ({}).

For example, if you made the value of currentscene match up perfectly with the label names (e.g., changed thebedroom to bedroom and theslaughterhouse to slaughterhouse), then this

*if currentscene = "day1"
    *redirect_scene day1

*if currentscene = "day2"
    *redirect_scene day2

*if currentscene = "bedroom"
    *redirect_scene thebedroom

*if currentscene = "slaughterhouse"
    *redirect_scene theslaughterhouse

*if currentscene = "conclusion"
    *redirect_scene conclusion

could be replaced with

*redirect_scene {currentscene}

If you want to get fancier, scene changing commands (*goto_scene, *gosub_scene, and *redirect_scene) let you specify a label. A lot of the *ifs could be eliminated by storing the scene and label names at each label. That way, most of the routing could be handled with a single *redirect_scene {scene_name} {label_name} command in the stats screen.

If you want to get even fancier, you can use expressions instead of simple variables. If you name scenes and labels predictably, the rabbit hole of complex routing is as deep as you’re willing to go.

*title Expression Example
*create checkpoint 0

*label label1
*set checkpoint 1
Text 1
*goto nav

*label label2
*set checkpoint 2
Text 2
*goto nav

*label label3
*set checkpoint 3
Text 3
*goto nav

*label nav
    *selectable_if(checkpoint < 3) #Go forward
        *goto {"label"&(checkpoint+1)}
    *selectable_if(checkpoint > 1) #Go back
        *goto {"label"&(checkpoint-1)}

My ChoiceScript knowledge is lacking, but I’m just amazed by the fact that something like this can be done within it! Maybe not for my current game, but I’m definitely playing around with this for the next one. Thanks for the write-up!

1 Like