I’m not sure how best to describe it, you’d really need to dig into the CS source code yourself to understand it properly, but I’ll give it a go:
Choicescript isn’t really designed in a way in which you can just say “go back to page 5”, pages are decided progamatically as the code is run by page_break’s and the like.
In fact the only way we can track a player’s position in a choicescript game is via scenes (text files) and their line numbers, and of course any precision falls to the latter.
Now if you think of how a lot of the commands in choicescript work, jumping to the wrong line can actually break a game, you can’t say jump to a line that contains a ‘#’ option for a *choice, because without that preceding *choice command, we’d be landed with an error.
This is of course is where the *label command comes in, you can use labels a little like you would bookmarks, but it’s impractical to put labels EVERYWHERE, particularity every-time you stick a *page_break in your code.
So how does all this affect the stats screen? Well another limitation of Choicescript is that it doesn’t really have support for two simultaneous scenes, so in order for the stat screen to be loaded, we need to swap out our game scene. But wait…
If we go back to our previous discussion, this is a problem, what if we’re at a point in our story where there are no labels, how do we remember where the player was in the previous scene? It seems a bit much to take them back to the last label, ideally they’d return to the same page (but remember: we don’t really have any concept of “pages” in CS code).
So how CS does it is it actually sticks the entire game’s - we’ll call it “state” - into a variable/bank and loads a brand new scene, to which we’ll pass a copy of all our variables. When we return from the stat screen all we have to do then is restore our banked/saved state and there we have it, we’re back to exactly where we were before we went to our stats screen, but alas, the bad side-effect of this is that all our variables are reset too.
tl;dr - When you click “Show Stats” for all intents and purposes consider your game saved and a new faux/fake game is started purely for displaying your stats, once you click return to game, your original game is loaded.
Note though that I didn’t write Choicescript (although I’ve worked with and looked through the codebase a fair bit), so don’t take this as gospel, but that’s how I think the stat screen behaviour is best described.
Could it be done better? Yes it could, but it would most likely involve something along the lines of giving CS a proper concept of pages (though in my opinion this would be too fallible), or hacking around the restoration (for example storing variable changes and re-restoring the game variables on return from the stats screen, this does actually work but it is what you’d consider to be a rough, “hacky” job and not particularly stellar or reliable code). Another option would be to simply store the page’s first line number but then you’ve got the issue that on return you rerun all the code and would get *set buildup (*set +5 how ever many times you went to the stats screen and back?).
Well there are a million and one ways to make it work but all would some rewriting of the CS core, which obviously takes time and time is money, and COG obviously haven’t thought this particular issue is quite worth their time (at present), but maybe they will in time.
Your issue with *rand is related to all the above, essentially when you restore the game state from the stats screen it does rerun that page’s code so if you’ve got a random command it’ll be re-randomized, it’s not so much a bug as another unintentional but rather unavoidable side-effect. General practice is to simply roll and set a random value a couple of pages before you need it, it’s not ideal in terms of code legibility I know, but it saves players from the temptation to abuse the roll.