Harlowe Macros In Saved Games?

I’m running Harlowe 3.3.3 and I ran across this post on Reddit… https://www.reddit.com/r/twinegames/comments/zmajts/harlowe_is_a_workable_story_format_now_even_for/

I noticed some commentary on macros being saved unnecessarily in the saved games. Is this because they are created as $global variables? Or are custom macros, even when assigned to _temporary variables making their way into save game data?

Just curious if I should be doing things a bit differently with that in mind. Thanks!

Temporary variables are not persisted to a Save.

Any Story Variable (what you are calling a $global) that exists when a Save is create will have its value stored in that Save, this incudes macro definitions.

The issue with a macro definition being stored in a Save comes when that save is loaded:

  1. If the Save contains a reference to a current in-use Store Variable then the current value of that variable will be overwritten by the value stored in the save. Which can result in a Store Variable that contains a macro definition reverting back to an older version of that macro definition.
  2. If the Save doesn’t contain a reference to a current in-use Store Variable then that Store Variable may cess to exist. Which can result in the lose of a macro definition, thus causing errors in the code.

One solution to the above issue is to add a numerical “save version” related Story variable to your project, whose value only gets increased each time you build a new release that includes new/changed macro definitions. This will allow you to tell one “save version” from another.

You can then use that “save version” variable within a header tagged passage to determine if a Save created in a previous release has been loaded, and if that old save included macro definitions different that are different to the current release’s. And if it did you can redefine those macro definitions.

eg. Assuming that the $saveVersion of the current release is 5 and that a Save from a previous release whose $saveVersion was 2 has been loaded.
(untested example written in TWEE Notation)

:: Initialise Variables [startup]
(set: $saveVersion to 5)
(set: $ghostlyLaughter to (macro: num-type _o, [
    (output: )+(text-rotate:(random:0,360))+(text-colour:(hsla:0, 1, 0.5, _o))[HE HE HE]
(set: $mean to (macro: ...num-type _a, [
    (output-data:(folded: _num making _total via _total + _num, ..._a) / _a's length)

:: Macro Definitions [header]
(unless: $saveVersion is 5)[
    (set: $ghostlyLaughter to (macro: num-type _o, [
       (output: )+(text-rotate:(random:0,360))+(text-colour:(hsla:0, 1, 0.5, _o))[HE HE HE]
    (set: $mean to (macro: ...num-type _a, [
        (output-data:(folded: _num making _total via _total + _num, ..._a) / _a's length)

WARNING: The downside of the above technique is that that “header” will be processed before every visited Passage.

1 Like

That makes sense, Greyelf. Thank you.

I think I read somewhere that story variables get sent over to each passage. If that’s true, would it not be better to just include all macros as temporary variables in the header? …or is setting all those temporary variables more overhead than passing along story variables? …or am I thinking about it wrong?

Oh, and thanks for all you do. There are answers to questions I’ve found spanning back many years where you’re “the guy” who sets things straight. Don’t burn yourself out, man!

Each time a Passage Transition occurs the current state of altered Story Variables is added to History, this is done in a way that allows for History to be undone one moment (transition) at a time.

During this process all existing Temporary variables are deleted.

The following TWEE Notation based example demonstrates that a Temporary variable doesn’t survive a Passage Transition, as the _temp variable reference in the Next Passage will produce an error…

:: Start
(set: $story to "a value", _temp to "a value")

debug: Story: $story; Temp: _temp

[[Next Passage]]

:: Next Passage
The Next Passage.

debug: Story: $story; Temp: _temp

That’s straight forward and easy to understand. Thanks, Greyelf.

I imagine Harlowe will eventually have some form of global variables that aren’t actual story variables. Until then, I’ll keep pedaling with my Harlowe training wheels on. :slight_smile: