Ok, I have implemented "onto". And it seems to work, too.
It has been pushed to the github site. NOTE: If you update to the latest code, you will probably need to clear your browser cache. Browsers seem to like to use cached versions of .js code even when it has been updated.
So you can just "say" characters onto the element, and they will be appended. This typewriter thing does cause some thoughts for me, though.
First, for what you're trying to do, you might be better off just appending the characters to the span yourself with simple JavaScript. The reason is that "say"'s real power comes from things like expanding the various kinds of markup, applying styles, etc. And these simple sort of typewriter effect implementations (character by character) suffer from not being able to deal with any sort of markup, even HTML tags, as you can't output them a character at a time. The code would need to be smarter and parse the string to see what's text and what's markup and then apply the markup intelligently as characters are being output. That could be an interesting programming challenge.
Here is a different way to handle a typewriter effect, though not necessarily a good one (but more in line with a response approach):
.define says-next
.says .<value> .onto #container
.enddef
.responses player
.response START
.does .says <span id="container"></span>
.invokes
setInterval(function() {
interact.call([{keyword: "NEXT"}])
}, 100);
.response NEXT
.does 1 .says-next T
.does 2 .says-next h
.does 3 .says-next i
.does 4 .says-next s
.does 5 .says-next
.does 6 .says-next i
.does 7 .says-next s
.does 8 .says-next
.does 9 .says-next i
.does 10 .says-next t
.does 11 .says-next !
.end
Ugly, I know, and a pain if you had long text, or a lot of it. It could lend itself, though, to other situations, like if you wanted to output words instead of characters (like what spondre did on its title screen). It also would allow you to put markup in the stream, though it would have to be output in chunks (e.g. an entire name). (It does need a way to stop the timer though. Otherwise, it will keep calling the NEXT topic over and over forever. I think it would be useful to expose a function like "is topic supported", and you could then call the topic until it's no longer supported.)
That makes me realize that the markup processing abilities of "say" should be able to be leveraged in non-output situations: for example, building a string. (That's one thing I had wished Quest had - the ability to parse the text processor markup into a string instead of just to output.) I'm just about to slightly rip the "say" code apart, trying to get "as" to work on nested calls (e.g. with call markup). Right now, the "as" class is applied after the entire string has been assembled, which works for simple cases but isn't right in general. I need the code to be able to apply classes piece-by-piece,w which means being able to hang onto a non-text representation internally. So I've been refactoring the code in preparation for that. I'll keep in mind how easy it would be to have it be able to generate a string instead of HTML DOM elements. That way, you could fully expand a string (with variables, call markup, etc) and then output it in typewriter fashion, or do whatever you want with it.
My example also makes me think it would be useful to have a better sequential notation than the "does ###" one, since the number has to vary each time and be explicitly stated. I'll have to think about that. (Perhaps "does next" or something. Then that part could be rolled up into the macro as well.)
Probably more detail than you needed, but where my head is right now.
It certainly seems like people like this typewriter effect.