Ignore "when play begins" rules when restarting

I have a title screen at the start of my game that uses Basic Screen Effects to work. When the game ends and restarts, the title screen appears again. How can I make it ignore the “when play begins” rule after the first bootup?

First when play begins:
		center "[bold type][story title][say default type]";
		center "[roman type]by [story author]";
		say line break;
		center "Press SPACE to begin.";
		wait for the SPACE key;
		clear the screen;
		say line break;
		rule succeeds.
1 Like

I guess my first question is – do you really want it to ignore it? The RESTART command in parser games traditionally acts like flipping the power off and on. People won’t be surprised to see the title screen again, and they won’t mind hitting SPACE one extra time (as per the rule you’ve shown here).

If the ‘when play begins’ rule(s) asked lots of questions, or caused intentional delays or went through long cut-scenes, then players might get pissed off at being made to sit through them again. But in general, they don’t mind what you’re describing.

Now forgetting the question of If – How?

Because RESTART totally flushes the game’s memory of itself, you can’t use a variable. An easy way to do it is to use a temporary file.

e.g. If player types RESTART, the game writes a tiny file whose existence acts as a flag. Then the ‘when play begins’ rules check to see if that file is present. If it is, they know the player typed RESTART and you skip the rule(s) you want to skip, then delete the file. If the file isn’t there, the game will do the usual startup routine.

I’ll just write an example then put it in the next post.

-Wade

2 Likes

Click the arrow to see the code. You can test this out by running it, doing a RESTART and seeing that it skips the title page. Then do a quit. Then re-run it from scratch and you’ll see you get the title page again.

Summary
"Restart Flag File Demo" by Wade Clarke.

Include Basic Screen Effects by Emily Short.

Test lab is a room. The player is in test lab.

Part - When play begins rule

When play begins (this is the print the title page if the player did not RESTART rule):
	if the file of restart-signalling exists:
		delete the file of restart-signalling;
	otherwise:
		center "[bold type][story title][say default type]";
		center "[roman type]by [story author]";
		say line break;
		center "Press SPACE to begin.";
		wait for the SPACE key;
		clear the screen;
		say line break;
		rule succeeds;

Part - The table and the file of restart-signalling

table of restart-signalling
truthy(a truth state)
true

[the table content is irrelevant, but to make a file from this table, the table needs to have an entry]

The file of restart-signalling is called "restartflag".

Part - Rewriting the RESTART action so we can tap into it

new-restarting the game is an action out of world.

Understand the command "restart" as something new.
Understand "restart" as new-restarting the game.

Carry out new-restarting the game:
	say "Are you sure you want to restart? ";
	if player consents:
		write the file of restart-signalling from the table of restart-signalling;
		follow the immediately restart the VM rule;

Part - Adding a file deletion function with some I6 code

Include (-
	[ FileIO_DeleteFile extf fref struc rv usage;
	if ((extf < 1) || (extf > NO_EXTERNAL_FILES)) rfalse;
	struc = TableOfExternalFiles-->extf;
	if ((struc == 0) || (struc-->AUXF_MAGIC ~= AUXF_MAGIC_VALUE)) rfalse;
	if ( struc-->AUXF_BINARY )
	{
		usage = fileusage_BinaryMode;
	} else {
		usage = fileusage_TextMode;
	}
	if ( struc-->AUXF_BINARY & 2 == 2 )
	{
		usage = usage + fileusage_SavedGame;
	} else {
		usage = usage + fileusage_Data;
	}
	fref = glk_fileref_create_by_name( usage, Glulx_ChangeAnyToCString(struc-->AUXF_FILENAME), 0 );
	rv = glk_fileref_delete_file(fref);
	glk_fileref_destroy(fref);
	return rv;
];
	
-).

To delete (filename - external file):
	(- FileIO_DeleteFile( {filename} ); -).

This isn’t the only way to detect a RESTART. For instance, there’s another way where you reserve some memory that survives the RESTART and can be checked afterwards, but it too would involve the addition of some I6 code. The way I’ve shown here is the way I do it myself.

PS - The temp file the game creates has the name restartflag. But what suffix it has, if any, will depend on what IF interpreter creates it. For instance, the Macintosh IDE creates a file called restartflag.glkdata. Of course, you are unlikely to ever see this file, as within milliseconds of it being created, the game deletes it :slight_smile:

-Wade

6 Likes

One other tricky option I’ve used (@severedhand’s code basically does this manually) - Emily Shorts “Recorded Endings” extension (from that link, or I believe it’s in the IDE Public Library) can write a bit of data outside your code. I used it in Baker of Shireton to change what error/bugfix messages showed up at the beginning of the game. It’s intended to remember game endings like an achievement list, but I used it to remember some game-state between restarts without necessarily ending the game.

You declare a file to write to in your code (see the documentation, it’s one line) and then for your title screen, you’d add code like:

First when play begins: 
     if "Saw Title Splash" is not a used ending:
          center "[bold type][story title][say default type]";
          [...]
          record "Saw Title Splash" as an ending;
          rule succeeds;
     end if.

That way your title splash only shows the first time even through restarts, and you won’t have to goof with the “when play begins” rule.

The extension also adds an ENDINGS command to the end of the game, (Would you like to UNDO RESTART RESTORE…" but I was able to modify the extension to turn that off if you don’t want the player to see this.

3 Likes

Just for public reference – the I7 Extension Library on Heroku hasn’t been maintained for a while; the Friends of I7 Github repo is the most up-to-date and comprehensive source of extensions.

(But it doesn’t make a difference in this case, the Friends of I7’s Recorded Endings is the same. Except, weirdly, that the I7EL copy’s version number has a date suffix and the Friends copy doesn’t.)

3 Likes

Just for the record, here’s a link that shows how to use protected memory:

I prefer that way, since it involves less complicated I6 than your file example, and it doesn’t do any file I/O. But both ways are OK, really.

5 Likes

Thanks for this link. I never saw a bit of nice, basic code for this before.

-Wade

2 Likes