CYOA extensions for TADS 3?

Are there any extensions or libraries similar to those available for Infrom for choice-based interaction with TADS? I remember there being something along those lines, but I admit I may be just confusing TADS with Dialog here.

I thought Iā€™d seen some numbered-choice stuff in TADS before, but I couldnā€™t tell you whereā€¦ sorry, not helpful :confused:

1 Like

There isnā€™t anything for T3, only for T2. The closest thing we have is the menu-based conversation library QTalk, which wouldnā€™t fit as it only works for conversations.

1 Like

Depends of what Dissolved means for ā€œinteractionā€. If is an interaction with NPC (or a menu-based device) one can use Qtalk or adv3Lite conversational system (ab)using the topics as choicesā€¦

Best regards from Italy,
dott. Piergiorgio.

While not an extension per se, I do have such a beast implemented in my WIP. It should be packaged into a global function, so here is an untested version of that. First, define numbered list and function:

// custom numbered tall lister, as for selection list
//
class SimpleTallLister: SimpleLister
    showSimpleList(lst) { showListAll(lst, ListTall, 1); }
;
stringTallNumLister: SimpleTallLister
    order = 1
    showListItem (str, options, pov, infoTab) {
        say(order++);
        say('.  ');
        say(str);
    }
    getArrangedListCardinality(singles, groups, groupTab) {
        order = 1;
        return singles.length();
    } 
;

/* =============================================
 *
 *   promptList utility function, prompts user for a number-based
 *        input selection
 *   Parameters:
 *     prompt - Text string prompting user for choice to follow
 *     list - list of strings that are the choices
 *     allowQuit - default true, when true allows user to Q without
 *          making a choice
 *   Returns:
 *     selection value integer, or nil if no selection made
 *     note caller will have to decode results
 *
 * ==================================================
 */
promptList(prompt, list, allowQuit = true) {

    "\n<<prompt>>
        <<stringTallNumLister.showSimpleList(allSections)>>
        <<if allowQuit>>\n\tQ.  Not now, will choose later.<<end>>
        \nSelect:  ";

    local strSel;
    local intSel;
    local num = list.length();
    do {
        strSel = inputManager.getKey(nil, nil).toUpper();
        intSel = toInteger(strSel);
	    "<<if allowQuit && (strSel == 'Q')>><<strSel>><<else>>
            <<((intSel > 0) && (intSel <= num)) ?
                '<<strSel>> (<<list[intSel]>>)' : 'X\nSelect:  '>><<end>>";
    } while (((strSel != 'Q') || !allowQuit) && ((intSel == 0) || (intSel > num)));

    return (strSel == 'Q' ? nil : intSel);
}

That allows it to be used like this:

    local choiceList = ['Red','Yellow','Green']
    local choice = promptList('To what color?', choiceList);
    if (choice == nil) "Ok, come back later.  ";
    else {
        "You set the traffic light to <<choiceList[choice]>>.  ";
        // any other choice side effects
    }

Which gives results like:

>set [something]
To what color?
       1.  Red
       2.  Yellow
       3.  Green
   Q.  Not now, will choose later.
Select:X // if anything other than 1-3 or Q selected
Select:  1 (Red)
//or
Select: Q
Ok, come back later.

// &etc

Will end up refactoring my code to function, and update if any typos found above.

2 Likes

This is wicked. I think this could definitely be used for a Hybrid Choices style experience, which is awesome. Unfortunately, unlike Inform 7, or even TADS 2, it would take too much work to strip the library down and create a library for exclusively CYOA-style experiences, as it would require writing a parser from hand, re-implementing save/restore/quit/undo, Etc.

2 Likes

Oooh, I see. You want to eliminate the cursor prompt altogether, and make every ā€˜turnā€™ be a choice-selection. I think you could implement something like that, where the ā€˜gameā€™ was completely encapsulated in

gameMain: GameMainDef
    showIntro() {
          // entire game implemented (or invoked from) here!
          // never make it to first prompt!
    }
;

but youā€™re absolutely right, the first step would be to create a game implementation infrastructure of nexus scene objects and the link stitching to navigate between them. The mechanics of player choice are the least of the challenges! You would also moot large swaths of the parser and object libraries. It could probably be a really tight grounds up library if implemented that way, but far easier (and kludgier) to just carry all that unused baggage.

I think I tend to agree you COULD do it, but maybe not the best tool for the job.

2 Likes

I formally encourage Eric to consider an (improved) port of JJā€™s adv3 ā€œbeastā€ (which seems tailored for his WIP, so I think that needs a substantial generalisation effortā€¦)

Best regards from Italy,
dott. Piergiorgio.

1 Like

Not TADS related so I apologize if itā€™s off topic, but Iā€™ve implemented a dialogue system in my Unity/C# game. It could easily be ported to make it into a CYOA game. If it would benefit folks here, I could knock that out and share it as a framework people could use.

Example Code for the above

        dg.AddNode(new("node1", "Woman", "The Woman looks at you and smiles."));
        dg.GetNode("node1").AddChoice("Honestly, they can be a bit boring sometimes.", "node12");
        dg.AddNode(new("node12", "Woman", "They chuckle. 'Fair enough. I guess not everyone finds them exciting. What do you do to pass the time?'"));
        dg.GetNode("node12").AddChoice("I usually bring a book or listen to music.", "node121");
        dg.GetNode("node12").AddChoice("Mostly just stare out the window. It's kind of mesmerizing.", "node122");
1 Like