Multiple Stat Screens & The Latest Version of Choicescript

Note: This is a ‘hack’ and shouldn’t be used if you wish to publish your game through CoG - Instead you should use the supported method of a *choice command inside a stats screen to emulate multiple stats pages. The documentation for this method remains, but the demo download has since been removed. Use is discouraged.

@Marius recently drew my attention to a recent update to the choicescript interpreter which changes how the StatScene is handled. Due to this change the old method we used to add additional stat screens will no longer function as intended (if at all).

Now before I continue let me say: Choicescript’s update did not break your game.
Multiple stat screens are a concept the community came up with and are not (and never have been) supported or endorsed by CoG. When we ‘hack’ things like that, we don’t really have a right to complain about it, or expect them to fix it.

However, since many people have found this useful in the past and will probably continue to desire multiple stat screens in the future, I have come up with two (well one) solution(s):

- Just don’t upgrade

  • If you really must (new author) or have already upgraded, I’ve devised something of a way to use multiple stat pages with the new code updates, and while it seems to work, it is not a perfect,clean and guaranteed to solve all your problems etc etc etc

The How

You’ll need to edit three javascript functions, in two of our favourite files, and of course add your buttons inside index.html and create your stat scene text files.

stat scene text files
index.html (add your buttons)
ui.js (edit two functions)
scene.js (edit one function)


Create Your Text Files

It does not matter what you call them, but try and keep it logical.
They go in the scenes folder like any other stat file:


Adding Buttons (Index.html)

Add a button for each of your stat pages here, note that unlike the old method the element’s ID does not matter, so you can leave them all as statsButton.

The important bit that you need to change is the text inside the showStats()'s brackets.
Here you need to put the name of the scene text file that particular button is supposed to open, without the file extension .txt and enclosed in SINGLE quotations ‘like so’.

Image


function showStats() UI.JS

Things might start to get a little tricky here, so feel free to download the ‘demo’ pack from below and just copy and paste the ui.js from there, you’ll still need to make a few edits, but the bits that need changing are obvious enough.
I’ll try to keep it simple though:

  • Add the word scene inside the brackets of 'showStats()', like this: showStats(scene).
  • On the line beginning with var scene = new Scene("choicescript_stats"... Etc - Replace "choicescript_stats" with the word scene, without quotation marks.
  • Add an additional IF after the first one's FIRST curly brace: `if (window.stats.sceneName == scene) { `
  • Move the next three lines of code (clearScreen, return etc..) to be after your NEW (second) if and then add an additional curly brace after return; to close the new if.
  • Lastly, return to the first if - the one with "choicescript_stats" in it. You need to use javascript's or operator which is || to add all your stat screens to this if (see the picture below).

    Image


    function printFooter() UI.JS

    Much easier, in this function we’re merely commenting out (or deleting, but I recommend commenting) out code using two forward slashes before a line //This is a comment.
    Or using opening and closing comment tags: /* This is a comment */
    See the picture below for exactly what needs commenting out.

    Image


    *finish command - Scene.js

    Now inside the scene.js file find the *finish command function and repeat a step similar to the last one on the showStats() function. We just need to edit the condition to include all our new scenes with || operator.

    Take care however to re-include the “&& this.originalScene” for every single or (see picture).

    Image


    If all else fails, check the pictures and/or download the template and trial and error edit:

    Demo/Template
    Removed by Author

    I hope this helps people, I tried to keep both the method and implementation/tutorial as simple as possible and the lack of any real explanation is part of that. Please let me know if you encounter any problems.

    Things to Note

    • The stats screen buttons will not change or hide/appear - they’re always there.
    • Clicking a second stats button while in another stats screen will take you to the new stats screen.
    • Clicking the stats button belonging to the stats screen you’re currently on will return you to the game.
    • Clicking next at the bottom of any stats pages will return you to the game.

Update: Already I may have found a bug with this method, though I can’t confirm it yet. But as I mention in the above post, this is NOT a perfect/proven method, you have been warned!

…Backup your work before attempting any modification :slight_smile:

EDIT: Confirmed bug with the scene.js edit, it prevented loading of new scenes.
I’ve fixed it and updated the tutorial/images and downloadable demo.

Seems fine now.

Is it possible to hide certain ones and only have them available at certain times?

yup i need to know the same thing

To add to my previous question, can you also link them? Like the first one is your primary, but on occasion you have need of a separate stat screen but still want what you do using the other stat screen to effect the primary.

You can hide stats but it requires if and an additional stat chart in the stat file.

@fantom @irule9344

To hide them you need to assign each one a unique id, I mention that you don’t need to do this in the tutorial, you DO if you wish to show/hide them at will.

Once they have a unique id you can use the following lines of code inside your choicescript scenes:

To show the button:
*script document.getElementById("statsButton1").style.display="inline";
and to hide the button:
*script document.getElementById("statsButton1").style.display="none";

You replace statsButton1 with the id of the button you wish to hide (hence why they all need unique ones).

If you only wish to hide content on a stat screen but not the screen itself, @Nocturnal_Stillness has the right idea.

I’m not sure what you mean by “linking” them though.

ok i still need help hiding certain stats help plz plz trying to learn for 2 week allready

I just want to say thank you very much for making this guide. It was extremely helpful in implementing additional buttons.

@FairyGodfeather You’re most welcome!
And thank you for letting me know it was of use to you - it makes it all worthwhile.

I’ve implemented this after updating to the latest version of ChoiceScript, and I have to say, it’s been a big help, especially since I have so much reference material to organize.

One question though: When you click on a button and move to the corresponding stats screen, then click it again, it moves back to the scene where you were before.

Is there a way to make the button not do that?

@Cataphrak In ui.js function showStats(scene)


     if (window.stats.sceneName == scene) { //Is the button pressed the current scene's button?

Change that line to:


     if (window.stats.sceneName == "choicescript_stats") { //Is the button pressed the main stats screen/can we return to game?

That will make it so clicking the first button WHILE on the first page will return to the game, but clicking buttons 2 and 3 won’t do anything except move to that page - it won’t close them if you click it again while on that page.

Hmm, that’s not *quite* what I wanted.

Basically, I’m looking for a method to make it so that if I click my stats screen button in the main game to enter the stats screen, then click the stats screen button again while in the stats screen, I’ll remain in the stats screen, instead of returning to the ingame scene I had entered the stats screen from.

It might be less confusing if I just said I wanted a particular menu button’s function disabled while I was on the corresponding page.

EDIT: Wait, I just commented out that section governing bit of functionality. That won’t come to bite me in the ass later, will it?

Well commenting that out will effectively leave you stuck in the stats screen for all eternity, so maybe :smiley:

Scratch that, I forgot about the next buttons - You should be fine!

I’m guessing it’s a problem if, when you start your index, it’s loading infinitely? My guess: I did something wrong. It also says, before I allow it, that internet explorer has restricted this page from running scripts or ActiveX controls. Then…yeah, infinity loading. Oh, and where you had ‘choicescript_stats 2’ I have ‘choicescript_stats King Relations’ because of the name I gave the file. Also, when we edited FootPrinter (don’t know what to call it), I was on line 165, not 168.

So, any thoughts on the problem at hand (and, preferably, how to fix it)?

There’s quite a lot you *could* be doing wrong, looking at the top of IE and allowing scripts and ActiveX to run would be a good start!

Copy and paste your code between `


` tags, and I’ll take a look.

@CJW Alright, thanks. Also, what is IE? I’ve already allowed scripts and ActiveX to run.

<p><button id="statsButton" class="spacedLink" onclick="showStats('choicescript_stats')">Show Stats</button> <button id="statsButton" class="spacedLink" onclick="showStats('choicescript_stats King Relations')">Show Stats 2</button>  <button id="restartButton" onclick="restartGame('prompt')">Restart</button></p>

All of that is line 79.

function showStats(scene) {
    if (window.stats.sceneName == "choicescript_stats") {
     if (window.stats.sceneName == scene) { //Is the button pressed the current scene's button?
      window.stats.scene = window.stats.scene.originalScene; //If it is, return to game.
	  clear Screen (loadAndRestoreGame) ;
      return;
	   }
    }
	//Else, in any other case: Load selected stat screen.
    var currentScene = window.stats.scene;
    var scene = new Scene(scene, window.stats, this.nav);
    scene.originalScene = currentScene;
    main.innerHTML = "<div id='text'></div>";
    scene.execute();
}

Lines 54 to 68.

function printFooter() {
  // var footer = document.getElementById('footer');
  // We could put anything we want in the footer here, but perhaps we should avoid it.
 /* var statsButton = document.getElementById("statsButton");
  if (statsButton) {
    if (window.stats.sceneName == "choicescript_stats") {
      statsButton.innerHTML = "Return to the Game";
    } else {
      statsButton.innerHTML = "Show Stats";
    }
  } */
  setTimeout(function() {callIos("curl");}, 0);
}

Lines 176 to 188

// *finish
// halt the scene
Scene.prototype.finish = function finish(buttonName) {
    this.paragraph();
    this.finished = true;
    var self = this;
    if (this.name == "choicescript_stats" && this.originalScene) || "choicescript_stats King Relations" && this.originalScene) {
      printButton(buttonName || "Next", main, false,
        function() {
          window.stats.scene = self.originalScene;
          clearScreen(loadAndRestoreGame);
        }

Lines 526 to 537

Thanks again!

(Note: the first code is in index.html, but apparently it’s all good…

In the prototype.finish function:

if (this.name == "choicescript_stats" && this.originalScene) || "choicescript_stats King Relations" && this.originalScene) {

^There’s a closing parenthesis (bracket) before the first OR (||) - Remove that.

@CJW Still a no. Any other problems you’re seeing (and would this accursed Windows 8 count as a problem)?