OK, I’m going to think out loud here, lay out the issues that I see and possible solutions, and then you can tell me what I’m missing or doesn’t make sense to you.
Later: This turned out to be very long and maybe incomprehensible. If you have next week off I’ll try to add a bunch of this by the end of the weekend, and do a more coherent writeup. It should be pretty quick; I think most of the work will be checking to make sure that it doesn’t break in odd circumstances.
tl;dr version: you can do most stuff by having card fronts be separate passages from the card contents, and choices be separate cards, and coding the extra non-visibility requirements yourself in the card front or choice. But that’s clunky and I think there are some easy additions I can make to the library which will help a lot.
StoryNexus has the “hand of cards” thing. I haven’t documented doing that with TinyQBN, but basically you save the set of passages to a story variable (one whose name starts with
$). Off the top of my head, you should be able to do
<<set $hand to `QBN.passages(4)`>> to draw an initial hand of up to four cards (less if there aren’t currently four available) and
<<set $hand to $hand.concat(QBN.passages(4 - $hand.length))>>.
Hmm. That will only work with single-use cards: otherwise you may get duplicates in the hand. I’ll add an array merge function to TinyQBN which removes duplicates.
The bigger issue is that I think StoryNexus cards have two parts (I’m not quite clear on this: I’ve never used it and it has been a while since I read the manual): a card front (image?) and the actual contents (story text and a set of choices, which also have requirements?). But Twine passages are a single thing, and TinyQBN has the option to display the whole passage, link to it by name, or give the passage name to a Sugarcube “widget” which does something else with it.
You can, of course, just have two Twine passages for the two parts of the card (maybe giving the contents a normal name and adding " card" to the card front passage?). Which works, but it’s clunky.
It would be better if I made a macro to split it up (maybe
<<card>>front<<contents>>...<</card>>?) But then how does it know which part to show? We could make a widget to set a temporary variable
_card_front or something and then include the passage.
Could we autodetect whether the card is included into another passage (show card front) or visited directly (show contents)? Sugarcube has the
passage() function which gives us the top-level passage that we’re currently looking at. But I don’t think there’s any way to tell what passage is being included inside another. So we’d have to repeat the card name in its code. Not ideal.
Also we need a way to show/hide and lock/unlock choices based on their requirements. TinyQBN currently only works with passages, so right now they would need to be separate cards (with a requirement that says which story card they belong to), I guess? But it should be easy for me to add a macro that allows writing choices inline.
And a way to have visibility requirements. It could be that tagged requirements are for visibility, and the extra ones are hard-coded into the card-front or choice display. You could do that with the current code, but again, that’s kind of clunky.
So probably a different prefix for the tag. So we’d have one that says “required for the card to be visible” and one that’s just “required to access it”. If anyone has any brilliant ideas about naming that, I’m all ears. Maybe ‘req-’ is visibility (to stay compatible with the current code), and ‘also-’ is for requirements that don’t hide it, just lock it from being accessible?
And then a way to tell the display code that a passage should be visible but not clickable.
And, finally (?) StoryNexus displays the requirements and which ones are met and which ones are not. It would be possible to write this part as Twine code, but it would be duplicating stuff that TinyQBN already does, so I should provide a way to get that info easily.
Oh, and there’s the “a low-risk challenge”, “a very chancy challenge”, etc., but I think that would be better done on the Twine side of things.