Hi all. I’m using ye olde Unified Glulx Input (UGI). When I say chained commands, I mean when the player types “N. E. E. get lamp. Climb ladder” or “N then E then E” etc.
So, previously a bug was fixed in the extension which meant entering chained commands caused it to hang/loop. The discussion of that bug and the fixed version are over in this linked topic. So that’s been dealt with, and I’m working from the fixed version.
I now face a tangentially related problem. Recall that with UGI, you can have your game wait for a particular kind of input on any turn. The major ones being Line (enter string, press return) and Character (press a key and in it goes).
I realised that if chained line commands are entered, the game will go on executing their actions even if, say, the first one in the chain led the game to an awaiting-character-input moment.
This can mess things up because, obviously, the player wasn’t meant to be able to do anything at the char-input moment except enter a particular character, to which the game would respond in a particular way. Instead, the player goes on bouncing around like a pinball, moving to rooms they weren’t meant to have access to yet and knocking things off tables. (And when they do come to a rest, the game is awaiting char-input, though you/the player wouldn’t necessarily know it. But this is a moot point because by now, the game is in a mess.)
I understand there’s probably some high level systemic work that could be done on the extension here. But I can say that for my own purposes, I’m looking for a specific, more modest(?..) fix. Which would be that… if a stored-up chained command encounters character-input mode, it would just stop and issue ‘reject the player’s command’ for each command in the rest of the chain. The effect would be that the chain would halt and the player would just be left sitting there at the char-input moment.
This currently isn’t possible for Deep Magic reasons (i.e. it’s built into the parser at a deep level that’s extremely difficult to change without breaking things).
However, this is something the original Infocom/ZIL parser was capable of, and something the I7 parser could be capable of if I ever got around to doing that rewrite. Is there demand for this/would it be worth putting in the energy?
Heh, I can’t answer re: demand, though I realise you’re probably polling The Room
I’ve been working on this project 10 months and I expect a minimum 18 more. It’s completely dependent on UGI now, so if anyone ever addresses this chained command issue, I’ll be ready to benefit and express eternal gratitude for the end result. Good news for me atm is, it’s not stopping me progressing. But I feel it would be a solid damper on the final result.
Looking at what matt w did in the other topic (blocking player from chaining with ‘after reading a command’), I thought of an alternative approach to make this work (alternative to rewriting the parser). Though I can’t tell how much easier it is. Maybe not very much at all –
UGI can’t insert its own command into an input at the moment. If it could, I could break up the player’s chained text myself with regex and then poke the commands in each turn until they ran out, or we hit an input type change.
I think I asked zarf years ago about adding what you might call ‘command spoofing’ to UGI, but did not hear back. It is acknowledged as a ‘to do’ in the comments of the extension. I was working on a CYOA extension that got out of hand, trying to be too much to many.
If you just want to block chained commands once and for all, that’s a pretty simple I6 hack: either redefine THEN*_WD (the words that act like “then”) as empty strings, or wipe the buffer after any command is processed. The former means “TAKE CHAIR THEN JUMP” will say you can’t see any “chair then jump” here, while the latter will take the chair and then silently ignore the rest.
The difficulty is just in making it work better; diking out what already exists is much easier.
Literally, removing something from a circuit board completely and thoroughly without much collateral damage.
In this case, doing the same, but with code. Zarf’s suggestion is the best way to do it: using dictionary words with commas and periods in them is a long-standing I6 tradition for “things that can never be typed”.
OK, I’ve learned lots. About circuit boards. And about commas in I6. But I think I’ve still got the wrong end of the stick about what this (redefining then as ‘,then’) would achieve.
I thought you guys were saying that performing the ‘then’ alteration (to all three THEN words in language.i6t) would block all chained commands. But it only seems to block the use of ‘then’ to chain commands. I can still use periods and commas. Have I done it incorrectly, or did I misinterpret what the outcome would be?
If I misinterpreted, maybe the ‘clearing the buffer each turn’ way would be better. Though I do not know how to do that. Thanks
For future reference, I am back to report on how to completely block chained commands. I’m doing this after much experimentation
in Inform 6M62
both with and without including Unified Glulx Input
both with and without modifying the inform language.i6t template
If you want to block all attempts at chaining commands (which can be made by typing periods, or commas, or THEN) in 6M62, it can be done by checking for each of the three cases after reading a command.
If you do it this way, there’s no need to modify language.i6t and it also has the advantage that you can redirect the player to your special fob-off messages about how they can’t chain commands. I attached a demo to show this.
Btw, turning the three 'then’s to ',then’s in language.i6t blocks the THEN case only – not commas or periods – and does so in a way where you’re not redirecting the player to a help message.
Annoyance Zone is a room. "There are two rooms east of here. And you won't be able to get through them all at once by chaining a bunch of EASTs together, so nyah nyah!".
Player is in Annoyance Zone.
room 1 is east of Annoyance Zone.
room 2 is east of room 1.
room 3 is east of room 2.
After reading a command when the player’s command matches the text ".":
say "Period rejection.";
reject the player’s command;
After reading a command when the player’s command matches the text ",":
say "Comma rejection.";
reject the player’s command;
After reading a command when the player's command matches the text " then ":
say "Then rejection.";
reject the player’s command;
Test me with "east. e/go e then e/e,e, e/e/east".