Storing a phrase you want to run later

Is there any way to store a phrase in a variable and run it later?

I’m specifically asking about phrases. Not actions. This is all background code, not player commands.

Consider defining custom, high level phrases (with To... :), and running one inside another:

To throw (item - a thing) at (target - a thing):
  [code A]
  impact item against target;
  [code B]

To impact (item - a thing) against (target - a thing):
   ...

This code will nest “impact” inside “throw”. Code B in “throw” will be run after “impact”.

Now, for a couple of reasons, I prefer finishing “throw” and running code B before running “impact”. Instead of nesting, if one phrase calls another “custom” phrase , I want to add it to a list of stuff to do, that the engine will do in order.

My current approach is very inelegant. I keep a table with the phrases to run, parameters and order: throw this, impact that, throw something else, etc. Then there is a routine that checks that table and runs whatever it finds there. The ugly thing is that I have to hardcode the references to the phrases in this way:

To perform stuff:
  [code reads the table and stores the entries in different variables]
  if act is "throw", throw first item at second item;
  if act is "impact", impact first item against second item;

Do you think there’s any better way, one that removes such hardcoding?

I’m not sure that I 100% understand what you’re trying to do, but it sounds like you basically want to queue execution of phrases as well as their parameters.

There is the apply... functionality for named phrases, which may be helpful here; see WWI 22.3 Phrases as values.

The greater problem would be the lack of any struct-like element. You’d have to fake it with either some sort of “carrier” object with properties that you can use like struct fields, or set up parallel lists, or tables as you are doing now.

To exec-phrase (O - object) with (N - number) and (T - text) (this is exec-phrasing):
	say "[O]:[N]:[T]."

Table of Stuff to Do
exec (phrase (object, number, text) -> nothing)	param1 (object)	param2 (number)	param3 (text)
with 10 blank rows.

Last Every turn:
	repeat through the Table of Stuff to Do:
		apply the exec entry to param1 entry and param2 entry and param3 entry;
		blank out the whole row.

To exec queue (P - phrase (object, number, text) -> nothing) with parameters (O - object) and (N - number) and (T - text):
	choose a blank row in the Table of Stuff to Do;
	now the exec entry is P;
	now the param1 entry is O;
	now the param2 entry is N;
	now the param3 entry is T.

Every turn:
	let N be a random number between 1 and 100;
	exec queue exec-phrasing with parameters yourself and N and "example1";
	let T be  random thing;
	exec queue exec-phrasing with parameters T and 5 and "example2".
1 Like

It’s totally fine to define actions that are only used in background code.

If you say

Back-impacting is an action applying to two visible things.

…with no Understand lines, then you have a purely internal action. Player commands cannot trigger it.

Then you can use a stored action to queue up whatever for later.

This isn’t fundamentally different from what you’re doing now; it’s just using stored actions and action rules instead of a table. It fits better into Inform’s model.

(There’s also the point of view that says “elegant is whatever works.”)

2 Likes

I had a hunch that this could be related, but to be honest that part of the docs is kinda impenetrable to me. I’ll look deeper into that. Thanks!

Oh!!! This is obviously the solution. I’m often too limited by the intended “correct” use of tools and I wouldn’t have thought that “It’s totally fine to define actions that are only used in background code.”

I bet this will make my engine way simpler. Trying it right away. Thank you.

1 Like

It works. And I replaced 60 lines of code (more in the future) with 2.

2 Likes