Not sure if Twine Harlowe does this, but...

Greetings all,

Working on my first Twine project (it’s version 2.11.1.0 if that is important), never did any coding before but with tutorials and Internet search I’ve learned to crawl. I’ve hit a coding brick wall and thought I’d ask for some advice.

My favorite hobby is tabletop board gaming. This project involves taking a skirmish game that is episodic in nature and using Twine to generate narrative options that connect these episodes into an ongoing campaign. Choosing different story paths will lead to different foes, until all paths converge on the big, bad, evil guy at the end.

The players assume the roles of heroes, and two to four of these heroes can be drafted for a given game. At campaign start, they have six heroes in what I’m calling the Ready Roster. When heroes are chosen to take part in a game, their names should move to the Active Roster (allowing me to use if: to create specific events or dialogue to show up if a given hero is present), and if heroes are knocked out of play during a game, their names should move to an Injured Roster, where they are unavailable for the next game while they heal, after which they return to the Ready Roster. As play continues, more heroes will be added to the Ready Roster, where they can be selected for Active, and if knocked out they, too, end up on the Injured Roster.

So far, I’ve tried using an array for each roster, setting up a temporary variable and using set: to it +/- to add or delete names, but this didn’t survive my adding the checkbox macro. It looks like an error grenade went off when i test it. I also tried dividing the task between two passages, but I don’t think I divided the process in the right place for that to work.

Then I thought maybe I should have Boolean values for each hero and each status, so a hero could be true for the ready roster and false for all the other ones, but I wasn’t sure how to tell the checkboxes how to do that.

Then I realized that there are bigger brains than mine, who know Twine can do things I don’t yet know about, and that they hang out here. So here’s a question for anyone interested: What is the best approach in Harlowe to do the following (not sure if all of them can be done in Harlowe, so “that’s not possible” is a potential answer):

  1. Create the rosters
  2. Allow viewers to select heroes from the Ready Roster and move their names to the Active Roster
  3. Allow users to enter if anyone was knocked out, and move those names to the Injured Roster, and
  4. Automatically move injured people back to the Ready Roster after one game

Any ideas about which commands or macros to use would be deeply appreciated. Thanks so much for reading,

Green

1 Like

Is a Hero just a Name (like “Conan” or “Jane”), or are there other attributes like Health Points and the like that also make up a Hero’s definition?

Just a name. Stats don’t change between games. The group may collectively gain or use items, but I an use a generic inventory for that, I think.

The rosters can be Array variables, which you may want to initialise in the project’s startup tagged Passage.

The (for:) macro can be used to iterate the elements of an Array. The following example shows one way to display the Hero’s names in the Ready Roster.

Ready Roster: {
(for: each _name, ...$ready)[
	<br>_name
]
}

The (move:) macro can be used to extract a specific element from an Array. But unfortunately that macro doesn’t handle array element insertion, so a buffer variable will need to be used to temporary store the value until a (set:) macro can be used to do the insertion.

<!-- move 2nd member, which is Conan, to Active Roster -->
(move: $ready's 2nd into _buffer)
(set: $active to it + (a: _buffer))

One issue with the above is that you needed to know the position/index of the Hero’s name in the $ready Array to it can be targeted by the (move:) macro. Harlowe unfortunately doesn’t include a macro for determining the index of a specific array element, so I created the following custom macro to do that. Macro definitions should be placed in a project’s startup tagged Passage.

<!-- Index Of element -->
(set: $indexOf to (macro: array-type _array, any-type _value, [
	(set: _index to 0, _length to _array's length)
	(unless: _length is 0)[
		(for: each _i, ...(range: 1, _length))[
			(if: $array's (_i) is _value)[(set: _index to _i)]
		]
	]
	(output-data: _index)
]))

…the above is used like so…

(set: _index to ($indexOf: $ready, "Name of Hero"))

…so the previous “move” code would change to…

<!-- move Conan to Active Roster -->
(set: _index to ($indexOf: $ready, "Conan"))
(move: $ready's (_index) into _buffer)
(set: $active to it + (a: _buffer))

It may be possible to craft another custom macro that takes the Hero’s name as an argument, that abstracts away the above three macro calls.

1 Like