So how do I do this now?

I took a long break and now I keep banging my head against things that got changed - including “change.” I’m not interested in going back to an older version. That’s just not how I roll.
Anyway, this no longer works:

Before reading a command while action memory is true: now the previous action is the last action; now %1 is false; continue the action.

to decide if continuing the action: if the the previous action is the acting action begin; yes; otherwise; no; end if.

to capture the action: now %1 is the current action.

To treat action as success:
	follow the post-action bookkeeping rulebook.

This was in an old extension by someone else, and I’m just trying to recreate some of the behavior it provided. In this case, tracking prior actions while ignoring certain specific actions (like looking). An alternative solution would be welcome.

What is the error?

Problem. In the sentence ‘now %1 is false’ , I was expecting to read a condition, but instead found some text that I couldn’t understand - ‘%1 is false’.

I’m fairly sure that none of that old code will work as expected in any case. The solution I’m looking for is less “make %1 work” and more “do what this old code used to do.” I know Inform handles repeated actions, but I don’t get how to track what the previous action was or ignore specific actions to track.

What extension is this? It seems to me like there’s probably been some kind of problem in copy-pasting or something, because “%1” shouldn’t be both a stored action and something that can be set to false. In any case, I’m not quite sure what the code is supposed to do.

That’s how it appears in the extension. It was apparently valid 4 years ago. I’m not trying to use the extension though, only the “selective action memory” behavior from it. But valid or not, the whole block of code will do nothing.
Let me reiterate: I have no interest in fixing the extension or even this section of code. I only want to do with the current Inform what the extension did - selectively track prior commands.

So what exactly is your goal? You want to be able to refer to “the previous action”, but have a specific fixed list of actions be excluded?

OK, but I don’t feel like I have enough information to properly help you here. I don’t know exactly what you mean by “selectively track prior commands,” and without seeing more code from the extension I don’t know what the code you quoted is doing; for instance, I don’t know what the “post-action bookkeeping rulebook” does. If you told me what the extension was then I might be able to find it and see what it is doing.

Usually updates for the latest Inform aren’t very cumbersome if they don’t involve I6 inclusions, but the code you’ve posted isn’t enough to work with. There are several things there that must have been declared as variables elsewhere in the code, but I don’t have that code, so I can’t compile it to see what might be going wrong.

I guess I’ll say again that the %1s look like data corruption, and that the first %1 in that code almost certainly should be “action memory,” while the second %1 should maybe be “last action” or “previous action.” But without access to the rest of the code I don’t know what it should be.

[code]Test Chamber is a room.

Gordon is a person in the test chamber. The bucket is an open container in the test chamber. Gordon carries a gun. A flute is in the bucket.

Looking is ignorable.
Examining something is ignorable.
Waiting is ignorable.

The previous action is an action that varies.

The last every turn rule:
if the current action is not ignorable, now the previous action is the current action.

Every turn:
say “Previous action: [previous action].”

Test me with “get flute / examine flute / give flute to gordon / look / wait / put the flute in the bucket / wait”.
[/code]

Here’s a version if you want to remember more than one action at a time:

[code]
Test Chamber is a room.

Gordon is a person in the test chamber. The bucket is an open container in the test chamber. Gordon carries a gun. A flute is in the bucket.

Looking is ignorable.
Examining something is ignorable.
Waiting is ignorable.

The previous actions queue is a list of actions that varies.

The last every turn rule:
if the current action is not ignorable:
add the current action at entry 1 in the previous actions queue;
[presumably this would get cumbersome if you kept extending the list indefinitely, so we’ll cut this one off at 10 entries]
if the number of entries in the previous actions queue is greater than 10:
truncate the previous actions queue to 10 entries.

Every turn:
say “Previous actions: [previous actions queue].”

Test me with “get flute / examine flute / give flute to gordon / look / wait / put the flute in the bucket / get the bucket / drop the bucket / jump / listen / smell / ask Gordon about the gun / attack Gordon / wait”.[/code]

Thanks, mikegentry! That first solution is quite elegant compared to the old code and exactly what I was looking for, but that second solution adds possibilities I hadn’t even considered.

It looks like I’ve hit a snag with this. The actions are getting recorded, no problem there. But when I try to test if the previous action is the current action (for repeating the action) it acts like it’s the first time doing that action.
Here’s the code I’m using to see if it repeats:

To decide whether continuing the action:
	If the number of entries in the previous actions queue is at least 1:
		If entry 1 of the previous actions queue is the current action:
			Decide yes;
	Decide no;	

Are you trying to match the entire action, or just the “verb” part? A stored action includes not just the verb, but the noun and second noun as well, so TAKE BOOK would be considered a different action than TAKE SWORD, even though they’re both taking. If you’re only looking to match the verb part of the action, try this construction:

let the last action be entry 1 of the previous actions queue; if the action name part of the last action is the action name part of the current action: ...

That way TAKE (something) will match TAKE (something), regardless of what the something was.

I’m repeating the exact same action, including the noun. I even had a say “[the previous action]/[the current action]” in there and they looked the same. Could something be happening under the hood with disambiguation?

I just tested with your code and it STILL isn’t working. I really don’t understand what could be going wrong here.

Actually, could it be that I’m testing in the wrong place? Currently, I put the condition in the after action, and I realize that it might no longer be the current action at that stage.

Well, the problem might be that you never get to the after stage. There aren’t an awful lot of non-ignorable actions that you can do multiple times in a row successfully (take something once and the next time you take it it’ll fail the “can’t take what’s already taken rule,” for instance), and if the action gets interrupted at the check or instead or before stage, then your after rules won’t run. So if you do this:

[code]Test Chamber is a room.

Gordon is a person in the test chamber. The bucket is an open container in the test chamber. Gordon carries a gun. A flute is in the bucket.

Looking is ignorable.
Examining something is ignorable.
Waiting is ignorable.

The previous actions queue is a list of actions that varies.

The last every turn rule:
if the current action is not ignorable:
add the current action at entry 1 in the previous actions queue;
[presumably this would get cumbersome if you kept extending the list indefinitely, so we’ll cut this one off at 10 entries]
if the number of entries in the previous actions queue is greater than 10:
truncate the previous actions queue to 10 entries.

Every turn:
say “Current action: [current action].”;
say “Previous actions: [previous actions queue].”

To decide whether continuing the action:
If the number of entries in the previous actions queue is at least 1:
If entry 1 of the previous actions queue is the current action:
Decide yes;
Decide no;

After doing something when continuing the action: say “You do the same thing again.”

Every turn when continuing the action: say “You repeated yourself.”[/code]

You get this:

Note that the Every turn rule is running properly, but you don’t get the After message–because those actions never get to the After phase.

No, I meant I use it like this:

After doing something:
  If continuing the action:
    Say "blah";

I added the check to a before action rule and set a truth state there, then check that in the after. That works.

After doing something: If continuing the action: Say "blah";

The only difference between this and

After doing something when continuing the action: say "blah."

should be that the first rule runs whether or not you’re continuing the action (and thus cuts off any further After and Report rules). But they should both print “blah” only when you reach the After stage when continuing the action. If you don’t reach the After stage it won’t work–but that’s going to depend on how you’ve set up your action processing.

Well, it definitely reaches the after stage, as

  Otherwise:
    Say "not blah";

always works. For whatever reason, the current action isn’t valid during the after stage. I suppose I could just use another global variable for a stored action, make it the current action, then check that instead.

This is definitely not true under normal circumstances. Consider this code:

[code]Test Chamber is a room.

Gordon is a person in the test chamber. The bucket is an open container in the test chamber. Gordon carries a gun. A flute is in the bucket.

Looking is ignorable.
Examining something is ignorable.
Waiting is ignorable.

The previous actions queue is a list of actions that varies.

The last every turn rule:
if the current action is not ignorable:
add the current action at entry 1 in the previous actions queue;
[presumably this would get cumbersome if you kept extending the list indefinitely, so we’ll cut this one off at 10 entries]
if the number of entries in the previous actions queue is greater than 10:
truncate the previous actions queue to 10 entries.

Every turn:
say “Current action: [current action].”;
say “Previous actions: [previous actions queue].”

To decide whether continuing the action:
If the number of entries in the previous actions queue is at least 1:
If entry 1 of the previous actions queue is the current action:
Decide yes;
Decide no;

First After:
say “After phase rule for current action: [current action].”;
continue the action.

After doing something when continuing the action: say “You do the same thing again.”

Every turn when continuing the action: say “You repeated yourself.”[/code]

Output:

As you can see, the After phase rule for current action fires only in the cases where the action succeeds–the looking actions, the jumping actions, and the first taking the flute action–and when it does fire, it properly prints the current action. You can also see that when the same non-ignorable action was able to reach the After phase twice in a row, with jumping, the After doing something when continuing the action rule did run. The other actions fail at the Check stage (you can verify this if you type “rules” before running them), so they don’t reach the After stage at all.

Honestly, it looks like you must be doing something unusual that is causing your code to behave oddly, but I can’t tell what, because you’re only posting tiny snippets of code. If you really want us to be able to help you, you should come up with a minimal code example–copy out bits of your code that are small enough to post and that exhibit the inexplicable behavior. Sometimes doing this will even let you figure the problem out yourself.

But given the things you’ve posted, I can’t see why setting a truth state in the before stage and checking it in the after would do any good; if the action doesn’t reach the after stage, then the check won’t run, and in the cases where it does, checking continuing action directly in the after stage seems to be working. Perhaps when you made that change you changed something else that fixed the problem?

It might not seem like it, but you’ve already helped me quite a bit, matt w. For instance, I now know that the behavior I’ve been seeing isn’t normal. That probably means one of the extensions I’m using is doing weird things. If that’s the case I can just work around the problem.

As for the work around, I set the truth state in the before stage and then check it in the after stage. I’m not checking the current action in that stage. To verify this, I changed it back to checking the current action in the after stage and it fails.

I’m testing it with a blank project. If I can work out where the problem is, I can probably fix it myself. It’s not practical to post the entire project.

OK, glad to be able to help! I can tell that you have a complex project that might be hard to whittle down, and it sounds like you’re using some unusual extensions.

One question I have is whether you’re trying to make this apply to NPC actions. If we add “Persuasion rule: Persuasion succeeds” to the above code, we get this:

“After” rules run when you request someone to do something, but by the time you get to the Every Turn phrase the NPC’s action has stopped being the current action, so it doesn’t get added to the queue.

Or, to see how spontaneous NPC actions work, add this:

Instead of sleeping: try Gordon examining the player.

Note that Gordon’s action is the current action in the After phase, but by the time we get to Every turn the current action is sleeping again. Also, the After rules don’t fire for the sleeping action itself, because it was halted by an Instead rule and never reached the After stage.

I hadn’t even considered NPC actions yet. So far this is just straight player commands, without persuasion. However, the extension does do some complex things regarding persuasion and player actions involving NPCs so that they are closely entwined.