Here’s another smallish TADS3/adv3 module, this one that allows a game to execute arbitrary command strings as any actor: execCommandAs github repo.
Usage is simple. To execute >TAKE PEBBLE
as alice
:
execCommandAs(alice, 'take pebble');
To check to see if the command would succeed without actually changing the game state:
execCommandAs(alice, 'take pebble', true);
The return value is boolean true
on success, nil
otherwise.
In the first example the command will be tested and then “really” executed if the test succeeds. In the second example only the test will be run. The point being that execCommandAs()
will never attempt to “really” execute a command it expects to fail. This is mostly to prevent weird stuff in the transcript—if Alice tries to take the pebble and the pebble is in the player’s inventory that will produce “You won’t let Alice have that.” without anything to indicate what Alice is trying to do or why the game just produced that message.
Internally this uses savepoint()
and undo
in a try
/catch
/finally
block for command testing, and execCommandAs()
always tests before execution. So standard disclaimers about the undo
stack, performance, and so on apply.
Making this work requires mildly extensive tinkering with adv3’s command execution, so the this module requires the modularExecuteCommand module, the outputToggle module, and the new moreFailureReports module.
The modularExecuteCommand module is needed to correctly (for our purposes) handle command failure states that involve exceptions (like >X WAINSCOTTING
if “wainscotting” is not part of any object’s vocabulary).
The moreFailureReports module patches places in adv3 where actions fail without marking their failure in the transcript (like >TAKE PEBBLE
when the pebble is in another actor’s inventory).
This is another one of those weird things that I happen to need but I have no idea how much use it would be to anyone else. But it was involved enough handling the corner cases (that I have identified so far) so I figured it was worth putting out there in case anyone else could use it.