Getting input and suppressing \n?

My objective is a bit arcane, and I suspect that it may reside in the VM/interpreter and not in TADS code, but I’m not sure.

I’m still working on a readthrough mode for my game (and potentially as a module), and I would like to be able to print text immediately after the prompt if the player enters a blank command.
I wonder if this is possible, though, since hitting the Enter key sends a signal to force the newline? I was hoping that it could simply act as a signal to end getting input, where I could somehow suspend any TADS-written “\n” or “\b” that may customarily come after the get input process.
Just to explain my motivation: I have a mode (which basically works, as-is) where you can type your own commands at the prompt if you like, and they will be executed. Your input, of course, appears directly after the prompt sign. But if you hit Enter with a blank comand line, the game undoes all of your autonomous changes to the game state, and proceeds with the next step of the readthrough. It prints, in bold, the command you are supposed to have just executed, and then actually executes it as if the player had entered it. Works well enough, but in this case, when I print the text of the readthrough command, it always appears on the line below the prompt sign.
I’ve tried tinkering around with getInputLineExt,readMainCommand,inputLineEnd etc., but haven’t seemed to be able to get rid of the newline after a blank prompt.
Anyone able to help, or confirm the impossibility?

1 Like

Do you specifically want to catch a blank input line, or a blank command? Like, are you calling your own read-line command, or catching this from the normal action cycle?

1 Like

That’s going to be interpreter-dependent. AFAIK, all of the emglken-based terps use a separate DOM element for prompt/command, so if you wanted to stuff random text in there you’d end up having to commit various minor felonies against CSS to get it working, and I’m fairly certain such a solution wouldn’t work in, for example, FrobTADS.

2 Likes

I have no idea how to reply to multiple posts in a single reply, so I’ll just add that faking it by formatting an output line to look like a prompt is probably how I’d approach it, unless I was expecting the illusion to pass very close examination (e.g. someone looking at the DOM in a web-based terp).

If you’re basically just wanting to insert whatever commands a player would have typed if they were playing “interactively”, that’s how I’d approach it. It’s probably still going to be a little tricky if you want it to be seamless cross-platform, but you could probably “solve” most of your problems by sufficiently twiddling the default styling (so that prompts and response text always are in the same color and so on). Or, alternately, intentionally style the “fake” prompts so that they don’t even pretend to look exactly like “real” input.

2 Likes

I’m pretty sure somewhere in the Command class (or somewhere in the Action stuff) there’s a handler for blank commands.

I’m just now getting to my computer so I’ll look into it.

1 Like

That’s a plausible idea for various applications, but I’m not sure it can fly in my case. I need the regular readMainCommand prompt routine @inventor200 , because I want the player to have the option to enter their own commands at any time. It’s in the event that they hit Enter with a blank line that I would then print (in bold) the text of the next readthrough command, and of course in that case the “real” prompt is already there, so I can’t, say, just print a fresh line that starts with the prompt sign followed by my readthrough command. It isn’t going to sink the project if I can’t figure this out, but I’d really like the readthrough text to appear right after the (real) prompt sign.
I just can’t figure out any way to eliminate/suppress/circumvent the inevitable \n that happens (seemingly) as soon as the player hits the Enter key.
Does that make sense? Can you verify whether I’m missing some modifiable method/output tweak somewhere, or is it basically TADS-impossible to get rid of that \n?

1 Like

Yes, there’s an emptyCommandResponse… but if I try to print text before this is even called, that text appears on a newline from what the getInput line was…

1 Like

@RealNC , do you happen to know if that newline is interpreter/VM-controlled at the end of a get input function?

1 Like

From the Glk side you can turn off command echoing, which would allow you to manually echo the input without the \n. Garglk also has an “unput” extension function that might be able to be used to unprint a line break.

But I don’t know if there’s any way from TADS to specify that. This is a pretty obscure request!

2 Likes

It is pretty obscure, but it would be pretty desirable for my readthrough mode!
The thing that puzzles me is that I try to get into the innermost TADS functions that read the input, and when I do a debug print, it seems to be returning an empty string. I thought maybe the \n was getting added to the return value of getInput, but it doesn’t seem to be. I don’t know what/who/where is responsible for adding that newline…

1 Like

Yeah, that’s what I thought you were going for, and that totally makes sense. The thing I was suggesting is, instead of trying to make it “seamless” by trying to re-purpose the existing UI semantics, you could just implement the “readthrough” commands as a separate UI element. That is, instead of trying to make a transcript in which player commands and “readthrough” automatic commands are indistinguishable, they’d be easy to identify. So instead of, I dunno:

West of House
You are standing in an open field west of a white house, with a boarded front
door.
There is a small mailbox here.

>open mailbox
Opening the small mailbox reveals a leaflet.

>read leaflet
(Taken)
"WELCOME TO A GAME THAT'S TOTALLY NOT ZORK!"

>

…whether the two commands were entered by the player or automagically by the walkthrough mechanics, have something like

West of House
You are standing in an open field west of a white house, with a boarded front
door.
There is a small mailbox here.

>
[Deciding the mailbox looks interesting, you decide to investigate it]
> OPEN MAILBOX
Opening the small mailbox reveals a leaflet.

>
[You decide to check out that leaflet, might be important]
> READ LEAFLET
(Taken)
"WELCOME TO A GAME THAT'S TOTALLY NOT ZORK!"

[It wasn't important]

>

…and so on.

That is, instead of trying to pretend nothing different is happening, lean into it.

I mean I’m not saying that you should do it that way. Just throwing it out there as an idea.

Not quite like this, but I’ve done similar things in non-IF games where I wanted to let players sorta opt-out of specific puzzles without just bypassing them. And my thinking there was that whenever a player is opting-out of a puzzle, there’s a decent chance that the reason is that they’re just not grokking the logic (or whatever) of the puzzle, and this is a way to treat it as a teachable moment or whatever, instead of just “enter the next step in the walkthrough”, if that makes sense.

2 Likes

I get ya. And I’m really not that concerned about disguising readthrough commands as being indistinct from player-entered commands. I just thought it was a bit of an eyesore to see those blank prompts, and it makes the text window fill up a bit quicker (when you have a prompt, a \b, open mailbox, another \b, and then the normal action response; I use \b because I like the extra whitespace there).
And I do include comments as well, explaining what we’re thinking and what we’re trying to do next. Just not before every single command.
It’s not horrible as it is… I just thought putting the command after the prompt was ideal, and I hoped there was a way to accomplish it. It sounds like maybe not…
Basically, I was hoping for

<>> <b>open mailbox</b>

  There's your leaflet.

instead of

<>>

<b>open mailbox</b>

  There's your leaflet. 

It’s just a visual thing, really.

Yeah, if you want that to work cross-platform I don’t know of any way to make it work. For a text-based medium, most of the “legacy” IF platforms are surprisingly stingy about letting you fiddle with text formatting.

If you just wanted this working on web-based interpreters you could probably kludge a standalone script that listens for updates and then shuffles the DOM for you. But that’s probably asking for trouble in terms of compatibility problems you aren’t expecting.

2 Likes

Another thing… I don’t know how to web :slight_smile: Also the game is heavily geared to QTads…

1 Like

If anybody’s curious, here’s what’s happening.
aioInputLineTimeout is the lowest-level TADS function that calls the intrinsic function inputLineTimeout.

modify aioInputLineTimeout(timeout)
{
   "This text will print directly after the prompt. But this
    is no good because I can't tell yet whether the player
    is entering a command or leaving it blank. ";

      // normally the function simply returns the following line
      // without putting it in a variable
   local ret = inputLineTimeout(timeout);

   "And by this point a newline has already been inserted
    between the prompt line and this text. Tampering with 
    ret before returning it doesn't help, because ret[2]
    (string value of what was entered) is *not* displayed
    to the screen. The interpreter causes the player's entered
    keystrokes to appear after the prompt. This block of text
    is the first opportunity to try to print anything since the mo-
    ment of signaling to the program that we want to get input,
    and yet the newline has already occurred. ";

      // for instance, this does no good. It may execute the string,
      // but it won't display the string on the prompt line before
      // executing it.
   if(readthroughMode && usersStringWasEmpty)
      return [ret[1], 'next command in the readthrough steps'];
   else return inherited(timeout);
}
1 Like

The newline after input is printed by the interpreter. There is no way to suppress that.

2 Likes

Thanks for confirming… I suspected as much…

1 Like

Yeah, I can’t think of any way to cheese it with QTads, or at least not the version that comes with Ubuntu. FrobTADS seems to understand Unicode control characters and so you might be able to do some brutally inefficient typesetting that way (and no telling how portable that would be), but QTads prints empty cells for the Unicode control characters I just tried. I think there’s some way to specify specific fonts to use with QTads and that might help with it, but I don’t remember the details.

Probably not a good way to approach the problem anyway; just throwing it out there as something else I thought of.

2 Likes

Are you saying control characters can backtrack a \n?

1 Like

Well, in principle they should, but my guess would be that most interpreters don’t make any attempt to handle all of the Unicode special characters. Like Unicode includes a reverse line feed that’s specifically intended for this sort of thing (and used to be commonly used to do things like multi-strike ASCII art on line printers).

But I took a look at QTads to see how it output 'x' + makeString(0x0008) + 'foo' (because I happen to remember that off the top of my head) and got x□foo, so figured it wasn’t worth fiddling around with any further. But, you know, someone else might come up with something I’m not thinking of.

2 Likes