pauseForMore being called before double quoted strings are being printed in scene start?

Basically, I want to imitate how days work in Anchorhead or chapters in King of Shreds and Patches, where you print a bunch of stuff following on from an action, then pause for more, then clear the screen and print a chapter title and some more text. I’m making chapters roughly correspond to scenes, so when a new chapter starts I have the corresponding scene start and then have some code roughly like this in whenStarting:

whenStarting()
{
    "Text here";
    "Text here";
    inputManager.pauseForMore();
    cls();
    "Chapter title heading";
    "Call to action text";
}

The problem is that pause for more gets called first somehow, and then cls, and then all the text prints. Is there a way to force this stuff to happen in the right order?

1 Like

Ohhhhh, I remember pauseForMore having issues, and reading about a better alternative somewhere. One sec, I can probably dive for a solution from mobile.

EDIT: Oop! Nevermind, you’re already using the alternative!

Oh no! Now I have no idea how to fix this lol

1 Like

Is this method being called directly from some action code? Like:

dobjFor(Take) {
    action() {
        ...
        whenStarting();
    }
}

Because printing stuff within the action() bit has weird side-effects for some reason, so you might see better results by using extraReport('Text here'); instead.

Again, assuming this is what’s causing the problem.

I’m calling chapter2.start() in the action, but yeah the fact that it’s being called within the action might be the issue. I originally tried doing an afterAction function, but the door is locked so the action doesn’t pass the check stage, meaning afterAction never gets called. I’m really not sure where else to put everything now, since it seems like neither afterAction nor action will work…

1 Like

OH!! Wait!! I think I have a solution!

// Call this from your action instead
startNextChapter()
{
    // This forces the method to be called from outside
    // the action cycle, but still during this turn.
    // This should hopefully avoid the issues.
    
    // This line is here if you put the startNextChapter()
    // method in your scene object.
    // local scene = self;
    
    // This line is here if you put the startNextChapter()
    // method somewhere else, like in your action-
    // handling dobj.
    local scene = sceneObjectNameGoesHere;
    
    // This is the line that calls the scene's
    // start() method outside of the action-handling
    // cycle.
    // The "0" is the turn offset, so this will fire
    // upon the end of the same turn.
    local startFuse = new Fuse(scene, &start, 0);

    // This next line is to try and execute this immediately, before
    // anything else might also run.
    // This is not a guaranteed solution, and in some cases
    // you might want to use a OneTimePromptDaemon instead.
    startFuse.eventOrder = 1;
    
    // If you would rather use a OneTimePromptDaemon,
    // then it can be done with the following:
    // new OneTimePromptDaemon(scene, &start);

    // In the case of a OneTimePromptDaemon, it is not necessary
    // to alter the eventOrder.
}

// This is the method in your scene object
whenStarting()
{
    "Text here";
    "Text here";
    inputManager.pauseForMore();
    cls();
    "Chapter title heading";
    "Call to action text";
}

EDIT: I’m writing all of this from memory on mobile before my meds are kicking in, so it isn’t exactly tested yet lol. Disclaimer.

EDIT 2: Re-arranged the code and added some clarifications for our future explorers! :smile:

EDIT 3: Tweaked the code to acknowledge possible problems with atmospheric daemons and NPC actions.

1 Like

Ooh, I can totally see this working. Let me try it! Damn, there are so many ways to do things in TADS, it’s really cool

2 Likes

It’s why I’m a fan. :grin: If I ever get stuck, there’s usually an alternative.

And if there isn’t: I’m allowed to gut the library and add enough modifications to make it work, lmao.

2 Likes

It’s such bad coding practice for normal software architecture, but for a one person literary project it’s so damn convenient.

This is why TADS reminds me of Ruby. It has the same kind of approach that relies heavily on everything being an object, extreme late binding, everything being as dynamic and organic and modifiable as possible, with lots of syntactic sugar for things to make them more convenient. It really has the same feel of being an intensely fun, flexible language to use and prototype in.

2 Likes

Oh, absolutely. I would never do this to proper libraries in Java/C++/C#/JavaScript.

I literally only do this in TADS because it has the modify keyword, and libraries tend to be specialized for one specific kind of game, whereas I want to go absolutely wild with new mechanics and gameplay loops in a TADS game.

2 Likes

It seems really concerning if Lite can’t properly handle Pause from within an action() method… the Fuse seems very unnecessary. I wonder if @Eric_Eve could point this out?

2 Likes

Don’t get me wrong, I’ve used Fuses to save my befuddled head many a time!

1 Like

I think actions might intercept and collect the outputs of print statements to accommodate how actions tend to be attempted and tossed until the best method is found.

1 Like

I love dissecting the library, it’s so liberating…

2 Likes

Same. It seems that actions are analogous to event threads in Java.

Stuff done in an action happens in the “action thread”, and fuses put the code in the “main thread”. (Again, these aren’t actually threads; just a metaphor)

1 Like

That seems to be what’s happening, yeah.

1 Like

Same. Again, I feel like TADS was designed with this egregious amount of library alteration in mind, hence the modify keyword. Sort of a written permission to go absolutely wild with modding and innovation, whereas other languages rely on addressing all possibilities first—with flexibility as a priority—because corporate software teams rely on this rigid structure for security and organization.

2 Likes

Possible issue with the Fuse: if the text is meant to look like part of the player’s turn, any NPCs or even room atmosphere may fire between the player action and the Fuse text. Unless you very tediously give the Fuse an eventOrder that will fire directly after the PC, maybe…

1 Like

Okay, with some fiddling this did partially work. However, cls isn’t working after the pauseForMore now…

Edit: somehow I deleted it. I am a dummy.

2 Likes

Oh, you mean you deleted cls from the code…? Just checking for my understanding.