Two <<forgetall>> custom macros to wipe all variables from memory

Please read the comment made by @ TheMadExile below. I will offer revised code in a comment below.


If anyone wants to use a custom macro to wipe story memory clean here are two “forgetall” versions.

Tested on Twine 2,3.15
SugarCube 2.36.1.

The first is to clear story variables in active memory and to clear variables stored to the ‘remember’ cache:

//Macro <<forgetalllegacy>>	Joeyrsp Jan 2022 - For Twine 2 SugarCube 2
// Deletes all story variables in active memory & clears all variables stored in the 'remember' cache

Macro.add("forgetalllegacy", {
  handler: (a, name) => {
        Object.keys(State.variables).forEach(
            (key) => delete State.variables[key]
        );
        storage.delete('remember');
    }
});	

The second is to clear story variables saved using the memorize function to the metadata cache:

//Macro <<forgetall>> Joeyrsp Jan 2022 - For Twine 2 SugarCube 2
// Deletes all variables saved using the memorize function to the metadata cache

Macro.add("forgetall", {
  handler: (a, name) => State.metadata.keys()?.forEach((key) => forget(key))
});

A couple of comments/tips

Macro API handlers, as opposed to legacy macros, do not take parameters, so the a and name parameters in the handlers of both of your macros aren’t being used.

Your second macro could be simplified by use of the State.metadata.clear() static method. Yes, it does exactly what its name implies.

An observation on purging story variables

There aren’t many sane reasons that I can think of to purge all of the story variables. I’d be extremely careful with that.

The <<forgetall>> macros above have been replaced by three non-overlapping macros. These new macros can be used singly or in combination.

//Macro <<clearmetadata>> Joeyrsp Jan 2022 - For Twine 2 SugarCube 2
//Clears the metadata cache

Macro.add("clearmetadata", {
  handler: () => State.metadata.clear()
});
//Macro <<clearremember>> Joeyrsp Jan 2022 - For Twine 2 SugarCube 2
//Clears the remember cache by removing it

Macro.add("clearremember", {
  handler: () => storage.delete('remember')
});
//Macro <<clearvariables>> Joeyrsp Jan 2022 - For Twine 2 SugarCube 2
//Clears the state of variables 

Macro.add("clearvariables", {
  handler: () => Object.keys(State.variables).forEach(
        (key) => delete State.variables[key]
    )
});

If you want to avoid setting up a custom macro you could use these <<run>> statements instead:

For clearing the variables in active memory:

<<run Object.keys(State.variables).forEach((key) => delete State.variables[key])>>

For clearing the ‘remember’ cache:

<<run storage.delete('remember')>>

For clearing metadata:

<<run State.metadata.clear()>>

@TheMadExile said “There aren’t many sane reasons that I can think of to purge all of the story variables. I’d be extremely careful with that.”

The main reason why I use “forgetall” macros is as part of my processes for testing twine projects that are in development. I’ll leave it to others to decide whether that is a sane use.

I’m not clear why you’d need macros for this. For example, instead of writing a whole macro for it, you could just do:

<<run State.metadata.clear()>>

Seems pretty simple to me.

Good point @HiEv. But for developers of twine projects who are not competent in javascript etc, (ie. me and most likely lots of other people) there is a value in using the custom macro format - the macros can be given easily remembered names and so there’s less risk of making an error in typing out the longer <<run>> statement and it’s quicker than copying the right text from a help file. But other people might prefer the <<run>> statements so I’ll add them to my post on the three custom macros (above).

If you can’t remember it, then you have to copy something either way, either the method call or your macro code. Perhaps it’s just my preference, but I try to avoid creating a macro when doing so would add more lines of code than simply executing the code directly.

Also, I believe that instead of doing:

Object.keys(State.variables).forEach((key) => delete State.variables[key])

you could simply do:

State.variables = {}

That should be pretty easy to remember and will run faster as well.

Never mind. :stuck_out_tongue:

Yeah I tried that first but State.variables is read only so I had to mutate it instead of setting it.

1 Like

You’re correct. Good catch! :slight_smile: