Harlowe 3.0.2: Creating a character "diary"

I’m creating a highly tailored story, but I’m having some trouble finding a way to implement a diary that records what happened to the character beforehand.

My ideal solution would be a passage that recounts what the character has experienced in the past, along the lines of:

Jan 1261
Got a birthday present from my mother.
Fell from a tree and broke my ankle.
Stole a chicken to win a dare and now have to do community service for the rest of the year.

Jun 1261
Skipped community service for three months in a row, so I got expelled from school instead.
My friends don’t answer my calls.
I fell from a ladder and broke my ankle.

Jul 1280
Got into a bar fight and won.

Can someone please point me in the right direction?

There are many different ways to implement this in Harlowe 3. What you need to think about first is what data matters the most and how you want to work with it.

For example, looking at the dates themselves, are certain dates more important than others? Is there a sense of “time” within the story where it passes if certain things happen (i.e. the story ends each “day” and then time passes)?

Fixed Dates

If the dates are fixed, you could use an Array to store the values in order. That might look like the following:

(set: $dates to (a: "Jan 1261", "Jun 1261", "Jul 1280") )

Then, for the passage in which you show them, you might do something like this:

(for: each _date, ...$dates)[
**_date**
Event that happened.
]

Dynamic Dates

If the story is more dynamic, you could start with an array and then increase the date each time. So, for that, it might work like the following to set it up the first time:

(set: $day to 1261)
(set: $month to "Jan")
(set: $dates to (a: $month + " " + (str: $day) ) )

(Notice that in the above code, I used the (str:) macro to convert the number, 1261, into a string before “joining” it to the value of $month, which is a string.)

Each new day, would be something like the following where $day is increased and then added to the existing array of values

(set: $day to $day + 1)
(set: $dates to it + (a: $month + " " + (str: $day) ) )

To show the array, the previous code to “loop” through the array could be used.

Testing for Events

With the dates figured it, the next problem is how to show the events. Again, like before, what events are important? Are they fixed? Are they binary – that is, can either one thing or another happen?

If the story has a simpler branching structure, this is easier to test for an arrange. Something to consider using is a series of (if:) and (else:) macro usages.

(if: $birthdayPresent is true)[
Got a birthday present from my mother.
](else:)[
Skipped the birthday party
]
(if: $fellFromTree is true) [
Fell from a tree and broke my ankle.
] (else:) [
Didn't climb tree.
]

Hopefully this can get you going on how to organize things into an initial diary structure where you are considering the story and how to store and work with its data.

I have the time passing covered, so don’t worry about that.

While your solution is not quite what I was looking for, you gave me new ideas on how to organise the “diary” that might actually work, so I’ll mark it as solved anyway.

Thank you!

This may not be what you’re looking for (and I know it’s a little late to the game), but I’m gonna leave it here it case it helps (or if anyone else searches this topic in the future).

This is based off of something else I was using for giving feedback on decisions, but I adapted it to a diary.

Basically, each event gets stored in a datamap, where the key is the date/time, and the value is the event. For example, if you eat breakfast at 7am, the key is “7am” and the value “Ate breakfast”. You then store the datamap for each event in an array, which is your diary. As events happen, you add them to the array. You can then print items in the array to view past events (read diary). See example below:

(set: $diary to (a:))

{
(link:'Eat breakfast at 7am')[
	You eat breakfast at 7am
	(set: $diary to (it + (a:(dm:'7am:  ','You ate breakfast'))))
	]
}

{
(link:'Eat lunch at 12pm')[
	You eat lunch at 12pm
	(set: $diary to (it + (a:(dm:'12pm:  ','You ate lunch'))))
	]
}

{
(link:'Eat dinner at 5pm')[
	You eat dinner at 5pm
	(set: $diary to (it + (a:(dm:'5pm:  ','You ate dinner'))))
	]
}

{
(link-repeat:'read diary')[
	(replace:?diarytext)[
		(for: each _event,...$diary)[
			(print:_event)
			(print:' ')
			]
		]
	]
}
---

|diarytext)[]

A couple things to note:

  1. This is set up to all be on one page for viewing purposes. You’d want to set the $diary array in a startup passage so it doesn’t get erased, and things happening on individual passages would get added as they happen.
  2. The ‘read diary’ option can go in a footer passage, if desired.
  3. Currently, each datamap is only 1 key/value pair long. However, you could have each day be a datamap, with individual keys/values being specific times/events. For exampe:
(set: $dayone to (dm:"7am","Breakfast","12pm","Lunch"))
(set: $diary to (it + (a:$dayone)))

Also of note, because arrays can contain duplicate values, if you have items added to the diary upon entering a passage that players can enter multiple times, you’ll need to safeguard against adding the same event twice.

The dynamic dates mentioned above can by passed into the datamap instead of a set time:

(set: $diary to (it + (a:(dm:$date,'You ate dinner'))))

Hope this helps!