# Difference between Conditionals in the Past and Past Perfect

WI 9.13 has the following to say about the past tense (highlighting is mine):

if X was Y …
holds if and only if “X is Y” was true at the start of the most recent action.

And this, about the past perfect:

if X had been Y …
which records whether “X has been Y” was true at the start of the most recent action.

Are the two equivalent? The manual and the example both make it seem so, but I think I’m missing a trick. When would one use the past perfect?

They are not equivalent. “X was Y” can vary per turn. “X had been Y” stays true forever once it becomes true.

Say X is Y at the start of the game, but becomes not-Y during turn 2.

“X was Y” and “X had been Y” are both true through all of turn 1 and turn 2.

On turn 3, “X was Y” will be false. (Because X was not Y at the start of turn 3.) “X had been Y” will still be true. (Because, at the start of turn 3, “X has been Y” is true.)

2 Likes

That explains it, thank you.

There is some nuance based on the way that the underlying record-keeping works.

Most of the time, the state tracked by these types of conditions is updated by the “update chronological records rule” (listed in the turn sequence rules), which occurs after action processing, every turn rule processing, and the advancement of time. However, the state is updated by `has been` tests when evaluating their own conditions, regardless of where that occurs in the rule processing for the turn.

Take a look at this example:

``````"Tenses"

Place is a room.

An open unopenable container called a bucket is in Place.

The player carries a ball.

Every turn (this is the check was rule): [true if condition was true during last execution of "update chronological records rule" in the turn sequence rules, i.e. towards the end of the last turn]
if the ball was in the bucket:
say "The ball was in the bucket."

Every turn (this is the check has been rule): [true after condition evaluates true at least once in the context of this has been rule or during normal bookkeeping]
if the ball has been in the bucket:
say "The ball has been in the bucket."

Every turn (this is the check had been rule):  [true if this particular condition has ever been true during chronological record bookkeeping; not linked to any other test's rules even if logic is identical; notice not true on the first turn that "has been" is true]
if the ball had been in the bucket:
say "The ball had been in the bucket."

[After inserting the ball into the bucket:
now the ball is in Place;
say "The ball hops out."] [prevents any of above from ever evaluating true]

[First Every turn when the ball is in the bucket:
now the ball is in Place;
say "The ball hops out."] [prevents any of above from ever evaluating true]

[Last Every turn when the ball is in the bucket:
now the ball is in Place;
say "The ball hops out."] [prevents all but "check has been rule" condition from ever evaluating true]

Test me with "z / put ball in bucket / z / take ball / z / put ball in bucket / z".
``````

There are a couple of things to note about the way that this subsystem works:

1. Every `was`/`has been`/`had been` test generates its own unique condition identifier. Even two tests that are exactly the same get assigned their own IDs. In the example above, three condition IDs are generated, each with the same I6 test logic.

2. The way that `has been` tests work is a little different than the others. A flag passed to the chronological records testing function indicates that it should evaluate the condition right then and update the chronological record accordingly. The other tests (`was`/`had been`) only look at the current state of the chronological record.

Uncommenting the “last every turn…” rule shows the impact of these notes. Per note #2, when the “check has been rule” is applied, the record is updated while the `ball` is in the `bucket`. That rule’s condition will always evaluate true forever after. However, per note #1, the “check had been rule” – ostensibly based on the same underlying condition – will never become true because it is assigned its own ID, and the `ball` is never in the `bucket` when the “update chronological records” rule is executed.

5 Likes

This is really useful to know, thank you.